{"thread":{"id":"64538","subject":"[PATCH 0/5] Audit and document Scalar config","startedAt":"2025-11-26T22:18:39Z","lastAt":"2025-12-16T00:39:21Z","messageCount":48,"participants":["Derrick Stolee via GitGitGadget","Junio C Hamano","Derrick Stolee","Patrick Steinhardt","Johannes Schindelin","Matthew Hughes","Henrique Ferreiro"],"isPatch":true,"patchVersion":1,"patchTotal":5},"messages":[{"id":"531336","messageId":"pull.2010.git.1764195516.gitgitgadget@gmail.com","threadId":"64538","inReplyTo":null,"subject":"[PATCH 0/5] Audit and document Scalar config","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-11-26T22:18:31Z","receivedAt":"2025-11-26T22:18:39Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"In September [1], we discussed that the Scalar config options could use some\ndocumented justification as well as some comments to the config file that\nthey were set by Scalar. I was then immediately distracted by other work\nthings and am finally here with a series to do just that.\n\n[1]\nhttps://lore.kernel.org/git/ffa61066-7004-48dd-9096-85b305373bc7@gmail.com/\n\nI have indeed used Patrick's idea to add '# set by scalar' to each line\nadded by Scalar, it took a little more work for all the kinds of config set.\nI made myself a co-author.\n\nWhile working to justify each config option, I found some stale or incorrect\nconfig options. I also relaxed the override setting in most cases which gave\nme an opportunity to alphabetize the settings.\n\nThere was at least one case (I'm thinking of core.fscache here) where the\nconfig doesn't even exist in core Git, but instead in Git for Windows. We'll\nneed to adjust in that fork to reinclude it in the right place.\n\nThanks, -Stolee\n\nDerrick Stolee (5):\n  scalar: annotate config file with \"set by scalar\"\n  scalar: use index.skipHash=true for performance\n  scalar: remove stale config values\n  scalar: alphabetize and simplify config\n  scalar: document config settings\n\n Documentation/scalar.adoc | 158 ++++++++++++++++++++++++++++++++++++++\n scalar.c                  |  81 ++++++++++---------\n t/t9210-scalar.sh         |  26 ++++---\n 3 files changed, 218 insertions(+), 47 deletions(-)\n\n\nbase-commit: 6ab38b7e9cc7adafc304f3204616a4debd49c6e9\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-2010%2Fderrickstolee%2Fscalar-config-v1\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2010/derrickstolee/scalar-config-v1\nPull-Request: https://github.com/gitgitgadget/git/pull/2010\n-- \ngitgitgadget\n"},{"id":"531337","messageId":"a4ad8f80d062cd9fc62db69c21625eb286f4ebb8.1764195516.git.gitgitgadget@gmail.com","threadId":"64538","inReplyTo":"pull.2010.git.1764195516.gitgitgadget@gmail.com","subject":"[PATCH 1/5] scalar: annotate config file with \"set by scalar\"","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-11-26T22:18:32Z","receivedAt":"2025-11-26T22:18:41Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <stolee@gmail.com>\n\nA repo may have config options set by 'scalar clone' or 'scalar\nregister' and then updated by 'scalar reconfigure'. It can be helpful to\npoint out which of those options were set by the latest scalar\nrecommendations.\n\nAdd \"# set by scalar\" to the end of each config option to assist users\nin identifying why these config options were set in their repo.\n\nCo-authored-by: Patrick Steinhardt <ps@pks.im>\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\nSigned-off-by: Derrick Stolee <stolee@gmail.com>\n---\n scalar.c          | 16 +++++++++++++---\n t/t9210-scalar.sh |  3 +++\n 2 files changed, 16 insertions(+), 3 deletions(-)\n\ndiff --git a/scalar.c b/scalar.c\nindex f754311627..431b631585 100644\n--- a/scalar.c\n+++ b/scalar.c\n@@ -19,6 +19,7 @@\n #include \"help.h\"\n #include \"setup.h\"\n #include \"trace2.h\"\n+#include \"path.h\"\n \n static void setup_enlistment_directory(int argc, const char **argv,\n \t\t\t\t       const char * const *usagestr,\n@@ -99,16 +100,20 @@ static int set_scalar_config(const struct scalar_config *config, int reconfigure\n {\n \tchar *value = NULL;\n \tint res;\n+\tchar *file = repo_git_path(the_repository, \"config\");\n \n \tif ((reconfigure && config->overwrite_on_reconfigure) ||\n \t    repo_config_get_string(the_repository, config->key, &value)) {\n \t\ttrace2_data_string(\"scalar\", the_repository, config->key, \"created\");\n-\t\tres = repo_config_set_gently(the_repository, config->key, config->value);\n+\t\tres = repo_config_set_multivar_in_file_gently(the_repository, file, config->key,\n+\t\t\t\t\t\t\t      config->value, NULL,\n+\t\t\t\t\t\t\t      \" # set by scalar\", 0);\n \t} else {\n \t\ttrace2_data_string(\"scalar\", the_repository, config->key, \"exists\");\n \t\tres = 0;\n \t}\n \n+\tfree(file);\n \tfree(value);\n \treturn res;\n }\n@@ -195,13 +200,18 @@ static int set_recommended_config(int reconfigure)\n \t * for multiple values.\n \t */\n \tif (repo_config_get_string(the_repository, \"log.excludeDecoration\", &value)) {\n+\t\tchar *file = repo_git_path(the_repository, \"config\");\n \t\ttrace2_data_string(\"scalar\", the_repository,\n \t\t\t\t   \"log.excludeDecoration\", \"created\");\n-\t\tif (repo_config_set_multivar_gently(the_repository, \"log.excludeDecoration\",\n+\t\tif (repo_config_set_multivar_in_file_gently(the_repository, file,\n+\t\t\t\t\t\t    \"log.excludeDecoration\",\n \t\t\t\t\t\t    \"refs/prefetch/*\",\n-\t\t\t\t\t\t    CONFIG_REGEX_NONE, 0))\n+\t\t\t\t\t\t    CONFIG_REGEX_NONE,\n+\t\t\t\t\t\t    \" # set by scalar\",\n+\t\t\t\t\t\t    0))\n \t\t\treturn error(_(\"could not configure \"\n \t\t\t\t       \"log.excludeDecoration\"));\n+\t\tfree(file);\n \t} else {\n \t\ttrace2_data_string(\"scalar\", the_repository,\n \t\t\t\t   \"log.excludeDecoration\", \"exists\");\ndiff --git a/t/t9210-scalar.sh b/t/t9210-scalar.sh\nindex bd6f0c40d2..43c210a23d 100755\n--- a/t/t9210-scalar.sh\n+++ b/t/t9210-scalar.sh\n@@ -210,6 +210,9 @@ test_expect_success 'scalar reconfigure' '\n \tGIT_TRACE2_EVENT=\"$(pwd)/reconfigure\" scalar reconfigure -a &&\n \ttest_path_is_file one/src/cron.txt &&\n \ttest true = \"$(git -C one/src config core.preloadIndex)\" &&\n+\ttest_grep \"preloadIndex = true # set by scalar\" one/src/.git/config &&\n+\ttest_grep \"excludeDecoration = refs/prefetch/\\* # set by scalar\" one/src/.git/config &&\n+\n \ttest_subcommand git maintenance start <reconfigure &&\n \ttest_subcommand ! git maintenance unregister --force <reconfigure &&\n \n-- \ngitgitgadget\n\n"},{"id":"531338","messageId":"1c51dbb81485920e9faf336ffbda9d9258e7dfe1.1764195516.git.gitgitgadget@gmail.com","threadId":"64538","inReplyTo":"pull.2010.git.1764195516.gitgitgadget@gmail.com","subject":"[PATCH 2/5] scalar: use index.skipHash=true for performance","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-11-26T22:18:33Z","receivedAt":"2025-11-26T22:18:42Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <stolee@gmail.com>\n\nThe index.skipHash config option has been set to 'false' by Scalar since\n4933152cbb (scalar: enable path-walk during push via config, 2025-05-16)\nbut that commit message is trying to communicate the exact opposite:\nthat the 'true' value is what we want instead. This means that we've\nbeen disabling this performance benefit for Scalar repos\nunintentionally.\n\nFix this issue before we add justification for the config options set in\nthis list.\n\nOddly, enabling index.skipHash causes a test issue during 'test_commit'\nin one of the Scalar tests when GIT_TEST_SPLIT_INDEX is enabled (as\ncaught by the linux-test-vars build). I'm fixing the test by disabling\nthe environment variable, but the issue should be resolved in a series\nfocused on the split index.\n\nSigned-off-by: Derrick Stolee <stolee@gmail.com>\n---\n scalar.c          | 2 +-\n t/t9210-scalar.sh | 5 +++++\n 2 files changed, 6 insertions(+), 1 deletion(-)\n\ndiff --git a/scalar.c b/scalar.c\nindex 431b631585..75fd292be7 100644\n--- a/scalar.c\n+++ b/scalar.c\n@@ -154,7 +154,7 @@ static int set_recommended_config(int reconfigure)\n \t\t{ \"credential.validate\", \"false\", 1 }, /* GCM4W-only */\n \t\t{ \"gc.auto\", \"0\", 1 },\n \t\t{ \"gui.GCWarning\", \"false\", 1 },\n-\t\t{ \"index.skipHash\", \"false\", 1 },\n+\t\t{ \"index.skipHash\", \"true\", 1 },\n \t\t{ \"index.threads\", \"true\", 1 },\n \t\t{ \"index.version\", \"4\", 1 },\n \t\t{ \"merge.stat\", \"false\", 1 },\ndiff --git a/t/t9210-scalar.sh b/t/t9210-scalar.sh\nindex 43c210a23d..91d5964b73 100755\n--- a/t/t9210-scalar.sh\n+++ b/t/t9210-scalar.sh\n@@ -246,6 +246,11 @@ test_expect_success 'scalar reconfigure --all with includeIf.onbranch' '\n '\n \n test_expect_success 'scalar reconfigure --all with detached HEADs' '\n+\t# This test demonstrates an issue with index.skipHash=true and\n+\t# this test variable for the split index. Disable the test variable.\n+\tGIT_TEST_SPLIT_INDEX= &&\n+\texport GIT_TEST_SPLIT_INDEX &&\n+\n \trepos=\"two three four\" &&\n \tfor num in $repos\n \tdo\n-- \ngitgitgadget\n\n"},{"id":"531339","messageId":"156be69a7994f6978a5bae30b82ae374fe4d506a.1764195516.git.gitgitgadget@gmail.com","threadId":"64538","inReplyTo":"pull.2010.git.1764195516.gitgitgadget@gmail.com","subject":"[PATCH 3/5] scalar: remove stale config values","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-11-26T22:18:34Z","receivedAt":"2025-11-26T22:18:44Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <stolee@gmail.com>\n\nThese config values were added in the original Scalar contribution,\nd0feac4e8c (scalar: 'register' sets recommended config and starts\nmaintenance, 2021-12-03), but were never fully checked for validity in\nthe upstream Git project. At the time, Scalar was only intended for the\ncontrib/ directory so did not have as rigorous of an investigation.\n\nEach config option has its own justification for removal:\n\n* core.preloadIndex: This value is true by default, now. Removing this\n  causes some changes required to the tests that checked this config\n  value. Use gui.gcwarning=false instead.\n\n* core.fscache: This config does not exist in the core Git project, but\n  is instead a config option for a Git for Windows feature.\n\n* core.multiPackIndex: This config value is now enabled by default, so\n  does not need to be called out specifically. It was originally\n  included to make sure the background maintenance that created\n  multi-pack-indexes would result in the expected performance\n  improvements.\n\n* credential.validate: This option is not something specific to Git but\n  instead an older version of Git Credential Manager for Windows. That\n  software was replaced several years ago by the cross-platform Git\n  Credential Manger so this option is no longer needed to help users who\n  were on that older software.\n\n* pack.useSparse=true: This value is now Git's default as of de3a864114\n  (config: set pack.useSparse=true by default, 2020-03-20) so we don't\n  need it set by Scalar.\n\nSigned-off-by: Derrick Stolee <stolee@gmail.com>\n---\n scalar.c          |  5 -----\n t/t9210-scalar.sh | 20 ++++++++++----------\n 2 files changed, 10 insertions(+), 15 deletions(-)\n\ndiff --git a/scalar.c b/scalar.c\nindex 75fd292be7..fb595fab3a 100644\n--- a/scalar.c\n+++ b/scalar.c\n@@ -129,9 +129,6 @@ static int set_recommended_config(int reconfigure)\n \tstruct scalar_config config[] = {\n \t\t/* Required */\n \t\t{ \"am.keepCR\", \"true\", 1 },\n-\t\t{ \"core.FSCache\", \"true\", 1 },\n-\t\t{ \"core.multiPackIndex\", \"true\", 1 },\n-\t\t{ \"core.preloadIndex\", \"true\", 1 },\n #ifndef WIN32\n \t\t{ \"core.untrackedCache\", \"true\", 1 },\n #else\n@@ -151,7 +148,6 @@ static int set_recommended_config(int reconfigure)\n #endif\n \t\t{ \"core.logAllRefUpdates\", \"true\", 1 },\n \t\t{ \"credential.https://dev.azure.com.useHttpPath\", \"true\", 1 },\n-\t\t{ \"credential.validate\", \"false\", 1 }, /* GCM4W-only */\n \t\t{ \"gc.auto\", \"0\", 1 },\n \t\t{ \"gui.GCWarning\", \"false\", 1 },\n \t\t{ \"index.skipHash\", \"true\", 1 },\n@@ -160,7 +156,6 @@ static int set_recommended_config(int reconfigure)\n \t\t{ \"merge.stat\", \"false\", 1 },\n \t\t{ \"merge.renames\", \"true\", 1 },\n \t\t{ \"pack.useBitmaps\", \"false\", 1 },\n-\t\t{ \"pack.useSparse\", \"true\", 1 },\n \t\t{ \"receive.autoGC\", \"false\", 1 },\n \t\t{ \"feature.manyFiles\", \"false\", 1 },\n \t\t{ \"feature.experimental\", \"false\", 1 },\ndiff --git a/t/t9210-scalar.sh b/t/t9210-scalar.sh\nindex 91d5964b73..63224d2062 100755\n--- a/t/t9210-scalar.sh\n+++ b/t/t9210-scalar.sh\n@@ -202,15 +202,15 @@ test_expect_success 'scalar clone --no-... opts' '\n test_expect_success 'scalar reconfigure' '\n \tgit init one/src &&\n \tscalar register one &&\n-\tgit -C one/src config core.preloadIndex false &&\n+\tgit -C one/src config unset gui.gcwarning &&\n \tscalar reconfigure one &&\n-\ttest true = \"$(git -C one/src config core.preloadIndex)\" &&\n-\tgit -C one/src config core.preloadIndex false &&\n+\ttest false = \"$(git -C one/src config gui.gcwarning)\" &&\n+\tgit -C one/src config unset gui.gcwarning &&\n \trm one/src/cron.txt &&\n \tGIT_TRACE2_EVENT=\"$(pwd)/reconfigure\" scalar reconfigure -a &&\n \ttest_path_is_file one/src/cron.txt &&\n-\ttest true = \"$(git -C one/src config core.preloadIndex)\" &&\n-\ttest_grep \"preloadIndex = true # set by scalar\" one/src/.git/config &&\n+\ttest false = \"$(git -C one/src config gui.gcwarning)\" &&\n+\ttest_grep \"GCWarning = false # set by scalar\" one/src/.git/config &&\n \ttest_grep \"excludeDecoration = refs/prefetch/\\* # set by scalar\" one/src/.git/config &&\n \n \ttest_subcommand git maintenance start <reconfigure &&\n@@ -234,14 +234,14 @@ test_expect_success 'scalar reconfigure --all with includeIf.onbranch' '\n \t\tgit init $num/src &&\n \t\tscalar register $num/src &&\n \t\tgit -C $num/src config includeif.\"onbranch:foo\".path something &&\n-\t\tgit -C $num/src config core.preloadIndex false || return 1\n+\t\tgit -C $num/src config unset gui.gcwarning || return 1\n \tdone &&\n \n \tscalar reconfigure --all &&\n \n \tfor num in $repos\n \tdo\n-\t\ttest true = \"$(git -C $num/src config core.preloadIndex)\" || return 1\n+\t\ttest false = \"$(git -C $num/src config gui.gcwarning)\" || return 1\n \tdone\n '\n \n@@ -257,7 +257,7 @@ test_expect_success 'scalar reconfigure --all with detached HEADs' '\n \t\trm -rf $num/src &&\n \t\tgit init $num/src &&\n \t\tscalar register $num/src &&\n-\t\tgit -C $num/src config core.preloadIndex false &&\n+\t\tgit -C $num/src config unset gui.gcwarning &&\n \t\ttest_commit -C $num/src initial &&\n \t\tgit -C $num/src switch --detach HEAD || return 1\n \tdone &&\n@@ -266,7 +266,7 @@ test_expect_success 'scalar reconfigure --all with detached HEADs' '\n \n \tfor num in $repos\n \tdo\n-\t\ttest true = \"$(git -C $num/src config core.preloadIndex)\" || return 1\n+\t\ttest false = \"$(git -C $num/src config gui.gcwarning)\" || return 1\n \tdone\n '\n \n@@ -298,7 +298,7 @@ test_expect_success 'scalar supports -c/-C' '\n \tgit init sub &&\n \tscalar -C sub -c status.aheadBehind=bogus register &&\n \ttest -z \"$(git -C sub config --local status.aheadBehind)\" &&\n-\ttest true = \"$(git -C sub config core.preloadIndex)\"\n+\ttest false = \"$(git -C sub config gui.gcwarning)\"\n '\n \n test_expect_success '`scalar [...] <dir>` errors out when dir is missing' '\n-- \ngitgitgadget\n\n"},{"id":"531340","messageId":"9b8ce6ba2bcc802ae38b2e1223d7d93b03fb2a1b.1764195516.git.gitgitgadget@gmail.com","threadId":"64538","inReplyTo":"pull.2010.git.1764195516.gitgitgadget@gmail.com","subject":"[PATCH 4/5] scalar: alphabetize and simplify config","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-11-26T22:18:35Z","receivedAt":"2025-11-26T22:18:46Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <stolee@gmail.com>\n\nThe config values set by Scalar went through an audit in the previous\nchanges, so now reorganize the settings and simplify their purpose.\n\nFirst, alphabetize the config options, except put the platform-specific\noptions at the end. This groups two Windows-specific settings and only\none non-Windows setting.\n\nAlso, this removes the 'overwrite_on_reconfigure' setting for many of\nthese options. That setting made nearly all of these options \"required\"\nfor scalar enlistments, restricting use for users. Instead, now nearly\nall options have removed this setting.\n\nHowever, there is one setting that still has this, which is\nindex.skipHash, which was previously being set to _false_ when we\nactually prefer the value of true. Keep the overwrite here to help\nScalar users upgrade to the new version. We may remove that overwrite in\nthe future once we belive that most of the users who have the false\nvalue have upgraded to a version that overwrites that to 'true'.\n\nSigned-off-by: Derrick Stolee <stolee@gmail.com>\n---\n scalar.c | 60 ++++++++++++++++++++++++++++----------------------------\n 1 file changed, 30 insertions(+), 30 deletions(-)\n\ndiff --git a/scalar.c b/scalar.c\nindex fb595fab3a..d73f9d85c7 100644\n--- a/scalar.c\n+++ b/scalar.c\n@@ -127,10 +127,33 @@ static int have_fsmonitor_support(void)\n static int set_recommended_config(int reconfigure)\n {\n \tstruct scalar_config config[] = {\n-\t\t/* Required */\n-\t\t{ \"am.keepCR\", \"true\", 1 },\n+\t\t{ \"am.keepCR\", \"true\" },\n+\t\t{ \"commitGraph.changedPaths\", \"true\" },\n+\t\t{ \"commitGraph.generationVersion\", \"1\" },\n+\t\t{ \"core.autoCRLF\", \"false\" },\n+\t\t{ \"core.logAllRefUpdates\", \"true\" },\n+\t\t{ \"core.safeCRLF\", \"false\" },\n+\t\t{ \"credential.https://dev.azure.com.useHttpPath\", \"true\" },\n+\t\t{ \"feature.experimental\", \"false\" },\n+\t\t{ \"feature.manyFiles\", \"false\" },\n+\t\t{ \"fetch.showForcedUpdates\", \"false\" },\n+\t\t{ \"fetch.unpackLimit\", \"1\" },\n+\t\t{ \"fetch.writeCommitGraph\", \"false\" },\n+\t\t{ \"gc.auto\", \"0\" },\n+\t\t{ \"gui.GCWarning\", \"false\" },\n+\t\t{ \"index.skipHash\", \"true\", 1 /* Fix previous setting. */ },\n+\t\t{ \"index.threads\", \"true\"},\n+\t\t{ \"index.version\", \"4\" },\n+\t\t{ \"merge.renames\", \"true\" },\n+\t\t{ \"merge.stat\", \"false\" },\n+\t\t{ \"pack.useBitmaps\", \"false\" },\n+\t\t{ \"pack.usePathWalk\", \"true\" },\n+\t\t{ \"receive.autoGC\", \"false\" },\n+\t\t{ \"status.aheadBehind\", \"false\" },\n+\n+\t\t/* platform-specific */\n #ifndef WIN32\n-\t\t{ \"core.untrackedCache\", \"true\", 1 },\n+\t\t{ \"core.untrackedCache\", \"true\" },\n #else\n \t\t/*\n \t\t * Unfortunately, Scalar's Functional Tests demonstrated\n@@ -144,34 +167,11 @@ static int set_recommended_config(int reconfigure)\n \t\t * Therefore, with a sad heart, we disable this very useful\n \t\t * feature on Windows.\n \t\t */\n-\t\t{ \"core.untrackedCache\", \"false\", 1 },\n-#endif\n-\t\t{ \"core.logAllRefUpdates\", \"true\", 1 },\n-\t\t{ \"credential.https://dev.azure.com.useHttpPath\", \"true\", 1 },\n-\t\t{ \"gc.auto\", \"0\", 1 },\n-\t\t{ \"gui.GCWarning\", \"false\", 1 },\n-\t\t{ \"index.skipHash\", \"true\", 1 },\n-\t\t{ \"index.threads\", \"true\", 1 },\n-\t\t{ \"index.version\", \"4\", 1 },\n-\t\t{ \"merge.stat\", \"false\", 1 },\n-\t\t{ \"merge.renames\", \"true\", 1 },\n-\t\t{ \"pack.useBitmaps\", \"false\", 1 },\n-\t\t{ \"receive.autoGC\", \"false\", 1 },\n-\t\t{ \"feature.manyFiles\", \"false\", 1 },\n-\t\t{ \"feature.experimental\", \"false\", 1 },\n-\t\t{ \"fetch.unpackLimit\", \"1\", 1 },\n-\t\t{ \"fetch.writeCommitGraph\", \"false\", 1 },\n-#ifdef WIN32\n-\t\t{ \"http.sslBackend\", \"schannel\", 1 },\n+\t\t{ \"core.untrackedCache\", \"false\" },\n+\n+\t\t/* Other Windows-specific required settings: */\n+\t\t{ \"http.sslBackend\", \"schannel\" },\n #endif\n-\t\t/* Optional */\n-\t\t{ \"status.aheadBehind\", \"false\" },\n-\t\t{ \"commitGraph.changedPaths\", \"true\" },\n-\t\t{ \"commitGraph.generationVersion\", \"1\" },\n-\t\t{ \"core.autoCRLF\", \"false\" },\n-\t\t{ \"core.safeCRLF\", \"false\" },\n-\t\t{ \"fetch.showForcedUpdates\", \"false\" },\n-\t\t{ \"pack.usePathWalk\", \"true\" },\n \t\t{ NULL, NULL },\n \t};\n \tint i;\n-- \ngitgitgadget\n\n"},{"id":"531341","messageId":"18580f020d149eaa8271542d7e629ef10fd8c9a0.1764195516.git.gitgitgadget@gmail.com","threadId":"64538","inReplyTo":"pull.2010.git.1764195516.gitgitgadget@gmail.com","subject":"[PATCH 5/5] scalar: document config settings","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-11-26T22:18:36Z","receivedAt":"2025-11-26T22:18:47Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <stolee@gmail.com>\n\nAdd user-facing documentation that justifies the values being set by\n'scalar clone', 'scalar register', and 'scalar reconfigure'.\n\nSigned-off-by: Derrick Stolee <stolee@gmail.com>\n---\n Documentation/scalar.adoc | 158 ++++++++++++++++++++++++++++++++++++++\n 1 file changed, 158 insertions(+)\n\ndiff --git a/Documentation/scalar.adoc b/Documentation/scalar.adoc\nindex f81b2832f8..b34af225e6 100644\n--- a/Documentation/scalar.adoc\n+++ b/Documentation/scalar.adoc\n@@ -197,6 +197,164 @@ delete <enlistment>::\n \tThis subcommand lets you delete an existing Scalar enlistment from your\n \tlocal file system, unregistering the repository.\n \n+REQUIRED AND RECOMMENDED CONFIG\n+-------------------------------\n+\n+As part of both `scalar clone` and `scalar register`, certain Git config\n+values are set to optimize for large repositories or cross-platform support.\n+These options are updated in new Git versions according to the best known\n+advice for large repositories, and users can get the latest recommendations\n+by running `scalar reconfigure [--all]`.\n+\n+This section lists justifications for the config values that are set in the\n+latest version.\n+\n+am.keepCR=true::\n+\tThis setting is important for cross-platform development across Windows\n+\tand non-Windows platforms and keeping carriage return (`\\r`) characters\n+\tin certain workflows.\n+\n+commitGraph.changedPaths=true::\n+\tThis setting helps the background maintenance steps that compute the\n+\tserialized commit-graph to also store changed-path Bloom filters. This\n+\taccelerates file history commands and allows users to automatically\n+\tbenefit without running a foreground command.\n+\n+commitGraph.generationVersion=1::\n+\tWhile the preferred version is 2 for performance reasons, existing users\n+\tthat had version 1 by default will need special care in upgrading to\n+\tversion 2. This is likely to change in the future as the upgrade story\n+\tis solidifies.\n+\n+core.autoCRLF=false::\n+\tThis removes the transformation of worktree files to add CRLF line\n+\tendings when only LF line endings exist. This is removed for performance\n+\treasons. Repositories that use tools that care about CRLF line endings\n+\tshould commit the necessary files with those line endings instead.\n+\n+core.logAllRefUpdates=true::\n+\tThis enables the reflog on all branches. While this is a performance\n+\tcost for large repositories, it is frequently an important data source\n+\tfor users to get out of bad situations or to seek support from experts.\n+\n+core.safeCRLF=false::\n+\tSimilar to `core.autoCRLF=false`, this disables checks around whether\n+\tthe CRLF conversion is reversible. This is a performance improvement,\n+\tbut can be dangerous if `core.autoCRLF` is reenabled by the user.\n+\n+credential.https://dev.azure.com.useHttpPath=true::\n+\tThis setting enables the `credential.useHttpPath` feature only for web\n+\tURLs for Azure DevOps. This is important for users interacting with that\n+\tservice using multiple organizations and thus multiple credential\n+\ttokens.\n+\n+feature.experimental=false::\n+\tThis disables the \"experimental\" optimizations grouped under this\n+\tfeature config. The expectation is that all valuable optimizations are\n+\talso set explicitly by Scalar config, and any differences are\n+\tintentional. Notable differences include several bitmap-related config\n+\toptions which are disabled for client-focused Scalar repos.\n+\n+feature.manyFiles=false::\n+\tThis disables the \"many files\" optimizations grouped under this feature\n+\tconfig. The expectation is that all valuable optimizations are also set\n+\texplicitly by Scalar config, and any differences are intentional.\n+\n+fetch.showForcedUpdates=false::\n+\tThis disables the check at the end of `git fetch` that notifies the user\n+\tif the ref update was a forced update (one where the previous position\n+\tis not reachable from the latest position). This check can be very\n+\texpensive in large repositories, so is disabled and replaced with an\n+\tadvice message. Set `advice.fetchShowForcedUpdates=false` to disable\n+\tthis advice message.\n+\n+fetch.unpackLimit=1::\n+\tThis setting prevents Git from unpacking packfiles into loose objects\n+\tas they are downloaded from the server. This feature was intended as a\n+\tway to prevent performance issues from too many packfiles, but Scalar\n+\tuses background maintenance to group packfiles and cover them with a\n+\tmulti-pack-index, removing this issue.\n+\n+fetch.writeCommitGraph=false::\n+\tThis config setting was created to help users automatically udpate their\n+\tcommit-graph files as they perform fetches. However, this takes time\n+\tfrom foreground fetches and pulls and Scalar uses background maintenance\n+\tfor this function instead.\n+\n+gc.auto=0::\n+\tThis disables automatic garbage collection, since Scalar uses background\n+\tmaintenance to keep the repository data in good shape.\n+\n+gui.GCWarning=false::\n+\tSince Scalar disables garbage collection by setting `gc.auto=0`, the\n+\t`git-gui` tool may start to warn about this setting. Disable this\n+\twarning as Scalar's background maintenance configuration makes the\n+\twarning irrelevant.\n+\n+index.skipHash=true::\n+\tDisable computing the hash of the index contents as it is being written.\n+\tThis assists with performance, especially for large index files.\n+\n+index.threads=true::\n+\tThis tells Git to automatically detect how many threads it should use\n+\twhen reading the index in parallel due to the `core.preloadIndex=true`\n+\tsetting.\n+\n+index.version=4::\n+\tThis index version adds compression to the path names, reducing the size\n+\tof the index in a significant way for large repos. This is an important\n+\tperformance boost.\n+\n+merge.renames=true::\n+\tWhen computing merges in large repos, it is particularly important to\n+\tdetect renames to maximize the potential for a result that will validate\n+\tcorrectly. Users performing merges locally are more likely to be doing\n+\tso because a server-side merge (via pull request or similar) resulted in\n+\tconflicts. While this is the default setting, it is set specifically to\n+\toverride a potential change to `diff.renames` which a user may set for\n+\tperformance reasons.\n+\n+merge.stat=false::\n+\tThis disables a diff output after computing a merge. This improves\n+\tperformance of `git merge` for large repos while reducing noisy output.\n+\n+pack.useBitmaps=false::\n+\tThis disables the use of `.bitmap` files attached to packfiles. Bitmap\n+\tfiles are optimized for server-side use, not client-side use. Scalar\n+\tdisables this to avoid some performance issues that can occur if a user\n+\taccidentally creates `.bitmap` files.\n+\n+pack.usePathWalk=true::\n+\tThis enables the `--path-walk` option to `git pack-objects` by default.\n+\tThis can accelerate the computation and compression of packfiles created\n+\tby `git push` and other repack operations.\n+\n+receive.autoGC=false::\n+\tSimilar to `gc.auto`, this setting is disabled in preference of\n+\tbackground maintenance.\n+\n+status.aheadBehind=false::\n+\tThis disables the ahead/behind calculation that would normally happen\n+\tduring a `git status` command. This information is frequently ignored by\n+\tusers but can be expensive to calculate in large repos that receive\n+\tthousands of commits per day. The calculation is replaced with an advice\n+\tmessage that can be disabled by disabling the `advice.statusAheadBehind`\n+\tconfig.\n+\n+The following settings are different based on which platform is in use:\n+\n+core.untrackedCache=(true|false)::\n+\tThe untracked cache feature is important for performance benefits on\n+\tlarge repositories, but has demonstrated some bugs on Windows\n+\tfilesystems. Thus, this is set for other platforms but disabled on\n+\tWindows.\n+\n+http.sslBackend=schannel::\n+\tOn Windows, the `openssl` backend has some issues with certain types of\n+\tremote providers and certificate types. Override the default setting to\n+\tavoid these common problems.\n+\n+\n SEE ALSO\n --------\n linkgit:git-clone[1], linkgit:git-maintenance[1].\n-- \ngitgitgadget\n"},{"id":"531344","messageId":"xmqqqztkl57l.fsf@gitster.g","threadId":"64538","inReplyTo":"a4ad8f80d062cd9fc62db69c21625eb286f4ebb8.1764195516.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 1/5] scalar: annotate config file with \"set by scalar\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-11-26T23:55:10Z","receivedAt":"2025-11-26T23:55:13Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Derrick Stolee via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> Add \"# set by scalar\" to the end of each config option to assist users\n> in identifying why these config options were set in their repo.\n\nThe implementation is quite straight-forward, inlining expansion of\nrepo_config_set_gently() in the places that we want to add comment to.\n\nIf we had (a lot) more than two callsites, I would have suggested to\nadd a simple helper function, something like\n\n    static int scalar_config_set(struct repository *r, const char *key, const char *value)\n    {\n\tchar *file = repo_git_path(r, \"config\");\n        int res = repo_config_set_multivar_in_file_gently(r, file,\n\t\tkey, value, NULL, \" # set by scalar\", 0);\n\tfree(file);\n\treturn res;\n    }\n\nand then the updates to the callers would have been absolute minimum.\n\nWell, even with only two callsites, perhaps such a refactoring may\nstill have value in reducing the risk of typo in the comment.\n\n> diff --git a/t/t9210-scalar.sh b/t/t9210-scalar.sh\n> index bd6f0c40d2..43c210a23d 100755\n> --- a/t/t9210-scalar.sh\n> +++ b/t/t9210-scalar.sh\n> @@ -210,6 +210,9 @@ test_expect_success 'scalar reconfigure' '\n>  \tGIT_TRACE2_EVENT=\"$(pwd)/reconfigure\" scalar reconfigure -a &&\n>  \ttest_path_is_file one/src/cron.txt &&\n>  \ttest true = \"$(git -C one/src config core.preloadIndex)\" &&\n> +\ttest_grep \"preloadIndex = true # set by scalar\" one/src/.git/config &&\n> +\ttest_grep \"excludeDecoration = refs/prefetch/\\* # set by scalar\" one/src/.git/config &&\n> +\n>  \ttest_subcommand git maintenance start <reconfigure &&\n>  \ttest_subcommand ! git maintenance unregister --force <reconfigure &&\n\nLooks good.\n"},{"id":"531346","messageId":"xmqqldjsl53m.fsf@gitster.g","threadId":"64538","inReplyTo":"1c51dbb81485920e9faf336ffbda9d9258e7dfe1.1764195516.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 2/5] scalar: use index.skipHash=true for performance","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-11-26T23:57:33Z","receivedAt":"2025-11-26T23:57:35Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Derrick Stolee via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> diff --git a/t/t9210-scalar.sh b/t/t9210-scalar.sh\n> index 43c210a23d..91d5964b73 100755\n> --- a/t/t9210-scalar.sh\n> +++ b/t/t9210-scalar.sh\n> @@ -246,6 +246,11 @@ test_expect_success 'scalar reconfigure --all with includeIf.onbranch' '\n>  '\n>  \n>  test_expect_success 'scalar reconfigure --all with detached HEADs' '\n> +\t# This test demonstrates an issue with index.skipHash=true and\n> +\t# this test variable for the split index. Disable the test variable.\n> +\tGIT_TEST_SPLIT_INDEX= &&\n> +\texport GIT_TEST_SPLIT_INDEX &&\n\nInteresting.  I would have expected to see a simple \"sane_unset\",\ninstead of exporting an empty setting explicitly.\n\n>  \trepos=\"two three four\" &&\n>  \tfor num in $repos\n>  \tdo\n"},{"id":"531347","messageId":"xmqqh5ugl4ye.fsf@gitster.g","threadId":"64538","inReplyTo":"156be69a7994f6978a5bae30b82ae374fe4d506a.1764195516.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 3/5] scalar: remove stale config values","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-11-27T00:00:41Z","receivedAt":"2025-11-27T00:00:43Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Derrick Stolee via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> From: Derrick Stolee <stolee@gmail.com>\n>\n> These config values were added in the original Scalar contribution,\n> d0feac4e8c (scalar: 'register' sets recommended config and starts\n> maintenance, 2021-12-03), but were never fully checked for validity in\n> the upstream Git project. At the time, Scalar was only intended for the\n> contrib/ directory so did not have as rigorous of an investigation.\n>\n> Each config option has its own justification for removal:\n>\n> * core.preloadIndex: This value is true by default, now. Removing this\n>   causes some changes required to the tests that checked this config\n>   value. Use gui.gcwarning=false instead.\n>\n> * core.fscache: This config does not exist in the core Git project, but\n>   is instead a config option for a Git for Windows feature.\n>\n> * core.multiPackIndex: This config value is now enabled by default, so\n>   does not need to be called out specifically. It was originally\n>   included to make sure the background maintenance that created\n>   multi-pack-indexes would result in the expected performance\n>   improvements.\n>\n> * credential.validate: This option is not something specific to Git but\n>   instead an older version of Git Credential Manager for Windows. That\n>   software was replaced several years ago by the cross-platform Git\n>   Credential Manger so this option is no longer needed to help users who\n>   were on that older software.\n>\n> * pack.useSparse=true: This value is now Git's default as of de3a864114\n>   (config: set pack.useSparse=true by default, 2020-03-20) so we don't\n>   need it set by Scalar.\n\nThanks for a conprehensive list.  Very well described.\n\n"},{"id":"531348","messageId":"xmqqbjkol4je.fsf@gitster.g","threadId":"64538","inReplyTo":"18580f020d149eaa8271542d7e629ef10fd8c9a0.1764195516.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 5/5] scalar: document config settings","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-11-27T00:09:41Z","receivedAt":"2025-11-27T00:09:43Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Derrick Stolee via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> +commitGraph.generationVersion=1::\n> +\tWhile the preferred version is 2 for performance reasons, existing users\n> +\tthat had version 1 by default will need special care in upgrading to\n> +\tversion 2. This is likely to change in the future as the upgrade story\n> +\tis solidifies.\n\n\"as the upgrade story solidifies\"?\n\n> +fetch.writeCommitGraph=false::\n> +\tThis config setting was created to help users automatically udpate their\n> +\tcommit-graph files as they perform fetches. However, this takes time\n> +\tfrom foreground fetches and pulls and Scalar uses background maintenance\n> +\tfor this function instead.\n\n\"update their files\".\n\n> +index.threads=true::\n> +\tThis tells Git to automatically detect how many threads it should use\n> +\twhen reading the index in parallel due to the `core.preloadIndex=true`\n> +\tsetting.\n\nIs \"due to the `core.preloadIndex=true` setting\" part of this\nsentence still relevant?\n\n\nOther than that, superbly written.  Thanks, will queue.\n"},{"id":"531476","messageId":"089c3225-82cb-4039-83df-f97ea9fd49b2@gmail.com","threadId":"64538","inReplyTo":"xmqqldjsl53m.fsf@gitster.g","subject":"Re: [PATCH 2/5] scalar: use index.skipHash=true for performance","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2025-11-30T19:55:02Z","receivedAt":"2025-11-30T19:55:04Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"On 11/26/2025 6:57 PM, Junio C Hamano wrote:\n> \"Derrick Stolee via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n> \n>> diff --git a/t/t9210-scalar.sh b/t/t9210-scalar.sh\n>> index 43c210a23d..91d5964b73 100755\n>> --- a/t/t9210-scalar.sh\n>> +++ b/t/t9210-scalar.sh\n>> @@ -246,6 +246,11 @@ test_expect_success 'scalar reconfigure --all with includeIf.onbranch' '\n>>  '\n>>  \n>>  test_expect_success 'scalar reconfigure --all with detached HEADs' '\n>> +\t# This test demonstrates an issue with index.skipHash=true and\n>> +\t# this test variable for the split index. Disable the test variable.\n>> +\tGIT_TEST_SPLIT_INDEX= &&\n>> +\texport GIT_TEST_SPLIT_INDEX &&\n> \n> Interesting.  I would have expected to see a simple \"sane_unset\",\n> instead of exporting an empty setting explicitly.\n\nThat's indeed a better way to do it. Will do in v2.\n\nThanks,\n-Stolee\n\n"},{"id":"531477","messageId":"a4d60418-f48a-4321-b305-d37ae2f752b1@gmail.com","threadId":"64538","inReplyTo":"xmqqbjkol4je.fsf@gitster.g","subject":"Re: [PATCH 5/5] scalar: document config settings","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2025-11-30T19:56:49Z","receivedAt":"2025-11-30T19:56:50Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"On 11/26/2025 7:09 PM, Junio C Hamano wrote:\n> \"Derrick Stolee via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n> \n>> +commitGraph.generationVersion=1::\n>> +\tWhile the preferred version is 2 for performance reasons, existing users\n>> +\tthat had version 1 by default will need special care in upgrading to\n>> +\tversion 2. This is likely to change in the future as the upgrade story\n>> +\tis solidifies.\n> \n> \"as the upgrade story solidifies\"?\n\nThat's better than what I was going for which was \"is solidified\". Will fix.\n\n>> +fetch.writeCommitGraph=false::\n>> +\tThis config setting was created to help users automatically udpate their\n>> +\tcommit-graph files as they perform fetches. However, this takes time\n>> +\tfrom foreground fetches and pulls and Scalar uses background maintenance\n>> +\tfor this function instead.\n> \n> \"update their files\".\n\nYes. thanks.\n\n>> +index.threads=true::\n>> +\tThis tells Git to automatically detect how many threads it should use\n>> +\twhen reading the index in parallel due to the `core.preloadIndex=true`\n>> +\tsetting.\n> \n> Is \"due to the `core.preloadIndex=true` setting\" part of this\n> sentence still relevant?\n\nI should still include this, but mention that it is enabled by default and\nstill recommended.\n\n> Other than that, superbly written.  Thanks, will queue.\n\nThanks,\n-Stolee\n\n"},{"id":"531488","messageId":"aS1X_UohbRkttu0E@pks.im","threadId":"64538","inReplyTo":"xmqqqztkl57l.fsf@gitster.g","subject":"Re: [PATCH 1/5] scalar: annotate config file with \"set by scalar\"","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-12-01T08:55:25Z","receivedAt":"2025-12-01T08:55:32Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Wed, Nov 26, 2025 at 03:55:10PM -0800, Junio C Hamano wrote:\n> \"Derrick Stolee via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n> \n> > Add \"# set by scalar\" to the end of each config option to assist users\n> > in identifying why these config options were set in their repo.\n> \n> The implementation is quite straight-forward, inlining expansion of\n> repo_config_set_gently() in the places that we want to add comment to.\n> \n> If we had (a lot) more than two callsites, I would have suggested to\n> add a simple helper function, something like\n> \n>     static int scalar_config_set(struct repository *r, const char *key, const char *value)\n>     {\n> \tchar *file = repo_git_path(r, \"config\");\n>         int res = repo_config_set_multivar_in_file_gently(r, file,\n> \t\tkey, value, NULL, \" # set by scalar\", 0);\n> \tfree(file);\n> \treturn res;\n>     }\n> \n> and then the updates to the callers would have been absolute minimum.\n> \n> Well, even with only two callsites, perhaps such a refactoring may\n> still have value in reducing the risk of typo in the comment.\n\nAgreed, I think it's a good idea to provide such a function. The calls\nto `repo_config_set_multivar_in_file_gently()` are quite verbose.\n\nPatrick\n"},{"id":"531489","messageId":"aS1YAugZpgtNkgkR@pks.im","threadId":"64538","inReplyTo":"9b8ce6ba2bcc802ae38b2e1223d7d93b03fb2a1b.1764195516.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 4/5] scalar: alphabetize and simplify config","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-12-01T08:55:30Z","receivedAt":"2025-12-01T08:55:36Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Wed, Nov 26, 2025 at 10:18:35PM +0000, Derrick Stolee via GitGitGadget wrote:\n> From: Derrick Stolee <stolee@gmail.com>\n> \n> The config values set by Scalar went through an audit in the previous\n> changes, so now reorganize the settings and simplify their purpose.\n> \n> First, alphabetize the config options, except put the platform-specific\n> options at the end. This groups two Windows-specific settings and only\n> one non-Windows setting.\n> \n> Also, this removes the 'overwrite_on_reconfigure' setting for many of\n> these options. That setting made nearly all of these options \"required\"\n> for scalar enlistments, restricting use for users. Instead, now nearly\n> all options have removed this setting.\n\nAs far as I understand, this setting causes us to overwrite any\npreexisting config values when reconfiguring Scalar? So with your\nchanges the effect is that we now don't do that anymore, which allows\nthe user to tune some of the configuration values to their liking after\nhaving run `scalar init` for the first time. I guess that makes sense,\nas it gives the user more flexibility.\n\nIt does make me wonder though: is it really the most sensible thing to\noverwrite any keys that already exist in the configuration? We may end\nup overwriting configuration specified by the user both in the case of\n`scalar init` and `scalar reconfigure`. But arguably, we might want to\nonly ever write configuration that does _not_ yet have an explicit value\nin the configuration file, regardless of whether or not we reconfigure.\n\n> However, there is one setting that still has this, which is\n> index.skipHash, which was previously being set to _false_ when we\n> actually prefer the value of true. Keep the overwrite here to help\n> Scalar users upgrade to the new version. We may remove that overwrite in\n> the future once we belive that most of the users who have the false\n> value have upgraded to a version that overwrites that to 'true'.\n\nMakes sense. This has likely been a bug, and we now want to rectify that\nbug.\n\nThanks!\n\nPatrick\n"},{"id":"531490","messageId":"aS1YCAIrafQ2iEfz@pks.im","threadId":"64538","inReplyTo":"18580f020d149eaa8271542d7e629ef10fd8c9a0.1764195516.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 5/5] scalar: document config settings","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-12-01T08:55:36Z","receivedAt":"2025-12-01T08:55:42Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Wed, Nov 26, 2025 at 10:18:36PM +0000, Derrick Stolee via GitGitGadget wrote:\n> diff --git a/Documentation/scalar.adoc b/Documentation/scalar.adoc\n> index f81b2832f8..b34af225e6 100644\n> --- a/Documentation/scalar.adoc\n> +++ b/Documentation/scalar.adoc\n> @@ -197,6 +197,164 @@ delete <enlistment>::\n>  \tThis subcommand lets you delete an existing Scalar enlistment from your\n>  \tlocal file system, unregistering the repository.\n>  \n> +REQUIRED AND RECOMMENDED CONFIG\n> +-------------------------------\n> +\n> +As part of both `scalar clone` and `scalar register`, certain Git config\n> +values are set to optimize for large repositories or cross-platform support.\n> +These options are updated in new Git versions according to the best known\n> +advice for large repositories, and users can get the latest recommendations\n> +by running `scalar reconfigure [--all]`.\n> +\n> +This section lists justifications for the config values that are set in the\n> +latest version.\n> +\n> +am.keepCR=true::\n> +\tThis setting is important for cross-platform development across Windows\n> +\tand non-Windows platforms and keeping carriage return (`\\r`) characters\n> +\tin certain workflows.\n> +\n> +commitGraph.changedPaths=true::\n> +\tThis setting helps the background maintenance steps that compute the\n> +\tserialized commit-graph to also store changed-path Bloom filters. This\n> +\taccelerates file history commands and allows users to automatically\n> +\tbenefit without running a foreground command.\n\nIs this something we also want to promote to \"default\" eventually? The\ndownside of course is that maintenance takes a bit longer, but given\nthat it runs in the background anyway this shouldn't really impact our\nusers all that much.\n\n> +commitGraph.generationVersion=1::\n> +\tWhile the preferred version is 2 for performance reasons, existing users\n> +\tthat had version 1 by default will need special care in upgrading to\n> +\tversion 2. This is likely to change in the future as the upgrade story\n> +\tis solidifies.\n\nIs that still the case? We _did_ have some bugs in the upgrade path in\nthe past, but I thought it got all sorted out by now?\n\n[snip]\n> +fetch.unpackLimit=1::\n> +\tThis setting prevents Git from unpacking packfiles into loose objects\n> +\tas they are downloaded from the server. This feature was intended as a\n> +\tway to prevent performance issues from too many packfiles, but Scalar\n> +\tuses background maintenance to group packfiles and cover them with a\n> +\tmulti-pack-index, removing this issue.\n\nThe second sentence here reads as if \"fetch.unpackLimit=1\" was the\nfeature you are talking about, which led to some puzzlement at first.\nBut what you are talking about is the _default_ unpack limit of 100.\nMaybe something like this reads better?\n\n    This setting prevents Git from unpacking packfiles into loose objects\n    as they are downloaded from the server. The default limit of 100\n    objects was intended as a way to prevent performance issues from too\n    many packfiles, but Scalar uses background maintenance to group\n    packfiles and cover them with a multi-pack-index, removing this\n    issue.\n\nPatrick\n"},{"id":"531503","messageId":"c40853fa-03fd-42f5-aff0-663a3567e930@gmail.com","threadId":"64538","inReplyTo":"aS1YAugZpgtNkgkR@pks.im","subject":"Re: [PATCH 4/5] scalar: alphabetize and simplify config","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2025-12-01T12:35:35Z","receivedAt":"2025-12-01T12:35:37Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"On 12/1/25 3:55 AM, Patrick Steinhardt wrote:\n> On Wed, Nov 26, 2025 at 10:18:35PM +0000, Derrick Stolee via GitGitGadget wrote:\n>> From: Derrick Stolee <stolee@gmail.com>\n>>\n>> The config values set by Scalar went through an audit in the previous\n>> changes, so now reorganize the settings and simplify their purpose.\n>>\n>> First, alphabetize the config options, except put the platform-specific\n>> options at the end. This groups two Windows-specific settings and only\n>> one non-Windows setting.\n>>\n>> Also, this removes the 'overwrite_on_reconfigure' setting for many of\n>> these options. That setting made nearly all of these options \"required\"\n>> for scalar enlistments, restricting use for users. Instead, now nearly\n>> all options have removed this setting.\n> \n> As far as I understand, this setting causes us to overwrite any\n> preexisting config values when reconfiguring Scalar? So with your\n> changes the effect is that we now don't do that anymore, which allows\n> the user to tune some of the configuration values to their liking after\n> having run `scalar init` for the first time. I guess that makes sense,\n> as it gives the user more flexibility.\n\nYes, that is correct.\n\n> It does make me wonder though: is it really the most sensible thing to\n> overwrite any keys that already exist in the configuration? We may end\n> up overwriting configuration specified by the user both in the case of\n> `scalar init` and `scalar reconfigure`. But arguably, we might want to\n> only ever write configuration that does _not_ yet have an explicit value\n> in the configuration file, regardless of whether or not we reconfigure.\n\nI agree that this notion of forcing config is not optimal, and is a leftover\nfrom VFS for Git where some of these config things were actually required\nfor the virtualization to work. Once that idea was in place, it was easy\nto think \"we'll make sure the repo is configured correctly\" but that makes\nmuch less sense in Scalar these days.\n\n>> However, there is one setting that still has this, which is\n>> index.skipHash, which was previously being set to _false_ when we\n>> actually prefer the value of true. Keep the overwrite here to help\n>> Scalar users upgrade to the new version. We may remove that overwrite in\n>> the future once we belive that most of the users who have the false\n>> value have upgraded to a version that overwrites that to 'true'.\n> \n> Makes sense. This has likely been a bug, and we now want to rectify that\n> bug.\n\nAnd hopefully this is the only reason we'd need this \"overwrite\" feature\nfrom this point on.\n\nThanks,\n-Stolee\n\n"},{"id":"531504","messageId":"e0745f6c-9de6-4c48-82ac-07db2d664a2a@gmail.com","threadId":"64538","inReplyTo":"aS1YCAIrafQ2iEfz@pks.im","subject":"Re: [PATCH 5/5] scalar: document config settings","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2025-12-01T12:40:39Z","receivedAt":"2025-12-01T12:40:42Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"On 12/1/25 3:55 AM, Patrick Steinhardt wrote:\n> On Wed, Nov 26, 2025 at 10:18:36PM +0000, Derrick Stolee via GitGitGadget wrote:\n>> diff --git a/Documentation/scalar.adoc b/Documentation/scalar.adoc\n>> index f81b2832f8..b34af225e6 100644\n>> --- a/Documentation/scalar.adoc\n>> +++ b/Documentation/scalar.adoc\n>> @@ -197,6 +197,164 @@ delete <enlistment>::\n>>   \tThis subcommand lets you delete an existing Scalar enlistment from your\n>>   \tlocal file system, unregistering the repository.\n>>   \n>> +REQUIRED AND RECOMMENDED CONFIG\n>> +-------------------------------\n>> +\n>> +As part of both `scalar clone` and `scalar register`, certain Git config\n>> +values are set to optimize for large repositories or cross-platform support.\n>> +These options are updated in new Git versions according to the best known\n>> +advice for large repositories, and users can get the latest recommendations\n>> +by running `scalar reconfigure [--all]`.\n>> +\n>> +This section lists justifications for the config values that are set in the\n>> +latest version.\n>> +\n>> +am.keepCR=true::\n>> +\tThis setting is important for cross-platform development across Windows\n>> +\tand non-Windows platforms and keeping carriage return (`\\r`) characters\n>> +\tin certain workflows.\n>> +\n>> +commitGraph.changedPaths=true::\n>> +\tThis setting helps the background maintenance steps that compute the\n>> +\tserialized commit-graph to also store changed-path Bloom filters. This\n>> +\taccelerates file history commands and allows users to automatically\n>> +\tbenefit without running a foreground command.\n> \n> Is this something we also want to promote to \"default\" eventually? The\n> downside of course is that maintenance takes a bit longer, but given\n> that it runs in the background anyway this shouldn't really impact our\n> users all that much.\n\nI'm not sure, as this is a significant cost to the computation time. It will\nimpact foreground commands, as well. It increases the size of the file, too.\n\nIt's worth considering, but I don't think the answer is very simple.\n\n>> +commitGraph.generationVersion=1::\n>> +\tWhile the preferred version is 2 for performance reasons, existing users\n>> +\tthat had version 1 by default will need special care in upgrading to\n>> +\tversion 2. This is likely to change in the future as the upgrade story\n>> +\tis solidifies.\n> \n> Is that still the case? We _did_ have some bugs in the upgrade path in\n> the past, but I thought it got all sorted out by now?\n\nThis is very likely, but I haven't validated myself. I'd be interested to\ndouble-check and update this setting in a later series. If we update to 2,\nthen this would be a good reason to overwrite the old config for a while.\n\n> [snip]\n>> +fetch.unpackLimit=1::\n>> +\tThis setting prevents Git from unpacking packfiles into loose objects\n>> +\tas they are downloaded from the server. This feature was intended as a\n>> +\tway to prevent performance issues from too many packfiles, but Scalar\n>> +\tuses background maintenance to group packfiles and cover them with a\n>> +\tmulti-pack-index, removing this issue.\n> \n> The second sentence here reads as if \"fetch.unpackLimit=1\" was the\n> feature you are talking about, which led to some puzzlement at first.\n> But what you are talking about is the _default_ unpack limit of 100.\n> Maybe something like this reads better?\n> \n>      This setting prevents Git from unpacking packfiles into loose objects\n>      as they are downloaded from the server. The default limit of 100\n>      objects was intended as a way to prevent performance issues from too\n>      many packfiles, but Scalar uses background maintenance to group\n>      packfiles and cover them with a multi-pack-index, removing this\n>      issue.\n\nGood catch. Thanks!\n\n-Stolee\n\n"},{"id":"531517","messageId":"8ec87618-54b0-9b15-c7ff-f53e1f4fe2f7@gmx.de","threadId":"64538","inReplyTo":"pull.2010.git.1764195516.gitgitgadget@gmail.com","subject":"Re: [PATCH 0/5] Audit and document Scalar config","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2025-12-01T14:04:57Z","receivedAt":"2025-12-01T14:05:07Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Stolee,\n\nOn Wed, 26 Nov 2025, Derrick Stolee via GitGitGadget wrote:\n\n> In September [1], we discussed that the Scalar config options could use some\n> documented justification as well as some comments to the config file that\n> they were set by Scalar. I was then immediately distracted by other work\n> things and am finally here with a series to do just that.\n\nThank you for doing this, in particular the (quite long!) list of\nexplanations are excellent, especially when some user wonders why a\nparticular setting was chosen and wants to understand the reason.\n\n> \n> [1]\n> https://lore.kernel.org/git/ffa61066-7004-48dd-9096-85b305373bc7@gmail.com/\n> \n> I have indeed used Patrick's idea to add '# set by scalar' to each line\n> added by Scalar, it took a little more work for all the kinds of config set.\n\nI am glad that the work I put in to optionally add comments pays off.\n\nIt's a bit sad that there is no well-designed bulk-edit \"API\" function\nwhich therefore requires constructing and `free()`ing that `file` variable\nmany times, but that's not the fault of this series.\n\n> I made myself a co-author.\n> \n> While working to justify each config option, I found some stale or incorrect\n> config options. I also relaxed the override setting in most cases which gave\n> me an opportunity to alphabetize the settings.\n> \n> There was at least one case (I'm thinking of core.fscache here) where the\n> config doesn't even exist in core Git, but instead in Git for Windows. We'll\n> need to adjust in that fork to reinclude it in the right place.\n\nThank you for calling this out! I will take care of this in Git for\nWindows and also in Microsoft Git (which inherits this flag from Git for\nWindows).\n\nTo be honest, I am not so certain that we want the FSCache to be enabled,\nit does have long-standing bugs (introduced by the partial clone feature,\nfor example, where the FSCache continues to retain stale information about\nwhich loose objects are present even after the missing ones have been\nfetched). I guess we'll have to measure the actual performance benefits to\nreassess whether the feature is worth the trouble.\n\nThank you for your diligent work, as always,\nJohannes\n\n> \n> Thanks, -Stolee\n> \n> Derrick Stolee (5):\n>   scalar: annotate config file with \"set by scalar\"\n>   scalar: use index.skipHash=true for performance\n>   scalar: remove stale config values\n>   scalar: alphabetize and simplify config\n>   scalar: document config settings\n> \n>  Documentation/scalar.adoc | 158 ++++++++++++++++++++++++++++++++++++++\n>  scalar.c                  |  81 ++++++++++---------\n>  t/t9210-scalar.sh         |  26 ++++---\n>  3 files changed, 218 insertions(+), 47 deletions(-)\n> \n> \n> base-commit: 6ab38b7e9cc7adafc304f3204616a4debd49c6e9\n> Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-2010%2Fderrickstolee%2Fscalar-config-v1\n> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2010/derrickstolee/scalar-config-v1\n> Pull-Request: https://github.com/gitgitgadget/git/pull/2010\n> -- \n> gitgitgadget\n> \n"},{"id":"531521","messageId":"pull.2010.v2.git.1764607847.gitgitgadget@gmail.com","threadId":"64538","inReplyTo":"pull.2010.git.1764195516.gitgitgadget@gmail.com","subject":"[PATCH v2 0/5] Audit and document Scalar config","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-12-01T16:50:42Z","receivedAt":"2025-12-01T16:50:50Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"In September [1], we discussed that the Scalar config options could use some\ndocumented justification as well as some comments to the config file that\nthey were set by Scalar. I was then immediately distracted by other work\nthings and am finally here with a series to do just that.\n\n[1]\nhttps://lore.kernel.org/git/ffa61066-7004-48dd-9096-85b305373bc7@gmail.com/\n\nI have indeed used Patrick's idea to add '# set by scalar' to each line\nadded by Scalar, it took a little more work for all the kinds of config set.\nI made myself a co-author.\n\nWhile working to justify each config option, I found some stale or incorrect\nconfig options. I also relaxed the override setting in most cases which gave\nme an opportunity to alphabetize the settings.\n\nThere was at least one case (I'm thinking of core.fscache here) where the\nconfig doesn't even exist in core Git, but instead in Git for Windows. We'll\nneed to adjust in that fork to reinclude it in the right place.\n\n\nUpdates in V2\n=============\n\n * The config-setting code is simplified somewhat.\n * Use 'sane_unset' instead of 'export' in test.\n * Documentation is improved for typos, grammar, and clarity.\n\nThanks, -Stolee\n\nDerrick Stolee (5):\n  scalar: annotate config file with \"set by scalar\"\n  scalar: use index.skipHash=true for performance\n  scalar: remove stale config values\n  scalar: alphabetize and simplify config\n  scalar: document config settings\n\n Documentation/scalar.adoc | 158 ++++++++++++++++++++++++++++++++++++++\n scalar.c                  |  83 ++++++++++----------\n t/t9210-scalar.sh         |  25 +++---\n 3 files changed, 218 insertions(+), 48 deletions(-)\n\n\nbase-commit: 6ab38b7e9cc7adafc304f3204616a4debd49c6e9\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-2010%2Fderrickstolee%2Fscalar-config-v2\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2010/derrickstolee/scalar-config-v2\nPull-Request: https://github.com/gitgitgadget/git/pull/2010\n\nRange-diff vs v1:\n\n 1:  a4ad8f80d0 ! 1:  639ff98c44 scalar: annotate config file with \"set by scalar\"\n     @@ Commit message\n          recommendations.\n      \n          Add \"# set by scalar\" to the end of each config option to assist users\n     -    in identifying why these config options were set in their repo.\n     +    in identifying why these config options were set in their repo. Use a new\n     +    helper method to simplify the two callsites.\n      \n          Co-authored-by: Patrick Steinhardt <ps@pks.im>\n          Signed-off-by: Patrick Steinhardt <ps@pks.im>\n     @@ scalar.c\n       \n       static void setup_enlistment_directory(int argc, const char **argv,\n       \t\t\t\t       const char * const *usagestr,\n     -@@ scalar.c: static int set_scalar_config(const struct scalar_config *config, int reconfigure\n     +@@ scalar.c: struct scalar_config {\n     + \tint overwrite_on_reconfigure;\n     + };\n     + \n     ++static int set_config_with_comment(const char *key, const char *value)\n     ++{\n     ++\tchar *file = repo_git_path(the_repository, \"config\");\n     ++\tint res = repo_config_set_multivar_in_file_gently(the_repository, file,\n     ++\t\t\t\t\t\t\t  key, value, NULL,\n     ++\t\t\t\t\t\t\t  \" # set by scalar\", 0);\n     ++\tfree(file);\n     ++\treturn res;\n     ++}\n     ++\n     + static int set_scalar_config(const struct scalar_config *config, int reconfigure)\n       {\n       \tchar *value = NULL;\n     - \tint res;\n     -+\tchar *file = repo_git_path(the_repository, \"config\");\n     - \n     +@@ scalar.c: static int set_scalar_config(const struct scalar_config *config, int reconfigure\n       \tif ((reconfigure && config->overwrite_on_reconfigure) ||\n       \t    repo_config_get_string(the_repository, config->key, &value)) {\n       \t\ttrace2_data_string(\"scalar\", the_repository, config->key, \"created\");\n      -\t\tres = repo_config_set_gently(the_repository, config->key, config->value);\n     -+\t\tres = repo_config_set_multivar_in_file_gently(the_repository, file, config->key,\n     -+\t\t\t\t\t\t\t      config->value, NULL,\n     -+\t\t\t\t\t\t\t      \" # set by scalar\", 0);\n     ++\t\tres = set_config_with_comment(config->key, config->value);\n       \t} else {\n       \t\ttrace2_data_string(\"scalar\", the_repository, config->key, \"exists\");\n       \t\tres = 0;\n     - \t}\n     - \n     -+\tfree(file);\n     - \tfree(value);\n     - \treturn res;\n     - }\n      @@ scalar.c: static int set_recommended_config(int reconfigure)\n     - \t * for multiple values.\n     - \t */\n       \tif (repo_config_get_string(the_repository, \"log.excludeDecoration\", &value)) {\n     -+\t\tchar *file = repo_git_path(the_repository, \"config\");\n       \t\ttrace2_data_string(\"scalar\", the_repository,\n       \t\t\t\t   \"log.excludeDecoration\", \"created\");\n      -\t\tif (repo_config_set_multivar_gently(the_repository, \"log.excludeDecoration\",\n     -+\t\tif (repo_config_set_multivar_in_file_gently(the_repository, file,\n     -+\t\t\t\t\t\t    \"log.excludeDecoration\",\n     - \t\t\t\t\t\t    \"refs/prefetch/*\",\n     +-\t\t\t\t\t\t    \"refs/prefetch/*\",\n      -\t\t\t\t\t\t    CONFIG_REGEX_NONE, 0))\n     -+\t\t\t\t\t\t    CONFIG_REGEX_NONE,\n     -+\t\t\t\t\t\t    \" # set by scalar\",\n     -+\t\t\t\t\t\t    0))\n     ++\t\tif (set_config_with_comment(\"log.excludeDecoration\",\n     ++\t\t\t\t\t    \"refs/prefetch/*\"))\n       \t\t\treturn error(_(\"could not configure \"\n       \t\t\t\t       \"log.excludeDecoration\"));\n     -+\t\tfree(file);\n       \t} else {\n     - \t\ttrace2_data_string(\"scalar\", the_repository,\n     - \t\t\t\t   \"log.excludeDecoration\", \"exists\");\n      \n       ## t/t9210-scalar.sh ##\n      @@ t/t9210-scalar.sh: test_expect_success 'scalar reconfigure' '\n 2:  1c51dbb814 ! 2:  10e9548955 scalar: use index.skipHash=true for performance\n     @@ t/t9210-scalar.sh: test_expect_success 'scalar reconfigure --all with includeIf.\n       test_expect_success 'scalar reconfigure --all with detached HEADs' '\n      +\t# This test demonstrates an issue with index.skipHash=true and\n      +\t# this test variable for the split index. Disable the test variable.\n     -+\tGIT_TEST_SPLIT_INDEX= &&\n     -+\texport GIT_TEST_SPLIT_INDEX &&\n     ++\tsane_unset GIT_TEST_SPLIT_INDEX &&\n      +\n       \trepos=\"two three four\" &&\n       \tfor num in $repos\n 3:  156be69a79 = 3:  8783db6153 scalar: remove stale config values\n 4:  9b8ce6ba2b = 4:  edc0254770 scalar: alphabetize and simplify config\n 5:  18580f020d ! 5:  ac1627dbd9 scalar: document config settings\n     @@ Commit message\n          Add user-facing documentation that justifies the values being set by\n          'scalar clone', 'scalar register', and 'scalar reconfigure'.\n      \n     +    Helped-by: Junio C Hamano <gitster@pobox.com>\n     +    Helped-by: Patrick Steinhardt <ps@pks.im>\n          Signed-off-by: Derrick Stolee <stolee@gmail.com>\n      \n       ## Documentation/scalar.adoc ##\n     @@ Documentation/scalar.adoc: delete <enlistment>::\n      +\tWhile the preferred version is 2 for performance reasons, existing users\n      +\tthat had version 1 by default will need special care in upgrading to\n      +\tversion 2. This is likely to change in the future as the upgrade story\n     -+\tis solidifies.\n     ++\tsolidifies.\n      +\n      +core.autoCRLF=false::\n      +\tThis removes the transformation of worktree files to add CRLF line\n     @@ Documentation/scalar.adoc: delete <enlistment>::\n      +\n      +fetch.unpackLimit=1::\n      +\tThis setting prevents Git from unpacking packfiles into loose objects\n     -+\tas they are downloaded from the server. This feature was intended as a\n     -+\tway to prevent performance issues from too many packfiles, but Scalar\n     -+\tuses background maintenance to group packfiles and cover them with a\n     -+\tmulti-pack-index, removing this issue.\n     ++\tas they are downloaded from the server. The default limit of 100 was\n     ++\tintended as a way to prevent performance issues from too many packfiles,\n     ++\tbut Scalar uses background maintenance to group packfiles and cover them\n     ++\twith a multi-pack-index, removing this issue.\n      +\n      +fetch.writeCommitGraph=false::\n     -+\tThis config setting was created to help users automatically udpate their\n     ++\tThis config setting was created to help users automatically update their\n      +\tcommit-graph files as they perform fetches. However, this takes time\n      +\tfrom foreground fetches and pulls and Scalar uses background maintenance\n      +\tfor this function instead.\n     @@ Documentation/scalar.adoc: delete <enlistment>::\n      +\n      +index.threads=true::\n      +\tThis tells Git to automatically detect how many threads it should use\n     -+\twhen reading the index in parallel due to the `core.preloadIndex=true`\n     -+\tsetting.\n     ++\twhen reading the index due to the default value of `core.preloadIndex`,\n     ++\twhich enables parallel index reads.\n      +\n      +index.version=4::\n      +\tThis index version adds compression to the path names, reducing the size\n\n-- \ngitgitgadget\n"},{"id":"531522","messageId":"639ff98c44c45bb570fdde5123127aa099c299f8.1764607847.git.gitgitgadget@gmail.com","threadId":"64538","inReplyTo":"pull.2010.v2.git.1764607847.gitgitgadget@gmail.com","subject":"[PATCH v2 1/5] scalar: annotate config file with \"set by scalar\"","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-12-01T16:50:43Z","receivedAt":"2025-12-01T16:50:52Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <stolee@gmail.com>\n\nA repo may have config options set by 'scalar clone' or 'scalar\nregister' and then updated by 'scalar reconfigure'. It can be helpful to\npoint out which of those options were set by the latest scalar\nrecommendations.\n\nAdd \"# set by scalar\" to the end of each config option to assist users\nin identifying why these config options were set in their repo. Use a new\nhelper method to simplify the two callsites.\n\nCo-authored-by: Patrick Steinhardt <ps@pks.im>\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\nSigned-off-by: Derrick Stolee <stolee@gmail.com>\n---\n scalar.c          | 18 ++++++++++++++----\n t/t9210-scalar.sh |  3 +++\n 2 files changed, 17 insertions(+), 4 deletions(-)\n\ndiff --git a/scalar.c b/scalar.c\nindex f754311627..be3878948d 100644\n--- a/scalar.c\n+++ b/scalar.c\n@@ -19,6 +19,7 @@\n #include \"help.h\"\n #include \"setup.h\"\n #include \"trace2.h\"\n+#include \"path.h\"\n \n static void setup_enlistment_directory(int argc, const char **argv,\n \t\t\t\t       const char * const *usagestr,\n@@ -95,6 +96,16 @@ struct scalar_config {\n \tint overwrite_on_reconfigure;\n };\n \n+static int set_config_with_comment(const char *key, const char *value)\n+{\n+\tchar *file = repo_git_path(the_repository, \"config\");\n+\tint res = repo_config_set_multivar_in_file_gently(the_repository, file,\n+\t\t\t\t\t\t\t  key, value, NULL,\n+\t\t\t\t\t\t\t  \" # set by scalar\", 0);\n+\tfree(file);\n+\treturn res;\n+}\n+\n static int set_scalar_config(const struct scalar_config *config, int reconfigure)\n {\n \tchar *value = NULL;\n@@ -103,7 +114,7 @@ static int set_scalar_config(const struct scalar_config *config, int reconfigure\n \tif ((reconfigure && config->overwrite_on_reconfigure) ||\n \t    repo_config_get_string(the_repository, config->key, &value)) {\n \t\ttrace2_data_string(\"scalar\", the_repository, config->key, \"created\");\n-\t\tres = repo_config_set_gently(the_repository, config->key, config->value);\n+\t\tres = set_config_with_comment(config->key, config->value);\n \t} else {\n \t\ttrace2_data_string(\"scalar\", the_repository, config->key, \"exists\");\n \t\tres = 0;\n@@ -197,9 +208,8 @@ static int set_recommended_config(int reconfigure)\n \tif (repo_config_get_string(the_repository, \"log.excludeDecoration\", &value)) {\n \t\ttrace2_data_string(\"scalar\", the_repository,\n \t\t\t\t   \"log.excludeDecoration\", \"created\");\n-\t\tif (repo_config_set_multivar_gently(the_repository, \"log.excludeDecoration\",\n-\t\t\t\t\t\t    \"refs/prefetch/*\",\n-\t\t\t\t\t\t    CONFIG_REGEX_NONE, 0))\n+\t\tif (set_config_with_comment(\"log.excludeDecoration\",\n+\t\t\t\t\t    \"refs/prefetch/*\"))\n \t\t\treturn error(_(\"could not configure \"\n \t\t\t\t       \"log.excludeDecoration\"));\n \t} else {\ndiff --git a/t/t9210-scalar.sh b/t/t9210-scalar.sh\nindex bd6f0c40d2..43c210a23d 100755\n--- a/t/t9210-scalar.sh\n+++ b/t/t9210-scalar.sh\n@@ -210,6 +210,9 @@ test_expect_success 'scalar reconfigure' '\n \tGIT_TRACE2_EVENT=\"$(pwd)/reconfigure\" scalar reconfigure -a &&\n \ttest_path_is_file one/src/cron.txt &&\n \ttest true = \"$(git -C one/src config core.preloadIndex)\" &&\n+\ttest_grep \"preloadIndex = true # set by scalar\" one/src/.git/config &&\n+\ttest_grep \"excludeDecoration = refs/prefetch/\\* # set by scalar\" one/src/.git/config &&\n+\n \ttest_subcommand git maintenance start <reconfigure &&\n \ttest_subcommand ! git maintenance unregister --force <reconfigure &&\n \n-- \ngitgitgadget\n\n"},{"id":"531523","messageId":"10e95489554fa99469b1fe3248e81db9b74364b2.1764607847.git.gitgitgadget@gmail.com","threadId":"64538","inReplyTo":"pull.2010.v2.git.1764607847.gitgitgadget@gmail.com","subject":"[PATCH v2 2/5] scalar: use index.skipHash=true for performance","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-12-01T16:50:44Z","receivedAt":"2025-12-01T16:50:53Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <stolee@gmail.com>\n\nThe index.skipHash config option has been set to 'false' by Scalar since\n4933152cbb (scalar: enable path-walk during push via config, 2025-05-16)\nbut that commit message is trying to communicate the exact opposite:\nthat the 'true' value is what we want instead. This means that we've\nbeen disabling this performance benefit for Scalar repos\nunintentionally.\n\nFix this issue before we add justification for the config options set in\nthis list.\n\nOddly, enabling index.skipHash causes a test issue during 'test_commit'\nin one of the Scalar tests when GIT_TEST_SPLIT_INDEX is enabled (as\ncaught by the linux-test-vars build). I'm fixing the test by disabling\nthe environment variable, but the issue should be resolved in a series\nfocused on the split index.\n\nSigned-off-by: Derrick Stolee <stolee@gmail.com>\n---\n scalar.c          | 2 +-\n t/t9210-scalar.sh | 4 ++++\n 2 files changed, 5 insertions(+), 1 deletion(-)\n\ndiff --git a/scalar.c b/scalar.c\nindex be3878948d..1cb8ce3723 100644\n--- a/scalar.c\n+++ b/scalar.c\n@@ -160,7 +160,7 @@ static int set_recommended_config(int reconfigure)\n \t\t{ \"credential.validate\", \"false\", 1 }, /* GCM4W-only */\n \t\t{ \"gc.auto\", \"0\", 1 },\n \t\t{ \"gui.GCWarning\", \"false\", 1 },\n-\t\t{ \"index.skipHash\", \"false\", 1 },\n+\t\t{ \"index.skipHash\", \"true\", 1 },\n \t\t{ \"index.threads\", \"true\", 1 },\n \t\t{ \"index.version\", \"4\", 1 },\n \t\t{ \"merge.stat\", \"false\", 1 },\ndiff --git a/t/t9210-scalar.sh b/t/t9210-scalar.sh\nindex 43c210a23d..923c243c13 100755\n--- a/t/t9210-scalar.sh\n+++ b/t/t9210-scalar.sh\n@@ -246,6 +246,10 @@ test_expect_success 'scalar reconfigure --all with includeIf.onbranch' '\n '\n \n test_expect_success 'scalar reconfigure --all with detached HEADs' '\n+\t# This test demonstrates an issue with index.skipHash=true and\n+\t# this test variable for the split index. Disable the test variable.\n+\tsane_unset GIT_TEST_SPLIT_INDEX &&\n+\n \trepos=\"two three four\" &&\n \tfor num in $repos\n \tdo\n-- \ngitgitgadget\n\n"},{"id":"531524","messageId":"8783db6153875deb52aaa354da189ae611de1057.1764607847.git.gitgitgadget@gmail.com","threadId":"64538","inReplyTo":"pull.2010.v2.git.1764607847.gitgitgadget@gmail.com","subject":"[PATCH v2 3/5] scalar: remove stale config values","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-12-01T16:50:45Z","receivedAt":"2025-12-01T16:50:55Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <stolee@gmail.com>\n\nThese config values were added in the original Scalar contribution,\nd0feac4e8c (scalar: 'register' sets recommended config and starts\nmaintenance, 2021-12-03), but were never fully checked for validity in\nthe upstream Git project. At the time, Scalar was only intended for the\ncontrib/ directory so did not have as rigorous of an investigation.\n\nEach config option has its own justification for removal:\n\n* core.preloadIndex: This value is true by default, now. Removing this\n  causes some changes required to the tests that checked this config\n  value. Use gui.gcwarning=false instead.\n\n* core.fscache: This config does not exist in the core Git project, but\n  is instead a config option for a Git for Windows feature.\n\n* core.multiPackIndex: This config value is now enabled by default, so\n  does not need to be called out specifically. It was originally\n  included to make sure the background maintenance that created\n  multi-pack-indexes would result in the expected performance\n  improvements.\n\n* credential.validate: This option is not something specific to Git but\n  instead an older version of Git Credential Manager for Windows. That\n  software was replaced several years ago by the cross-platform Git\n  Credential Manger so this option is no longer needed to help users who\n  were on that older software.\n\n* pack.useSparse=true: This value is now Git's default as of de3a864114\n  (config: set pack.useSparse=true by default, 2020-03-20) so we don't\n  need it set by Scalar.\n\nSigned-off-by: Derrick Stolee <stolee@gmail.com>\n---\n scalar.c          |  5 -----\n t/t9210-scalar.sh | 20 ++++++++++----------\n 2 files changed, 10 insertions(+), 15 deletions(-)\n\ndiff --git a/scalar.c b/scalar.c\nindex 1cb8ce3723..5fef9a4104 100644\n--- a/scalar.c\n+++ b/scalar.c\n@@ -135,9 +135,6 @@ static int set_recommended_config(int reconfigure)\n \tstruct scalar_config config[] = {\n \t\t/* Required */\n \t\t{ \"am.keepCR\", \"true\", 1 },\n-\t\t{ \"core.FSCache\", \"true\", 1 },\n-\t\t{ \"core.multiPackIndex\", \"true\", 1 },\n-\t\t{ \"core.preloadIndex\", \"true\", 1 },\n #ifndef WIN32\n \t\t{ \"core.untrackedCache\", \"true\", 1 },\n #else\n@@ -157,7 +154,6 @@ static int set_recommended_config(int reconfigure)\n #endif\n \t\t{ \"core.logAllRefUpdates\", \"true\", 1 },\n \t\t{ \"credential.https://dev.azure.com.useHttpPath\", \"true\", 1 },\n-\t\t{ \"credential.validate\", \"false\", 1 }, /* GCM4W-only */\n \t\t{ \"gc.auto\", \"0\", 1 },\n \t\t{ \"gui.GCWarning\", \"false\", 1 },\n \t\t{ \"index.skipHash\", \"true\", 1 },\n@@ -166,7 +162,6 @@ static int set_recommended_config(int reconfigure)\n \t\t{ \"merge.stat\", \"false\", 1 },\n \t\t{ \"merge.renames\", \"true\", 1 },\n \t\t{ \"pack.useBitmaps\", \"false\", 1 },\n-\t\t{ \"pack.useSparse\", \"true\", 1 },\n \t\t{ \"receive.autoGC\", \"false\", 1 },\n \t\t{ \"feature.manyFiles\", \"false\", 1 },\n \t\t{ \"feature.experimental\", \"false\", 1 },\ndiff --git a/t/t9210-scalar.sh b/t/t9210-scalar.sh\nindex 923c243c13..009437a5f3 100755\n--- a/t/t9210-scalar.sh\n+++ b/t/t9210-scalar.sh\n@@ -202,15 +202,15 @@ test_expect_success 'scalar clone --no-... opts' '\n test_expect_success 'scalar reconfigure' '\n \tgit init one/src &&\n \tscalar register one &&\n-\tgit -C one/src config core.preloadIndex false &&\n+\tgit -C one/src config unset gui.gcwarning &&\n \tscalar reconfigure one &&\n-\ttest true = \"$(git -C one/src config core.preloadIndex)\" &&\n-\tgit -C one/src config core.preloadIndex false &&\n+\ttest false = \"$(git -C one/src config gui.gcwarning)\" &&\n+\tgit -C one/src config unset gui.gcwarning &&\n \trm one/src/cron.txt &&\n \tGIT_TRACE2_EVENT=\"$(pwd)/reconfigure\" scalar reconfigure -a &&\n \ttest_path_is_file one/src/cron.txt &&\n-\ttest true = \"$(git -C one/src config core.preloadIndex)\" &&\n-\ttest_grep \"preloadIndex = true # set by scalar\" one/src/.git/config &&\n+\ttest false = \"$(git -C one/src config gui.gcwarning)\" &&\n+\ttest_grep \"GCWarning = false # set by scalar\" one/src/.git/config &&\n \ttest_grep \"excludeDecoration = refs/prefetch/\\* # set by scalar\" one/src/.git/config &&\n \n \ttest_subcommand git maintenance start <reconfigure &&\n@@ -234,14 +234,14 @@ test_expect_success 'scalar reconfigure --all with includeIf.onbranch' '\n \t\tgit init $num/src &&\n \t\tscalar register $num/src &&\n \t\tgit -C $num/src config includeif.\"onbranch:foo\".path something &&\n-\t\tgit -C $num/src config core.preloadIndex false || return 1\n+\t\tgit -C $num/src config unset gui.gcwarning || return 1\n \tdone &&\n \n \tscalar reconfigure --all &&\n \n \tfor num in $repos\n \tdo\n-\t\ttest true = \"$(git -C $num/src config core.preloadIndex)\" || return 1\n+\t\ttest false = \"$(git -C $num/src config gui.gcwarning)\" || return 1\n \tdone\n '\n \n@@ -256,7 +256,7 @@ test_expect_success 'scalar reconfigure --all with detached HEADs' '\n \t\trm -rf $num/src &&\n \t\tgit init $num/src &&\n \t\tscalar register $num/src &&\n-\t\tgit -C $num/src config core.preloadIndex false &&\n+\t\tgit -C $num/src config unset gui.gcwarning &&\n \t\ttest_commit -C $num/src initial &&\n \t\tgit -C $num/src switch --detach HEAD || return 1\n \tdone &&\n@@ -265,7 +265,7 @@ test_expect_success 'scalar reconfigure --all with detached HEADs' '\n \n \tfor num in $repos\n \tdo\n-\t\ttest true = \"$(git -C $num/src config core.preloadIndex)\" || return 1\n+\t\ttest false = \"$(git -C $num/src config gui.gcwarning)\" || return 1\n \tdone\n '\n \n@@ -297,7 +297,7 @@ test_expect_success 'scalar supports -c/-C' '\n \tgit init sub &&\n \tscalar -C sub -c status.aheadBehind=bogus register &&\n \ttest -z \"$(git -C sub config --local status.aheadBehind)\" &&\n-\ttest true = \"$(git -C sub config core.preloadIndex)\"\n+\ttest false = \"$(git -C sub config gui.gcwarning)\"\n '\n \n test_expect_success '`scalar [...] <dir>` errors out when dir is missing' '\n-- \ngitgitgadget\n\n"},{"id":"531525","messageId":"edc0254770597de89c64951e4d8932ed70ab41f2.1764607847.git.gitgitgadget@gmail.com","threadId":"64538","inReplyTo":"pull.2010.v2.git.1764607847.gitgitgadget@gmail.com","subject":"[PATCH v2 4/5] scalar: alphabetize and simplify config","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-12-01T16:50:46Z","receivedAt":"2025-12-01T16:50:56Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <stolee@gmail.com>\n\nThe config values set by Scalar went through an audit in the previous\nchanges, so now reorganize the settings and simplify their purpose.\n\nFirst, alphabetize the config options, except put the platform-specific\noptions at the end. This groups two Windows-specific settings and only\none non-Windows setting.\n\nAlso, this removes the 'overwrite_on_reconfigure' setting for many of\nthese options. That setting made nearly all of these options \"required\"\nfor scalar enlistments, restricting use for users. Instead, now nearly\nall options have removed this setting.\n\nHowever, there is one setting that still has this, which is\nindex.skipHash, which was previously being set to _false_ when we\nactually prefer the value of true. Keep the overwrite here to help\nScalar users upgrade to the new version. We may remove that overwrite in\nthe future once we belive that most of the users who have the false\nvalue have upgraded to a version that overwrites that to 'true'.\n\nSigned-off-by: Derrick Stolee <stolee@gmail.com>\n---\n scalar.c | 60 ++++++++++++++++++++++++++++----------------------------\n 1 file changed, 30 insertions(+), 30 deletions(-)\n\ndiff --git a/scalar.c b/scalar.c\nindex 5fef9a4104..1fbd02e03a 100644\n--- a/scalar.c\n+++ b/scalar.c\n@@ -133,10 +133,33 @@ static int have_fsmonitor_support(void)\n static int set_recommended_config(int reconfigure)\n {\n \tstruct scalar_config config[] = {\n-\t\t/* Required */\n-\t\t{ \"am.keepCR\", \"true\", 1 },\n+\t\t{ \"am.keepCR\", \"true\" },\n+\t\t{ \"commitGraph.changedPaths\", \"true\" },\n+\t\t{ \"commitGraph.generationVersion\", \"1\" },\n+\t\t{ \"core.autoCRLF\", \"false\" },\n+\t\t{ \"core.logAllRefUpdates\", \"true\" },\n+\t\t{ \"core.safeCRLF\", \"false\" },\n+\t\t{ \"credential.https://dev.azure.com.useHttpPath\", \"true\" },\n+\t\t{ \"feature.experimental\", \"false\" },\n+\t\t{ \"feature.manyFiles\", \"false\" },\n+\t\t{ \"fetch.showForcedUpdates\", \"false\" },\n+\t\t{ \"fetch.unpackLimit\", \"1\" },\n+\t\t{ \"fetch.writeCommitGraph\", \"false\" },\n+\t\t{ \"gc.auto\", \"0\" },\n+\t\t{ \"gui.GCWarning\", \"false\" },\n+\t\t{ \"index.skipHash\", \"true\", 1 /* Fix previous setting. */ },\n+\t\t{ \"index.threads\", \"true\"},\n+\t\t{ \"index.version\", \"4\" },\n+\t\t{ \"merge.renames\", \"true\" },\n+\t\t{ \"merge.stat\", \"false\" },\n+\t\t{ \"pack.useBitmaps\", \"false\" },\n+\t\t{ \"pack.usePathWalk\", \"true\" },\n+\t\t{ \"receive.autoGC\", \"false\" },\n+\t\t{ \"status.aheadBehind\", \"false\" },\n+\n+\t\t/* platform-specific */\n #ifndef WIN32\n-\t\t{ \"core.untrackedCache\", \"true\", 1 },\n+\t\t{ \"core.untrackedCache\", \"true\" },\n #else\n \t\t/*\n \t\t * Unfortunately, Scalar's Functional Tests demonstrated\n@@ -150,34 +173,11 @@ static int set_recommended_config(int reconfigure)\n \t\t * Therefore, with a sad heart, we disable this very useful\n \t\t * feature on Windows.\n \t\t */\n-\t\t{ \"core.untrackedCache\", \"false\", 1 },\n-#endif\n-\t\t{ \"core.logAllRefUpdates\", \"true\", 1 },\n-\t\t{ \"credential.https://dev.azure.com.useHttpPath\", \"true\", 1 },\n-\t\t{ \"gc.auto\", \"0\", 1 },\n-\t\t{ \"gui.GCWarning\", \"false\", 1 },\n-\t\t{ \"index.skipHash\", \"true\", 1 },\n-\t\t{ \"index.threads\", \"true\", 1 },\n-\t\t{ \"index.version\", \"4\", 1 },\n-\t\t{ \"merge.stat\", \"false\", 1 },\n-\t\t{ \"merge.renames\", \"true\", 1 },\n-\t\t{ \"pack.useBitmaps\", \"false\", 1 },\n-\t\t{ \"receive.autoGC\", \"false\", 1 },\n-\t\t{ \"feature.manyFiles\", \"false\", 1 },\n-\t\t{ \"feature.experimental\", \"false\", 1 },\n-\t\t{ \"fetch.unpackLimit\", \"1\", 1 },\n-\t\t{ \"fetch.writeCommitGraph\", \"false\", 1 },\n-#ifdef WIN32\n-\t\t{ \"http.sslBackend\", \"schannel\", 1 },\n+\t\t{ \"core.untrackedCache\", \"false\" },\n+\n+\t\t/* Other Windows-specific required settings: */\n+\t\t{ \"http.sslBackend\", \"schannel\" },\n #endif\n-\t\t/* Optional */\n-\t\t{ \"status.aheadBehind\", \"false\" },\n-\t\t{ \"commitGraph.changedPaths\", \"true\" },\n-\t\t{ \"commitGraph.generationVersion\", \"1\" },\n-\t\t{ \"core.autoCRLF\", \"false\" },\n-\t\t{ \"core.safeCRLF\", \"false\" },\n-\t\t{ \"fetch.showForcedUpdates\", \"false\" },\n-\t\t{ \"pack.usePathWalk\", \"true\" },\n \t\t{ NULL, NULL },\n \t};\n \tint i;\n-- \ngitgitgadget\n\n"},{"id":"531526","messageId":"ac1627dbd94e3330117fbaeac2e2373104aef531.1764607847.git.gitgitgadget@gmail.com","threadId":"64538","inReplyTo":"pull.2010.v2.git.1764607847.gitgitgadget@gmail.com","subject":"[PATCH v2 5/5] scalar: document config settings","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-12-01T16:50:47Z","receivedAt":"2025-12-01T16:50:57Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <stolee@gmail.com>\n\nAdd user-facing documentation that justifies the values being set by\n'scalar clone', 'scalar register', and 'scalar reconfigure'.\n\nHelped-by: Junio C Hamano <gitster@pobox.com>\nHelped-by: Patrick Steinhardt <ps@pks.im>\nSigned-off-by: Derrick Stolee <stolee@gmail.com>\n---\n Documentation/scalar.adoc | 158 ++++++++++++++++++++++++++++++++++++++\n 1 file changed, 158 insertions(+)\n\ndiff --git a/Documentation/scalar.adoc b/Documentation/scalar.adoc\nindex f81b2832f8..f1d776ae0b 100644\n--- a/Documentation/scalar.adoc\n+++ b/Documentation/scalar.adoc\n@@ -197,6 +197,164 @@ delete <enlistment>::\n \tThis subcommand lets you delete an existing Scalar enlistment from your\n \tlocal file system, unregistering the repository.\n \n+REQUIRED AND RECOMMENDED CONFIG\n+-------------------------------\n+\n+As part of both `scalar clone` and `scalar register`, certain Git config\n+values are set to optimize for large repositories or cross-platform support.\n+These options are updated in new Git versions according to the best known\n+advice for large repositories, and users can get the latest recommendations\n+by running `scalar reconfigure [--all]`.\n+\n+This section lists justifications for the config values that are set in the\n+latest version.\n+\n+am.keepCR=true::\n+\tThis setting is important for cross-platform development across Windows\n+\tand non-Windows platforms and keeping carriage return (`\\r`) characters\n+\tin certain workflows.\n+\n+commitGraph.changedPaths=true::\n+\tThis setting helps the background maintenance steps that compute the\n+\tserialized commit-graph to also store changed-path Bloom filters. This\n+\taccelerates file history commands and allows users to automatically\n+\tbenefit without running a foreground command.\n+\n+commitGraph.generationVersion=1::\n+\tWhile the preferred version is 2 for performance reasons, existing users\n+\tthat had version 1 by default will need special care in upgrading to\n+\tversion 2. This is likely to change in the future as the upgrade story\n+\tsolidifies.\n+\n+core.autoCRLF=false::\n+\tThis removes the transformation of worktree files to add CRLF line\n+\tendings when only LF line endings exist. This is removed for performance\n+\treasons. Repositories that use tools that care about CRLF line endings\n+\tshould commit the necessary files with those line endings instead.\n+\n+core.logAllRefUpdates=true::\n+\tThis enables the reflog on all branches. While this is a performance\n+\tcost for large repositories, it is frequently an important data source\n+\tfor users to get out of bad situations or to seek support from experts.\n+\n+core.safeCRLF=false::\n+\tSimilar to `core.autoCRLF=false`, this disables checks around whether\n+\tthe CRLF conversion is reversible. This is a performance improvement,\n+\tbut can be dangerous if `core.autoCRLF` is reenabled by the user.\n+\n+credential.https://dev.azure.com.useHttpPath=true::\n+\tThis setting enables the `credential.useHttpPath` feature only for web\n+\tURLs for Azure DevOps. This is important for users interacting with that\n+\tservice using multiple organizations and thus multiple credential\n+\ttokens.\n+\n+feature.experimental=false::\n+\tThis disables the \"experimental\" optimizations grouped under this\n+\tfeature config. The expectation is that all valuable optimizations are\n+\talso set explicitly by Scalar config, and any differences are\n+\tintentional. Notable differences include several bitmap-related config\n+\toptions which are disabled for client-focused Scalar repos.\n+\n+feature.manyFiles=false::\n+\tThis disables the \"many files\" optimizations grouped under this feature\n+\tconfig. The expectation is that all valuable optimizations are also set\n+\texplicitly by Scalar config, and any differences are intentional.\n+\n+fetch.showForcedUpdates=false::\n+\tThis disables the check at the end of `git fetch` that notifies the user\n+\tif the ref update was a forced update (one where the previous position\n+\tis not reachable from the latest position). This check can be very\n+\texpensive in large repositories, so is disabled and replaced with an\n+\tadvice message. Set `advice.fetchShowForcedUpdates=false` to disable\n+\tthis advice message.\n+\n+fetch.unpackLimit=1::\n+\tThis setting prevents Git from unpacking packfiles into loose objects\n+\tas they are downloaded from the server. The default limit of 100 was\n+\tintended as a way to prevent performance issues from too many packfiles,\n+\tbut Scalar uses background maintenance to group packfiles and cover them\n+\twith a multi-pack-index, removing this issue.\n+\n+fetch.writeCommitGraph=false::\n+\tThis config setting was created to help users automatically update their\n+\tcommit-graph files as they perform fetches. However, this takes time\n+\tfrom foreground fetches and pulls and Scalar uses background maintenance\n+\tfor this function instead.\n+\n+gc.auto=0::\n+\tThis disables automatic garbage collection, since Scalar uses background\n+\tmaintenance to keep the repository data in good shape.\n+\n+gui.GCWarning=false::\n+\tSince Scalar disables garbage collection by setting `gc.auto=0`, the\n+\t`git-gui` tool may start to warn about this setting. Disable this\n+\twarning as Scalar's background maintenance configuration makes the\n+\twarning irrelevant.\n+\n+index.skipHash=true::\n+\tDisable computing the hash of the index contents as it is being written.\n+\tThis assists with performance, especially for large index files.\n+\n+index.threads=true::\n+\tThis tells Git to automatically detect how many threads it should use\n+\twhen reading the index due to the default value of `core.preloadIndex`,\n+\twhich enables parallel index reads.\n+\n+index.version=4::\n+\tThis index version adds compression to the path names, reducing the size\n+\tof the index in a significant way for large repos. This is an important\n+\tperformance boost.\n+\n+merge.renames=true::\n+\tWhen computing merges in large repos, it is particularly important to\n+\tdetect renames to maximize the potential for a result that will validate\n+\tcorrectly. Users performing merges locally are more likely to be doing\n+\tso because a server-side merge (via pull request or similar) resulted in\n+\tconflicts. While this is the default setting, it is set specifically to\n+\toverride a potential change to `diff.renames` which a user may set for\n+\tperformance reasons.\n+\n+merge.stat=false::\n+\tThis disables a diff output after computing a merge. This improves\n+\tperformance of `git merge` for large repos while reducing noisy output.\n+\n+pack.useBitmaps=false::\n+\tThis disables the use of `.bitmap` files attached to packfiles. Bitmap\n+\tfiles are optimized for server-side use, not client-side use. Scalar\n+\tdisables this to avoid some performance issues that can occur if a user\n+\taccidentally creates `.bitmap` files.\n+\n+pack.usePathWalk=true::\n+\tThis enables the `--path-walk` option to `git pack-objects` by default.\n+\tThis can accelerate the computation and compression of packfiles created\n+\tby `git push` and other repack operations.\n+\n+receive.autoGC=false::\n+\tSimilar to `gc.auto`, this setting is disabled in preference of\n+\tbackground maintenance.\n+\n+status.aheadBehind=false::\n+\tThis disables the ahead/behind calculation that would normally happen\n+\tduring a `git status` command. This information is frequently ignored by\n+\tusers but can be expensive to calculate in large repos that receive\n+\tthousands of commits per day. The calculation is replaced with an advice\n+\tmessage that can be disabled by disabling the `advice.statusAheadBehind`\n+\tconfig.\n+\n+The following settings are different based on which platform is in use:\n+\n+core.untrackedCache=(true|false)::\n+\tThe untracked cache feature is important for performance benefits on\n+\tlarge repositories, but has demonstrated some bugs on Windows\n+\tfilesystems. Thus, this is set for other platforms but disabled on\n+\tWindows.\n+\n+http.sslBackend=schannel::\n+\tOn Windows, the `openssl` backend has some issues with certain types of\n+\tremote providers and certificate types. Override the default setting to\n+\tavoid these common problems.\n+\n+\n SEE ALSO\n --------\n linkgit:git-clone[1], linkgit:git-maintenance[1].\n-- \ngitgitgadget\n"},{"id":"531527","messageId":"ciegbs72xbepxawuf42pne7eu354ntbok5e3p6jxcuyddvaea2@6ykt3iej32xt","threadId":"64538","inReplyTo":"8783db6153875deb52aaa354da189ae611de1057.1764607847.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 3/5] scalar: remove stale config values","fromName":"Matthew Hughes","fromEmail":"matthewhughes934@gmail.com","sentAt":"2025-12-01T17:46:46Z","receivedAt":"2025-12-01T17:46:50Z","isPatch":true,"sender":{"key":"matthewhughes934@gmail.com","avatar":"https://avatars.githubusercontent.com/u/34972397?v=4"},"body":"On Mon, Dec 01, 2025 at 04:50:45PM +0000, Derrick Stolee via GitGitGadget wrote:\n> * core.preloadIndex: This value is true by default, now. Removing this\n>   causes some changes required to the tests that checked this config\n>   value. Use gui.gcwarning=false instead.\n\nI was going to ask about if we could also rely on the default value of\nindex.threads like we do here, but then went and did some reading and realised\nsome config values, like index.recordOffsetTable, have their value set\naccording to whether index.threads was explicitly set, so I guess there's an\nimplicit reliance on that behaviour that we want to keep?\n\n> * core.fscache: This config does not exist in the core Git project, but\n>   is instead a config option for a Git for Windows feature.\n> \n> * core.multiPackIndex: This config value is now enabled by default, so\n>   does not need to be called out specifically. It was originally\n>   included to make sure the background maintenance that created\n>   multi-pack-indexes would result in the expected performance\n>   improvements.\n> \n> * credential.validate: This option is not something specific to Git but\n>   instead an older version of Git Credential Manager for Windows. That\n>   software was replaced several years ago by the cross-platform Git\n>   Credential Manger so this option is no longer needed to help users who\n>   were on that older software.\n> \n> * pack.useSparse=true: This value is now Git's default as of de3a864114\n>   (config: set pack.useSparse=true by default, 2020-03-20) so we don't\n>   need it set by Scalar.\n\nThanks for the detail on all of these, very helpful\n"},{"id":"531528","messageId":"wqvecbwieexjpp2pgxn66mlvq5foiw6as4doxgyiehzjuo7hv7@jrskhegeuqvg","threadId":"64538","inReplyTo":"ac1627dbd94e3330117fbaeac2e2373104aef531.1764607847.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 5/5] scalar: document config settings","fromName":"Matthew Hughes","fromEmail":"matthewhughes934@gmail.com","sentAt":"2025-12-01T17:58:06Z","receivedAt":"2025-12-01T17:58:10Z","isPatch":true,"sender":{"key":"matthewhughes934@gmail.com","avatar":"https://avatars.githubusercontent.com/u/34972397?v=4"},"body":"On Mon, Dec 01, 2025 at 04:50:47PM +0000, Derrick Stolee via GitGitGadget wrote:\n> Add user-facing documentation that justifies the values being set by\n> 'scalar clone', 'scalar register', and 'scalar reconfigure'.\n\nThanks! This is exactly what I was hoping for.\n\n> +REQUIRED AND RECOMMENDED CONFIG\n> +-------------------------------\n\nWould it be worth noting in scalar.c that the config options listed there are\ndocumented here, So that a dev changing the list in the source will know to\nalso update this? I assume there's an understanding that if e.g. you update a\nflag you should know to also update relevant docs, but perhaps this is a bit\nmore niche.\n\n> +gc.auto=0::\n> +\tThis disables automatic garbage collection, since Scalar uses background\n> +\tmaintenance to keep the repository data in good shape.\n\nChecking my understanding: this means there will be _no_ automatic GC in a\nscalar repo? Since scalar calls 'maintenance register' which means\nmaintenance.strategy will be set to 'incremental' which won't schedule any gc\nruns\n"},{"id":"531535","messageId":"xmqqwm358wq4.fsf@gitster.g","threadId":"64538","inReplyTo":"pull.2010.v2.git.1764607847.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 0/5] Audit and document Scalar config","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-12-02T02:05:07Z","receivedAt":"2025-12-02T02:05:10Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Derrick Stolee via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n>      -@@ scalar.c: static int set_scalar_config(const struct scalar_config *config, int reconfigure\n>      +@@ scalar.c: struct scalar_config {\n>      + \tint overwrite_on_reconfigure;\n>      + };\n>      + \n>      ++static int set_config_with_comment(const char *key, const char *value)\n\nI do not care too deeply as this is a file-scope static that is\ncalled only twice, but I would have preferred scalar_set_config()\nwhich is a lot more specificto the purpose of this function (and the\ncomment \"# set by scalar\" is hardcoded constant in this function\nthat its callers cannot affect, so \"with_comment\" is not even a\nstatement that \"the callers can add comment to their config\nsettings\") which would have taken a bit shorter line to call.\n\n>       +fetch.unpackLimit=1::\n>       +\tThis setting prevents Git from unpacking packfiles into loose objects\n>      -+\tas they are downloaded from the server. This feature was intended as a\n>      -+\tway to prevent performance issues from too many packfiles, but Scalar\n>      -+\tuses background maintenance to group packfiles and cover them with a\n>      -+\tmulti-pack-index, removing this issue.\n>      ++\tas they are downloaded from the server. The default limit of 100 was\n>      ++\tintended as a way to prevent performance issues from too many packfiles,\n>      ++\tbut Scalar uses background maintenance to group packfiles and cover them\n>      ++\twith a multi-pack-index, removing this issue.\n\nNicely explained.\n\nWill replace (when I land).\n\nThanks.\n\n"},{"id":"531538","messageId":"aS6a-K--2acXnIFY@pks.im","threadId":"64538","inReplyTo":"639ff98c44c45bb570fdde5123127aa099c299f8.1764607847.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 1/5] scalar: annotate config file with \"set by scalar\"","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-12-02T07:53:28Z","receivedAt":"2025-12-02T07:53:44Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Mon, Dec 01, 2025 at 04:50:43PM +0000, Derrick Stolee via GitGitGadget wrote:\n> diff --git a/t/t9210-scalar.sh b/t/t9210-scalar.sh\n> index bd6f0c40d2..43c210a23d 100755\n> --- a/t/t9210-scalar.sh\n> +++ b/t/t9210-scalar.sh\n> @@ -210,6 +210,9 @@ test_expect_success 'scalar reconfigure' '\n>  \tGIT_TRACE2_EVENT=\"$(pwd)/reconfigure\" scalar reconfigure -a &&\n>  \ttest_path_is_file one/src/cron.txt &&\n>  \ttest true = \"$(git -C one/src config core.preloadIndex)\" &&\n> +\ttest_grep \"preloadIndex = true # set by scalar\" one/src/.git/config &&\n> +\ttest_grep \"excludeDecoration = refs/prefetch/\\* # set by scalar\" one/src/.git/config &&\n> +\n>  \ttest_subcommand git maintenance start <reconfigure &&\n>  \ttest_subcommand ! git maintenance unregister --force <reconfigure &&\n\nWe _could_ make this a bit more solid by adding a test that:\n\n  1. Initializes a new repository.\n\n  2. Saves the configuration.\n\n  3. Performs `scalar reconfigure`.\n\n  4. Asserts that all new non-section-header lines in the configuration\n     have a trailing \"#set by scalar\" comment.\n\nThis would ensure that there is no callsite we forgot to add the new\nannotation to, and that there are new future callsites where somebody\nisn't aware of the comments.\n\nI don't insist on such a test though, so please feel free to ignore this\nsuggestion.\n\nPatrick\n"},{"id":"531539","messageId":"aS6bCU19x-QM84tp@pks.im","threadId":"64538","inReplyTo":"ciegbs72xbepxawuf42pne7eu354ntbok5e3p6jxcuyddvaea2@6ykt3iej32xt","subject":"Re: [PATCH v2 3/5] scalar: remove stale config values","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-12-02T07:53:45Z","receivedAt":"2025-12-02T07:53:53Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Mon, Dec 01, 2025 at 05:46:46PM +0000, Matthew Hughes wrote:\n> On Mon, Dec 01, 2025 at 04:50:45PM +0000, Derrick Stolee via GitGitGadget wrote:\n> > * core.preloadIndex: This value is true by default, now. Removing this\n> >   causes some changes required to the tests that checked this config\n> >   value. Use gui.gcwarning=false instead.\n> \n> I was going to ask about if we could also rely on the default value of\n> index.threads like we do here, but then went and did some reading and realised\n> some config values, like index.recordOffsetTable, have their value set\n> according to whether index.threads was explicitly set, so I guess there's an\n> implicit reliance on that behaviour that we want to keep?\n\nWait. Are you saying that \"index.recordOffsetTable\" behaves differently\nbased on whether \"index.threads\" is implicitly enabled due to the\ndefault value or explicitly enabled via the configuration? If so, that\nsmells like a plain bug to me.\n\nPatrick\n"},{"id":"531540","messageId":"aS6bE9iNzAemw7pk@pks.im","threadId":"64538","inReplyTo":"wqvecbwieexjpp2pgxn66mlvq5foiw6as4doxgyiehzjuo7hv7@jrskhegeuqvg","subject":"Re: [PATCH v2 5/5] scalar: document config settings","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-12-02T07:53:55Z","receivedAt":"2025-12-02T07:54:03Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Mon, Dec 01, 2025 at 05:58:06PM +0000, Matthew Hughes wrote:\n> On Mon, Dec 01, 2025 at 04:50:47PM +0000, Derrick Stolee via GitGitGadget wrote:\n> > Add user-facing documentation that justifies the values being set by\n> > 'scalar clone', 'scalar register', and 'scalar reconfigure'.\n> \n> Thanks! This is exactly what I was hoping for.\n> \n> > +REQUIRED AND RECOMMENDED CONFIG\n> > +-------------------------------\n> \n> Would it be worth noting in scalar.c that the config options listed there are\n> documented here, So that a dev changing the list in the source will know to\n> also update this? I assume there's an understanding that if e.g. you update a\n> flag you should know to also update relevant docs, but perhaps this is a bit\n> more niche.\n> \n> > +gc.auto=0::\n> > +\tThis disables automatic garbage collection, since Scalar uses background\n> > +\tmaintenance to keep the repository data in good shape.\n> \n> Checking my understanding: this means there will be _no_ automatic GC in a\n> scalar repo? Since scalar calls 'maintenance register' which means\n> maintenance.strategy will be set to 'incremental' which won't schedule any gc\n> runs\n\nYes, auto-garbage-collection is completely disabled in repositories\nmanaged by Scalar. And I guess that made sense in the past:\nauto-maintenance did not know about maintenance strategies at all, and\nconsequently it would still run git-gc(1). And that's not really\ncompatible with the \"incremental\" strategy that Scalar wants to use.\n\nI changed that in Git 2.52 so that maintenance strategies now apply to\nboth scheduled and normal maintenance. But I was worried about backwards\ncompatibility for the \"incremental\" strategy, so I made the change in a\nbackwards compatible way so that normal maintenance still ends up using\ngit-gc(1).\n\nArguably though, we can now iterate on our infrastructure: if we were to\nintroduce an \"incremental-v2\" strategy we could adapt it to have proper\nstrategies for both scheduled and normal maintenance. And if so, we can\nadapt Scalar in such a way that it doesn't have to disable auto\nmaintenance anymore.\n\nI think that would be a reasonable thing to do. Scheduled maintenance\nonly runs once per hour, and in a high-activity repo a user may easily\ngenerate tons of objects in that hour that make the repository perform\nbadly.\n\nPatrick\n"},{"id":"531579","messageId":"zbmzxqckpmf3h2sc7g3zvrhcyur2kmanv5uz6nyd2lgmi2it3b@i65jeyvcvqqy","threadId":"64538","inReplyTo":"aS6bCU19x-QM84tp@pks.im","subject":"Re: [PATCH v2 3/5] scalar: remove stale config values","fromName":"Matthew Hughes","fromEmail":"matthewhughes934@gmail.com","sentAt":"2025-12-02T19:04:24Z","receivedAt":"2025-12-02T19:04:28Z","isPatch":true,"sender":{"key":"matthewhughes934@gmail.com","avatar":"https://avatars.githubusercontent.com/u/34972397?v=4"},"body":"On Tue, Dec 02, 2025 at 08:53:45AM +0100, Patrick Steinhardt wrote:\n> Wait. Are you saying that \"index.recordOffsetTable\" behaves differently\n> based on whether \"index.threads\" is implicitly enabled due to the\n> default value or explicitly enabled via the configuration?\n\nThat was my understanding from a cursory read of the results of searching for\n'index.threads' in git-config:\n\n> index.recordEndOfIndexEntries\n> ...\n> Defaults to true if index.threads has been explicitly enabled, false\n> otherwise\n"},{"id":"531580","messageId":"aS88bnmZXMZCV5oS@pks.im","threadId":"64538","inReplyTo":"zbmzxqckpmf3h2sc7g3zvrhcyur2kmanv5uz6nyd2lgmi2it3b@i65jeyvcvqqy","subject":"Re: [PATCH v2 3/5] scalar: remove stale config values","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-12-02T19:22:22Z","receivedAt":"2025-12-02T19:22:37Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Tue, Dec 02, 2025 at 07:04:24PM +0000, Matthew Hughes wrote:\n> On Tue, Dec 02, 2025 at 08:53:45AM +0100, Patrick Steinhardt wrote:\n> > Wait. Are you saying that \"index.recordOffsetTable\" behaves differently\n> > based on whether \"index.threads\" is implicitly enabled due to the\n> > default value or explicitly enabled via the configuration?\n> \n> That was my understanding from a cursory read of the results of searching for\n> 'index.threads' in git-config:\n> \n> > index.recordEndOfIndexEntries\n> > ...\n> > Defaults to true if index.threads has been explicitly enabled, false\n> > otherwise\n\nHm, true. At least that's a concious decision then.\n\nThe logic around this was introduced in 2a9dedef2e (index: make\nindex.threads=true enable ieot and eoie, 2018-11-19), and the ultimate\nreason for it seems to be backwards compatibility:\n\n    index.threads and index.recordOffsetTable unspecified: do not write\n    the offset table yet (to avoid alarming the user with \"ignoring IEOT\n    extension\" messages when an older version of Git accesses the\n    repository) but do make use of multiple threads to read the index if\n    the supporting offset table is present.\n\nOlder versions of Git complained when they see unknown extensions, and\nwe didn't want to expose users to such warnings. That makes me wonder\nwhether it's time now to revisit that decision -- it's been 7 years\nsince then, I guess that many clients nowadays would understand the\nextension. \n\nThe only (documented) downside should thus not be that important\nanymore, but the upside is that reading the index would be faster if we\ndefault-enable writing the extension.\n\nPatrick\n"},{"id":"531785","messageId":"xmqqms3vnn9e.fsf@gitster.g","threadId":"64538","inReplyTo":"aS88bnmZXMZCV5oS@pks.im","subject":"Re: [PATCH v2 3/5] scalar: remove stale config values","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-12-07T00:34:05Z","receivedAt":"2025-12-07T00:34:07Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> The logic around this was introduced in 2a9dedef2e (index: make\n> index.threads=true enable ieot and eoie, 2018-11-19), and the ultimate\n> reason for it seems to be backwards compatibility:\n>\n>     index.threads and index.recordOffsetTable unspecified: do not write\n>     the offset table yet (to avoid alarming the user with \"ignoring IEOT\n>     extension\" messages when an older version of Git accesses the\n>     repository) but do make use of multiple threads to read the index if\n>     the supporting offset table is present.\n>\n> Older versions of Git complained when they see unknown extensions, and\n> we didn't want to expose users to such warnings.\n\nNot \"Older versions\".\n\nAny version of Git should complain mandatory index extension that it\ndoes not understand.  And any version of Git, even today's Git,\ngives a note when it ignores an optional index extension it does not\nunderstand.\n\n> That makes me wonder\n> whether it's time now to revisit that decision -- it's been 7 years\n> since then, I guess that many clients nowadays would understand the\n> extension. \n\nI do not think 7 years matters.  The only reason you might see the\n\"ignoring\" message is after using a newer version of Git that is\naware of that index extension, and then reverting back to an older\nversion.  As the index file is a purely local matter, it is not very\nlikely situation to begin with, and when it happens, the user should\nbe made aware of it.  Not understanding an optional index extension\nis not a breaking sin; but being in such a situation, i.e., the user\nis using older version of Git than they once used to use, is a note\nworthy vent.\n\nSo yes, even this logic was introduced last week, if the only reason\nis to avoid showing the note, that design decision should be\nrevisited.\n\n> The only (documented) downside should thus not be that important\n> anymore, but the upside is that reading the index would be faster if we\n> default-enable writing the extension.\n>\n> Patrick\n"},{"id":"531807","messageId":"aTZ2_Y2FxbASYpPd@pks.im","threadId":"64538","inReplyTo":"xmqqms3vnn9e.fsf@gitster.g","subject":"Re: [PATCH v2 3/5] scalar: remove stale config values","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-12-08T06:58:05Z","receivedAt":"2025-12-08T06:58:14Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Sun, Dec 07, 2025 at 09:34:05AM +0900, Junio C Hamano wrote:\n> Patrick Steinhardt <ps@pks.im> writes:\n> \n> > The logic around this was introduced in 2a9dedef2e (index: make\n> > index.threads=true enable ieot and eoie, 2018-11-19), and the ultimate\n> > reason for it seems to be backwards compatibility:\n> >\n> >     index.threads and index.recordOffsetTable unspecified: do not write\n> >     the offset table yet (to avoid alarming the user with \"ignoring IEOT\n> >     extension\" messages when an older version of Git accesses the\n> >     repository) but do make use of multiple threads to read the index if\n> >     the supporting offset table is present.\n> >\n> > Older versions of Git complained when they see unknown extensions, and\n> > we didn't want to expose users to such warnings.\n> \n> Not \"Older versions\".\n> \n> Any version of Git should complain mandatory index extension that it\n> does not understand.  And any version of Git, even today's Git,\n> gives a note when it ignores an optional index extension it does not\n> understand.\n\nThat's what I wanted to say, but I did so poorly :)\n\n> > That makes me wonder\n> > whether it's time now to revisit that decision -- it's been 7 years\n> > since then, I guess that many clients nowadays would understand the\n> > extension. \n> \n> I do not think 7 years matters.  The only reason you might see the\n> \"ignoring\" message is after using a newer version of Git that is\n> aware of that index extension, and then reverting back to an older\n> version.  As the index file is a purely local matter, it is not very\n> likely situation to begin with, and when it happens, the user should\n> be made aware of it.  Not understanding an optional index extension\n> is not a breaking sin; but being in such a situation, i.e., the user\n> is using older version of Git than they once used to use, is a note\n> worthy vent.\n\nYeah, this is of course something that can happen. I'm a bit torn on the\nusefulness of the warning. Sure, it warns the user about something Git\ndoes not understand. But that's exactly why we have optional extensions\nin the first place: so that we can introduce something without old\nclients understanding it.\n\nBut I can also see arguments why we want to warn. The old client would\nalways discard the information contained in the extension, and that may\nbe unfortunate depending on the extension itself. Ultimately, it's only\nthe user that can decide, but they are most likely not informed enough\nto judge whether the warning really should be ignored or not.\n\nMaybe there should still be a configuration that allows us to disable\nthis warning, for example via our advice infra?\n\n> So yes, even this logic was introduced last week, if the only reason\n> is to avoid showing the note, that design decision should be\n> revisited.\n\nI think the number of years it has been since the new extension was\nintroduced does matter to a certain degree: the longer we wait, the less\nlikely it is that users will have mixed versions of Git clients where\none of the versions doesn't understand the extension.\n\nThanks!\n\nPatrick\n"},{"id":"532046","messageId":"e19246a7-40db-41d0-9cdf-817833123f45@igalia.com","threadId":"64538","inReplyTo":"ac1627dbd94e3330117fbaeac2e2373104aef531.1764607847.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 5/5] scalar: document config settings","fromName":"Henrique Ferreiro","fromEmail":"hferreiro@igalia.com","sentAt":"2025-12-11T14:20:46Z","receivedAt":"2025-12-11T14:20:56Z","isPatch":true,"sender":{"key":"hferreiro@igalia.com","avatar":"https://avatars.githubusercontent.com/u/984737?v=4"},"body":"On 12/1/25 5:50 PM, Derrick Stolee via GitGitGadget wrote:\n> From: Derrick Stolee <stolee@gmail.com>\n> \n> Add user-facing documentation that justifies the values being set by\n> 'scalar clone', 'scalar register', and 'scalar reconfigure'.\n\nHi Derrick. I was planning to contribute a patch removing some config\noptions so I'll take this opportunity to just discuss those here.\n\nMy motivation is that some of the options seem to be related to things\nother than performance and the list is huge, so I believe that some\noptions don't belong to scalar.\n\n> +REQUIRED AND RECOMMENDED CONFIG\n> +-------------------------------\n\nThere's no mention on which configs are required and which are\nrecommended, and it looks like none are actually required so maybe just\nremove REQUIRED.\n\n> +am.keepCR=true::\n > +core.logAllRefUpdates=true::\n > +credential.https://dev.azure.com.useHttpPath=true::\n > +http.sslBackend=schannel::\n\nThese options are not related to performance. Why not keeping them out\nof scalar?\n\n> +core.autoCRLF=false::\n> +core.safeCRLF=false::\n > +index.threads=true::\n\nThese options just duplicate the default settings.\n\n> +feature.manyFiles=false::\n> +\tThis disables the \"many files\" optimizations grouped under this feature\n> +\tconfig. The expectation is that all valuable optimizations are also set\n> +\texplicitly by Scalar config, and any differences are intentional.\n\nI disagree with this reasoning. This thread was actually brought to my\nattention when working on setting manyFiles to true in scalar:\nhttps://github.com/git/git/pull/2125.\n\nDo you foresee any features that would apply to scalar but not to\nmanyFiles? I'd even say that some scalar options could be moved to\nmanyFiles instead, so that people that don't use scalar can benefit too.\n\nCheers,\nHenrique.\n"},{"id":"532074","messageId":"7d347708-2c47-4847-8e29-56e03c6a6a13@gmail.com","threadId":"64538","inReplyTo":"ciegbs72xbepxawuf42pne7eu354ntbok5e3p6jxcuyddvaea2@6ykt3iej32xt","subject":"Re: [PATCH v2 3/5] scalar: remove stale config values","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2025-12-12T13:57:11Z","receivedAt":"2025-12-12T13:57:13Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"On 12/1/2025 12:46 PM, Matthew Hughes wrote:\n> On Mon, Dec 01, 2025 at 04:50:45PM +0000, Derrick Stolee via GitGitGadget wrote:\n>> * core.preloadIndex: This value is true by default, now. Removing this\n>>   causes some changes required to the tests that checked this config\n>>   value. Use gui.gcwarning=false instead.\n> \n> I was going to ask about if we could also rely on the default value of\n> index.threads like we do here, but then went and did some reading and realised\n> some config values, like index.recordOffsetTable, have their value set\n> according to whether index.threads was explicitly set, so I guess there's an\n> implicit reliance on that behaviour that we want to keep?\n\nThanks for identifying this subtle behavior. I will mention it explicitly so\nany future change that removes that behavior could also lead to a removal of\nthis explicit setting.\n\nThanks,\n-Stolee\n\n"},{"id":"532075","messageId":"e1d51a8f-582f-425e-9682-c93411b4d090@gmail.com","threadId":"64538","inReplyTo":"e19246a7-40db-41d0-9cdf-817833123f45@igalia.com","subject":"Re: [PATCH v2 5/5] scalar: document config settings","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2025-12-12T14:06:18Z","receivedAt":"2025-12-12T14:06:20Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"On 12/11/2025 9:20 AM, Henrique Ferreiro wrote:\n> On 12/1/25 5:50 PM, Derrick Stolee via GitGitGadget wrote:\n>> From: Derrick Stolee <stolee@gmail.com>\n>>\n>> Add user-facing documentation that justifies the values being set by\n>> 'scalar clone', 'scalar register', and 'scalar reconfigure'.\n> \n> Hi Derrick. I was planning to contribute a patch removing some config\n> options so I'll take this opportunity to just discuss those here.\n> \n> My motivation is that some of the options seem to be related to things\n> other than performance and the list is huge, so I believe that some\n> options don't belong to scalar.\n> \n>> +REQUIRED AND RECOMMENDED CONFIG\n>> +-------------------------------\n> \n> There's no mention on which configs are required and which are\n> recommended, and it looks like none are actually required so maybe just\n> remove REQUIRED.\n\nYou're absolutely right. Good eye! I started this documentation before\ngoing back and removing the \"required\" configs.\n \n>> +am.keepCR=true::\n>> +core.logAllRefUpdates=true::\n>> +credential.https://dev.azure.com.useHttpPath=true::\n>> +http.sslBackend=schannel::\n> \n> These options are not related to performance. Why not keeping them out\n> of scalar?\n> \n>> +core.autoCRLF=false::\n>> +core.safeCRLF=false::\n>> +index.threads=true::\n> \n> These options just duplicate the default settings.\n\nWe did find that index.threads=true gives something more when explicitly\nset, so there is currently value in keeping it explicit.\n\nThe CRLF configs are sometimes set globally on Windows systems, but we\nwant the local repository to override those global settings for\nperformance reasons.\n \n>> +feature.manyFiles=false::\n>> +    This disables the \"many files\" optimizations grouped under this feature\n>> +    config. The expectation is that all valuable optimizations are also set\n>> +    explicitly by Scalar config, and any differences are intentional.\n> \n> I disagree with this reasoning. This thread was actually brought to my\n> attention when working on setting manyFiles to true in scalar:\n> https://github.com/git/git/pull/2125.\n> \n> Do you foresee any features that would apply to scalar but not to\n> manyFiles? I'd even say that some scalar options could be moved to\n> manyFiles instead, so that people that don't use scalar can benefit too.\n\nI suppose that the default reason is that registering a repo with Scalar\nalready enables some config in an \"indirect\" way and having it rely on\nfeatures.manyFiles would be another layer of indirection.\n\nThe historical reason is that we initially didn't want changes to the\nfeatures.* config settings to automatically be assigned to Scalar. I\nthink this is more important on the features.experimental side, as\nthe intention of features.manyFiles is very similar to the intention of\ncloning/registering with Scalar.\n\nFor now, I'm going to leave this as-is, because we have enough changes\nto the config settings and documentation. You can submit a change on top\nof this one to demonstrate the value of setting features.manyFiles=true\nand how that impacts the code in its new shape.\n\nThanks,\n-Stolee\n\n"},{"id":"532079","messageId":"pull.2010.v3.git.1765552528.gitgitgadget@gmail.com","threadId":"64538","inReplyTo":"pull.2010.v2.git.1764607847.gitgitgadget@gmail.com","subject":"[PATCH v3 0/5] Audit and document Scalar config","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-12-12T15:15:23Z","receivedAt":"2025-12-12T15:15:31Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"In September [1], we discussed that the Scalar config options could use some\ndocumented justification as well as some comments to the config file that\nthey were set by Scalar. I was then immediately distracted by other work\nthings and am finally here with a series to do just that.\n\n[1]\nhttps://lore.kernel.org/git/ffa61066-7004-48dd-9096-85b305373bc7@gmail.com/\n\nI have indeed used Patrick's idea to add '# set by scalar' to each line\nadded by Scalar, it took a little more work for all the kinds of config set.\nI made myself a co-author.\n\nWhile working to justify each config option, I found some stale or incorrect\nconfig options. I also relaxed the override setting in most cases which gave\nme an opportunity to alphabetize the settings.\n\nThere was at least one case (I'm thinking of core.fscache here) where the\nconfig doesn't even exist in core Git, but instead in Git for Windows. We'll\nneed to adjust in that fork to reinclude it in the right place.\n\n\nUpdates in V2\n=============\n\n * The config-setting code is simplified somewhat.\n * Use 'sane_unset' instead of 'export' in test.\n * Documentation is improved for typos, grammar, and clarity.\n\n\nUpdates in V3\n=============\n\n * Updated method names when setting recommended config.\n * Updated documentation section title now that nothing is \"required\".\n * Made distinction for index.threads=true as explicit setting.\n * Added documentation for log.exludeDecoration.\n\nThanks, -Stolee\n\nDerrick Stolee (5):\n  scalar: annotate config file with \"set by scalar\"\n  scalar: use index.skipHash=true for performance\n  scalar: remove stale config values\n  scalar: alphabetize and simplify config\n  scalar: document config settings\n\n Documentation/scalar.adoc | 164 ++++++++++++++++++++++++++++++++++++++\n scalar.c                  |  93 +++++++++++----------\n t/t9210-scalar.sh         |  25 +++---\n 3 files changed, 231 insertions(+), 51 deletions(-)\n\n\nbase-commit: 6ab38b7e9cc7adafc304f3204616a4debd49c6e9\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-2010%2Fderrickstolee%2Fscalar-config-v3\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2010/derrickstolee/scalar-config-v3\nPull-Request: https://github.com/gitgitgadget/git/pull/2010\n\nRange-diff vs v2:\n\n 1:  639ff98c44 ! 1:  7a2f919d7c scalar: annotate config file with \"set by scalar\"\n     @@ scalar.c: struct scalar_config {\n       \tint overwrite_on_reconfigure;\n       };\n       \n     -+static int set_config_with_comment(const char *key, const char *value)\n     +-static int set_scalar_config(const struct scalar_config *config, int reconfigure)\n     ++static int set_scalar_config(const char *key, const char *value)\n      +{\n      +\tchar *file = repo_git_path(the_repository, \"config\");\n      +\tint res = repo_config_set_multivar_in_file_gently(the_repository, file,\n     @@ scalar.c: struct scalar_config {\n      +\treturn res;\n      +}\n      +\n     - static int set_scalar_config(const struct scalar_config *config, int reconfigure)\n     ++static int set_config_if_missing(const struct scalar_config *config, int reconfigure)\n       {\n       \tchar *value = NULL;\n     + \tint res;\n      @@ scalar.c: static int set_scalar_config(const struct scalar_config *config, int reconfigure\n       \tif ((reconfigure && config->overwrite_on_reconfigure) ||\n       \t    repo_config_get_string(the_repository, config->key, &value)) {\n       \t\ttrace2_data_string(\"scalar\", the_repository, config->key, \"created\");\n      -\t\tres = repo_config_set_gently(the_repository, config->key, config->value);\n     -+\t\tres = set_config_with_comment(config->key, config->value);\n     ++\t\tres = set_scalar_config(config->key, config->value);\n       \t} else {\n       \t\ttrace2_data_string(\"scalar\", the_repository, config->key, \"exists\");\n       \t\tres = 0;\n     +@@ scalar.c: static int set_recommended_config(int reconfigure)\n     + \tchar *value;\n     + \n     + \tfor (i = 0; config[i].key; i++) {\n     +-\t\tif (set_scalar_config(config + i, reconfigure))\n     ++\t\tif (set_config_if_missing(config + i, reconfigure))\n     + \t\t\treturn error(_(\"could not configure %s=%s\"),\n     + \t\t\t\t     config[i].key, config[i].value);\n     + \t}\n     + \n     + \tif (have_fsmonitor_support()) {\n     + \t\tstruct scalar_config fsmonitor = { \"core.fsmonitor\", \"true\" };\n     +-\t\tif (set_scalar_config(&fsmonitor, reconfigure))\n     ++\t\tif (set_config_if_missing(&fsmonitor, reconfigure))\n     + \t\t\treturn error(_(\"could not configure %s=%s\"),\n     + \t\t\t\t     fsmonitor.key, fsmonitor.value);\n     + \t}\n      @@ scalar.c: static int set_recommended_config(int reconfigure)\n       \tif (repo_config_get_string(the_repository, \"log.excludeDecoration\", &value)) {\n       \t\ttrace2_data_string(\"scalar\", the_repository,\n     @@ scalar.c: static int set_recommended_config(int reconfigure)\n      -\t\tif (repo_config_set_multivar_gently(the_repository, \"log.excludeDecoration\",\n      -\t\t\t\t\t\t    \"refs/prefetch/*\",\n      -\t\t\t\t\t\t    CONFIG_REGEX_NONE, 0))\n     -+\t\tif (set_config_with_comment(\"log.excludeDecoration\",\n     ++\t\tif (set_scalar_config(\"log.excludeDecoration\",\n      +\t\t\t\t\t    \"refs/prefetch/*\"))\n       \t\t\treturn error(_(\"could not configure \"\n       \t\t\t\t       \"log.excludeDecoration\"));\n 2:  10e9548955 = 2:  573929ecdb scalar: use index.skipHash=true for performance\n 3:  8783db6153 = 3:  85b499a616 scalar: remove stale config values\n 4:  edc0254770 = 4:  c30ffc87dc scalar: alphabetize and simplify config\n 5:  ac1627dbd9 ! 5:  f062b0e077 scalar: document config settings\n     @@ Documentation/scalar.adoc: delete <enlistment>::\n       \tThis subcommand lets you delete an existing Scalar enlistment from your\n       \tlocal file system, unregistering the repository.\n       \n     -+REQUIRED AND RECOMMENDED CONFIG\n     -+-------------------------------\n     ++RECOMMENDED CONFIG VALUES\n     ++-------------------------\n      +\n      +As part of both `scalar clone` and `scalar register`, certain Git config\n      +values are set to optimize for large repositories or cross-platform support.\n     @@ Documentation/scalar.adoc: delete <enlistment>::\n      +\n      +index.threads=true::\n      +\tThis tells Git to automatically detect how many threads it should use\n     -+\twhen reading the index due to the default value of `core.preloadIndex`,\n     -+\twhich enables parallel index reads.\n     ++\twhen reading the index due the default value of\t`core.preloadIndex`,\n     ++\twhich enables parallel index reads. This explicit setting also enables\n     ++\t`index.recordOffsetTable=true` to speed up parallel index reads.\n      +\n      +index.version=4::\n      +\tThis index version adds compression to the path names, reducing the size\n      +\tof the index in a significant way for large repos. This is an important\n      +\tperformance boost.\n      +\n     ++log.excludeDecoration=refs/prefetch/*::\n     ++\tSince Scalar enables background maintenance with the `incremental`\n     ++\tstrategy, this setting avoids polluting `git log` output with refs\n     ++\tstored by the background prefetch operations.\n     ++\n      +merge.renames=true::\n      +\tWhen computing merges in large repos, it is particularly important to\n      +\tdetect renames to maximize the potential for a result that will validate\n     @@ Documentation/scalar.adoc: delete <enlistment>::\n       SEE ALSO\n       --------\n       linkgit:git-clone[1], linkgit:git-maintenance[1].\n     +\n     + ## scalar.c ##\n     +@@ scalar.c: static int have_fsmonitor_support(void)\n     + \n     + static int set_recommended_config(int reconfigure)\n     + {\n     ++\t/*\n     ++\t * Be sure to update Documentation/scalar.adoc if you add, update,\n     ++\t * or remove any of these recommended settings.\n     ++\t */\n     + \tstruct scalar_config config[] = {\n     + \t\t{ \"am.keepCR\", \"true\" },\n     + \t\t{ \"commitGraph.changedPaths\", \"true\" },\n\n-- \ngitgitgadget\n"},{"id":"532080","messageId":"7a2f919d7c610ce7c9e93682884212ebee34d9b5.1765552528.git.gitgitgadget@gmail.com","threadId":"64538","inReplyTo":"pull.2010.v3.git.1765552528.gitgitgadget@gmail.com","subject":"[PATCH v3 1/5] scalar: annotate config file with \"set by scalar\"","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-12-12T15:15:24Z","receivedAt":"2025-12-12T15:15:32Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <stolee@gmail.com>\n\nA repo may have config options set by 'scalar clone' or 'scalar\nregister' and then updated by 'scalar reconfigure'. It can be helpful to\npoint out which of those options were set by the latest scalar\nrecommendations.\n\nAdd \"# set by scalar\" to the end of each config option to assist users\nin identifying why these config options were set in their repo. Use a new\nhelper method to simplify the two callsites.\n\nCo-authored-by: Patrick Steinhardt <ps@pks.im>\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\nSigned-off-by: Derrick Stolee <stolee@gmail.com>\n---\n scalar.c          | 24 +++++++++++++++++-------\n t/t9210-scalar.sh |  3 +++\n 2 files changed, 20 insertions(+), 7 deletions(-)\n\ndiff --git a/scalar.c b/scalar.c\nindex f754311627..1c7bd1a8f8 100644\n--- a/scalar.c\n+++ b/scalar.c\n@@ -19,6 +19,7 @@\n #include \"help.h\"\n #include \"setup.h\"\n #include \"trace2.h\"\n+#include \"path.h\"\n \n static void setup_enlistment_directory(int argc, const char **argv,\n \t\t\t\t       const char * const *usagestr,\n@@ -95,7 +96,17 @@ struct scalar_config {\n \tint overwrite_on_reconfigure;\n };\n \n-static int set_scalar_config(const struct scalar_config *config, int reconfigure)\n+static int set_scalar_config(const char *key, const char *value)\n+{\n+\tchar *file = repo_git_path(the_repository, \"config\");\n+\tint res = repo_config_set_multivar_in_file_gently(the_repository, file,\n+\t\t\t\t\t\t\t  key, value, NULL,\n+\t\t\t\t\t\t\t  \" # set by scalar\", 0);\n+\tfree(file);\n+\treturn res;\n+}\n+\n+static int set_config_if_missing(const struct scalar_config *config, int reconfigure)\n {\n \tchar *value = NULL;\n \tint res;\n@@ -103,7 +114,7 @@ static int set_scalar_config(const struct scalar_config *config, int reconfigure\n \tif ((reconfigure && config->overwrite_on_reconfigure) ||\n \t    repo_config_get_string(the_repository, config->key, &value)) {\n \t\ttrace2_data_string(\"scalar\", the_repository, config->key, \"created\");\n-\t\tres = repo_config_set_gently(the_repository, config->key, config->value);\n+\t\tres = set_scalar_config(config->key, config->value);\n \t} else {\n \t\ttrace2_data_string(\"scalar\", the_repository, config->key, \"exists\");\n \t\tres = 0;\n@@ -178,14 +189,14 @@ static int set_recommended_config(int reconfigure)\n \tchar *value;\n \n \tfor (i = 0; config[i].key; i++) {\n-\t\tif (set_scalar_config(config + i, reconfigure))\n+\t\tif (set_config_if_missing(config + i, reconfigure))\n \t\t\treturn error(_(\"could not configure %s=%s\"),\n \t\t\t\t     config[i].key, config[i].value);\n \t}\n \n \tif (have_fsmonitor_support()) {\n \t\tstruct scalar_config fsmonitor = { \"core.fsmonitor\", \"true\" };\n-\t\tif (set_scalar_config(&fsmonitor, reconfigure))\n+\t\tif (set_config_if_missing(&fsmonitor, reconfigure))\n \t\t\treturn error(_(\"could not configure %s=%s\"),\n \t\t\t\t     fsmonitor.key, fsmonitor.value);\n \t}\n@@ -197,9 +208,8 @@ static int set_recommended_config(int reconfigure)\n \tif (repo_config_get_string(the_repository, \"log.excludeDecoration\", &value)) {\n \t\ttrace2_data_string(\"scalar\", the_repository,\n \t\t\t\t   \"log.excludeDecoration\", \"created\");\n-\t\tif (repo_config_set_multivar_gently(the_repository, \"log.excludeDecoration\",\n-\t\t\t\t\t\t    \"refs/prefetch/*\",\n-\t\t\t\t\t\t    CONFIG_REGEX_NONE, 0))\n+\t\tif (set_scalar_config(\"log.excludeDecoration\",\n+\t\t\t\t\t    \"refs/prefetch/*\"))\n \t\t\treturn error(_(\"could not configure \"\n \t\t\t\t       \"log.excludeDecoration\"));\n \t} else {\ndiff --git a/t/t9210-scalar.sh b/t/t9210-scalar.sh\nindex bd6f0c40d2..43c210a23d 100755\n--- a/t/t9210-scalar.sh\n+++ b/t/t9210-scalar.sh\n@@ -210,6 +210,9 @@ test_expect_success 'scalar reconfigure' '\n \tGIT_TRACE2_EVENT=\"$(pwd)/reconfigure\" scalar reconfigure -a &&\n \ttest_path_is_file one/src/cron.txt &&\n \ttest true = \"$(git -C one/src config core.preloadIndex)\" &&\n+\ttest_grep \"preloadIndex = true # set by scalar\" one/src/.git/config &&\n+\ttest_grep \"excludeDecoration = refs/prefetch/\\* # set by scalar\" one/src/.git/config &&\n+\n \ttest_subcommand git maintenance start <reconfigure &&\n \ttest_subcommand ! git maintenance unregister --force <reconfigure &&\n \n-- \ngitgitgadget\n\n"},{"id":"532081","messageId":"573929ecdb950e3c3e862f14c59ed5a544b8b6ca.1765552528.git.gitgitgadget@gmail.com","threadId":"64538","inReplyTo":"pull.2010.v3.git.1765552528.gitgitgadget@gmail.com","subject":"[PATCH v3 2/5] scalar: use index.skipHash=true for performance","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-12-12T15:15:25Z","receivedAt":"2025-12-12T15:15:34Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <stolee@gmail.com>\n\nThe index.skipHash config option has been set to 'false' by Scalar since\n4933152cbb (scalar: enable path-walk during push via config, 2025-05-16)\nbut that commit message is trying to communicate the exact opposite:\nthat the 'true' value is what we want instead. This means that we've\nbeen disabling this performance benefit for Scalar repos\nunintentionally.\n\nFix this issue before we add justification for the config options set in\nthis list.\n\nOddly, enabling index.skipHash causes a test issue during 'test_commit'\nin one of the Scalar tests when GIT_TEST_SPLIT_INDEX is enabled (as\ncaught by the linux-test-vars build). I'm fixing the test by disabling\nthe environment variable, but the issue should be resolved in a series\nfocused on the split index.\n\nSigned-off-by: Derrick Stolee <stolee@gmail.com>\n---\n scalar.c          | 2 +-\n t/t9210-scalar.sh | 4 ++++\n 2 files changed, 5 insertions(+), 1 deletion(-)\n\ndiff --git a/scalar.c b/scalar.c\nindex 1c7bd1a8f8..55b8542770 100644\n--- a/scalar.c\n+++ b/scalar.c\n@@ -160,7 +160,7 @@ static int set_recommended_config(int reconfigure)\n \t\t{ \"credential.validate\", \"false\", 1 }, /* GCM4W-only */\n \t\t{ \"gc.auto\", \"0\", 1 },\n \t\t{ \"gui.GCWarning\", \"false\", 1 },\n-\t\t{ \"index.skipHash\", \"false\", 1 },\n+\t\t{ \"index.skipHash\", \"true\", 1 },\n \t\t{ \"index.threads\", \"true\", 1 },\n \t\t{ \"index.version\", \"4\", 1 },\n \t\t{ \"merge.stat\", \"false\", 1 },\ndiff --git a/t/t9210-scalar.sh b/t/t9210-scalar.sh\nindex 43c210a23d..923c243c13 100755\n--- a/t/t9210-scalar.sh\n+++ b/t/t9210-scalar.sh\n@@ -246,6 +246,10 @@ test_expect_success 'scalar reconfigure --all with includeIf.onbranch' '\n '\n \n test_expect_success 'scalar reconfigure --all with detached HEADs' '\n+\t# This test demonstrates an issue with index.skipHash=true and\n+\t# this test variable for the split index. Disable the test variable.\n+\tsane_unset GIT_TEST_SPLIT_INDEX &&\n+\n \trepos=\"two three four\" &&\n \tfor num in $repos\n \tdo\n-- \ngitgitgadget\n\n"},{"id":"532082","messageId":"85b499a616d7595287499e14358bc76618881e44.1765552528.git.gitgitgadget@gmail.com","threadId":"64538","inReplyTo":"pull.2010.v3.git.1765552528.gitgitgadget@gmail.com","subject":"[PATCH v3 3/5] scalar: remove stale config values","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-12-12T15:15:26Z","receivedAt":"2025-12-12T15:15:35Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <stolee@gmail.com>\n\nThese config values were added in the original Scalar contribution,\nd0feac4e8c (scalar: 'register' sets recommended config and starts\nmaintenance, 2021-12-03), but were never fully checked for validity in\nthe upstream Git project. At the time, Scalar was only intended for the\ncontrib/ directory so did not have as rigorous of an investigation.\n\nEach config option has its own justification for removal:\n\n* core.preloadIndex: This value is true by default, now. Removing this\n  causes some changes required to the tests that checked this config\n  value. Use gui.gcwarning=false instead.\n\n* core.fscache: This config does not exist in the core Git project, but\n  is instead a config option for a Git for Windows feature.\n\n* core.multiPackIndex: This config value is now enabled by default, so\n  does not need to be called out specifically. It was originally\n  included to make sure the background maintenance that created\n  multi-pack-indexes would result in the expected performance\n  improvements.\n\n* credential.validate: This option is not something specific to Git but\n  instead an older version of Git Credential Manager for Windows. That\n  software was replaced several years ago by the cross-platform Git\n  Credential Manger so this option is no longer needed to help users who\n  were on that older software.\n\n* pack.useSparse=true: This value is now Git's default as of de3a864114\n  (config: set pack.useSparse=true by default, 2020-03-20) so we don't\n  need it set by Scalar.\n\nSigned-off-by: Derrick Stolee <stolee@gmail.com>\n---\n scalar.c          |  5 -----\n t/t9210-scalar.sh | 20 ++++++++++----------\n 2 files changed, 10 insertions(+), 15 deletions(-)\n\ndiff --git a/scalar.c b/scalar.c\nindex 55b8542770..aeebea41fa 100644\n--- a/scalar.c\n+++ b/scalar.c\n@@ -135,9 +135,6 @@ static int set_recommended_config(int reconfigure)\n \tstruct scalar_config config[] = {\n \t\t/* Required */\n \t\t{ \"am.keepCR\", \"true\", 1 },\n-\t\t{ \"core.FSCache\", \"true\", 1 },\n-\t\t{ \"core.multiPackIndex\", \"true\", 1 },\n-\t\t{ \"core.preloadIndex\", \"true\", 1 },\n #ifndef WIN32\n \t\t{ \"core.untrackedCache\", \"true\", 1 },\n #else\n@@ -157,7 +154,6 @@ static int set_recommended_config(int reconfigure)\n #endif\n \t\t{ \"core.logAllRefUpdates\", \"true\", 1 },\n \t\t{ \"credential.https://dev.azure.com.useHttpPath\", \"true\", 1 },\n-\t\t{ \"credential.validate\", \"false\", 1 }, /* GCM4W-only */\n \t\t{ \"gc.auto\", \"0\", 1 },\n \t\t{ \"gui.GCWarning\", \"false\", 1 },\n \t\t{ \"index.skipHash\", \"true\", 1 },\n@@ -166,7 +162,6 @@ static int set_recommended_config(int reconfigure)\n \t\t{ \"merge.stat\", \"false\", 1 },\n \t\t{ \"merge.renames\", \"true\", 1 },\n \t\t{ \"pack.useBitmaps\", \"false\", 1 },\n-\t\t{ \"pack.useSparse\", \"true\", 1 },\n \t\t{ \"receive.autoGC\", \"false\", 1 },\n \t\t{ \"feature.manyFiles\", \"false\", 1 },\n \t\t{ \"feature.experimental\", \"false\", 1 },\ndiff --git a/t/t9210-scalar.sh b/t/t9210-scalar.sh\nindex 923c243c13..009437a5f3 100755\n--- a/t/t9210-scalar.sh\n+++ b/t/t9210-scalar.sh\n@@ -202,15 +202,15 @@ test_expect_success 'scalar clone --no-... opts' '\n test_expect_success 'scalar reconfigure' '\n \tgit init one/src &&\n \tscalar register one &&\n-\tgit -C one/src config core.preloadIndex false &&\n+\tgit -C one/src config unset gui.gcwarning &&\n \tscalar reconfigure one &&\n-\ttest true = \"$(git -C one/src config core.preloadIndex)\" &&\n-\tgit -C one/src config core.preloadIndex false &&\n+\ttest false = \"$(git -C one/src config gui.gcwarning)\" &&\n+\tgit -C one/src config unset gui.gcwarning &&\n \trm one/src/cron.txt &&\n \tGIT_TRACE2_EVENT=\"$(pwd)/reconfigure\" scalar reconfigure -a &&\n \ttest_path_is_file one/src/cron.txt &&\n-\ttest true = \"$(git -C one/src config core.preloadIndex)\" &&\n-\ttest_grep \"preloadIndex = true # set by scalar\" one/src/.git/config &&\n+\ttest false = \"$(git -C one/src config gui.gcwarning)\" &&\n+\ttest_grep \"GCWarning = false # set by scalar\" one/src/.git/config &&\n \ttest_grep \"excludeDecoration = refs/prefetch/\\* # set by scalar\" one/src/.git/config &&\n \n \ttest_subcommand git maintenance start <reconfigure &&\n@@ -234,14 +234,14 @@ test_expect_success 'scalar reconfigure --all with includeIf.onbranch' '\n \t\tgit init $num/src &&\n \t\tscalar register $num/src &&\n \t\tgit -C $num/src config includeif.\"onbranch:foo\".path something &&\n-\t\tgit -C $num/src config core.preloadIndex false || return 1\n+\t\tgit -C $num/src config unset gui.gcwarning || return 1\n \tdone &&\n \n \tscalar reconfigure --all &&\n \n \tfor num in $repos\n \tdo\n-\t\ttest true = \"$(git -C $num/src config core.preloadIndex)\" || return 1\n+\t\ttest false = \"$(git -C $num/src config gui.gcwarning)\" || return 1\n \tdone\n '\n \n@@ -256,7 +256,7 @@ test_expect_success 'scalar reconfigure --all with detached HEADs' '\n \t\trm -rf $num/src &&\n \t\tgit init $num/src &&\n \t\tscalar register $num/src &&\n-\t\tgit -C $num/src config core.preloadIndex false &&\n+\t\tgit -C $num/src config unset gui.gcwarning &&\n \t\ttest_commit -C $num/src initial &&\n \t\tgit -C $num/src switch --detach HEAD || return 1\n \tdone &&\n@@ -265,7 +265,7 @@ test_expect_success 'scalar reconfigure --all with detached HEADs' '\n \n \tfor num in $repos\n \tdo\n-\t\ttest true = \"$(git -C $num/src config core.preloadIndex)\" || return 1\n+\t\ttest false = \"$(git -C $num/src config gui.gcwarning)\" || return 1\n \tdone\n '\n \n@@ -297,7 +297,7 @@ test_expect_success 'scalar supports -c/-C' '\n \tgit init sub &&\n \tscalar -C sub -c status.aheadBehind=bogus register &&\n \ttest -z \"$(git -C sub config --local status.aheadBehind)\" &&\n-\ttest true = \"$(git -C sub config core.preloadIndex)\"\n+\ttest false = \"$(git -C sub config gui.gcwarning)\"\n '\n \n test_expect_success '`scalar [...] <dir>` errors out when dir is missing' '\n-- \ngitgitgadget\n\n"},{"id":"532083","messageId":"c30ffc87dc9ae61f87087e2fb8b325ae4fdb984a.1765552528.git.gitgitgadget@gmail.com","threadId":"64538","inReplyTo":"pull.2010.v3.git.1765552528.gitgitgadget@gmail.com","subject":"[PATCH v3 4/5] scalar: alphabetize and simplify config","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-12-12T15:15:27Z","receivedAt":"2025-12-12T15:15:37Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <stolee@gmail.com>\n\nThe config values set by Scalar went through an audit in the previous\nchanges, so now reorganize the settings and simplify their purpose.\n\nFirst, alphabetize the config options, except put the platform-specific\noptions at the end. This groups two Windows-specific settings and only\none non-Windows setting.\n\nAlso, this removes the 'overwrite_on_reconfigure' setting for many of\nthese options. That setting made nearly all of these options \"required\"\nfor scalar enlistments, restricting use for users. Instead, now nearly\nall options have removed this setting.\n\nHowever, there is one setting that still has this, which is\nindex.skipHash, which was previously being set to _false_ when we\nactually prefer the value of true. Keep the overwrite here to help\nScalar users upgrade to the new version. We may remove that overwrite in\nthe future once we belive that most of the users who have the false\nvalue have upgraded to a version that overwrites that to 'true'.\n\nSigned-off-by: Derrick Stolee <stolee@gmail.com>\n---\n scalar.c | 60 ++++++++++++++++++++++++++++----------------------------\n 1 file changed, 30 insertions(+), 30 deletions(-)\n\ndiff --git a/scalar.c b/scalar.c\nindex aeebea41fa..3b25fd3f35 100644\n--- a/scalar.c\n+++ b/scalar.c\n@@ -133,10 +133,33 @@ static int have_fsmonitor_support(void)\n static int set_recommended_config(int reconfigure)\n {\n \tstruct scalar_config config[] = {\n-\t\t/* Required */\n-\t\t{ \"am.keepCR\", \"true\", 1 },\n+\t\t{ \"am.keepCR\", \"true\" },\n+\t\t{ \"commitGraph.changedPaths\", \"true\" },\n+\t\t{ \"commitGraph.generationVersion\", \"1\" },\n+\t\t{ \"core.autoCRLF\", \"false\" },\n+\t\t{ \"core.logAllRefUpdates\", \"true\" },\n+\t\t{ \"core.safeCRLF\", \"false\" },\n+\t\t{ \"credential.https://dev.azure.com.useHttpPath\", \"true\" },\n+\t\t{ \"feature.experimental\", \"false\" },\n+\t\t{ \"feature.manyFiles\", \"false\" },\n+\t\t{ \"fetch.showForcedUpdates\", \"false\" },\n+\t\t{ \"fetch.unpackLimit\", \"1\" },\n+\t\t{ \"fetch.writeCommitGraph\", \"false\" },\n+\t\t{ \"gc.auto\", \"0\" },\n+\t\t{ \"gui.GCWarning\", \"false\" },\n+\t\t{ \"index.skipHash\", \"true\", 1 /* Fix previous setting. */ },\n+\t\t{ \"index.threads\", \"true\"},\n+\t\t{ \"index.version\", \"4\" },\n+\t\t{ \"merge.renames\", \"true\" },\n+\t\t{ \"merge.stat\", \"false\" },\n+\t\t{ \"pack.useBitmaps\", \"false\" },\n+\t\t{ \"pack.usePathWalk\", \"true\" },\n+\t\t{ \"receive.autoGC\", \"false\" },\n+\t\t{ \"status.aheadBehind\", \"false\" },\n+\n+\t\t/* platform-specific */\n #ifndef WIN32\n-\t\t{ \"core.untrackedCache\", \"true\", 1 },\n+\t\t{ \"core.untrackedCache\", \"true\" },\n #else\n \t\t/*\n \t\t * Unfortunately, Scalar's Functional Tests demonstrated\n@@ -150,34 +173,11 @@ static int set_recommended_config(int reconfigure)\n \t\t * Therefore, with a sad heart, we disable this very useful\n \t\t * feature on Windows.\n \t\t */\n-\t\t{ \"core.untrackedCache\", \"false\", 1 },\n-#endif\n-\t\t{ \"core.logAllRefUpdates\", \"true\", 1 },\n-\t\t{ \"credential.https://dev.azure.com.useHttpPath\", \"true\", 1 },\n-\t\t{ \"gc.auto\", \"0\", 1 },\n-\t\t{ \"gui.GCWarning\", \"false\", 1 },\n-\t\t{ \"index.skipHash\", \"true\", 1 },\n-\t\t{ \"index.threads\", \"true\", 1 },\n-\t\t{ \"index.version\", \"4\", 1 },\n-\t\t{ \"merge.stat\", \"false\", 1 },\n-\t\t{ \"merge.renames\", \"true\", 1 },\n-\t\t{ \"pack.useBitmaps\", \"false\", 1 },\n-\t\t{ \"receive.autoGC\", \"false\", 1 },\n-\t\t{ \"feature.manyFiles\", \"false\", 1 },\n-\t\t{ \"feature.experimental\", \"false\", 1 },\n-\t\t{ \"fetch.unpackLimit\", \"1\", 1 },\n-\t\t{ \"fetch.writeCommitGraph\", \"false\", 1 },\n-#ifdef WIN32\n-\t\t{ \"http.sslBackend\", \"schannel\", 1 },\n+\t\t{ \"core.untrackedCache\", \"false\" },\n+\n+\t\t/* Other Windows-specific required settings: */\n+\t\t{ \"http.sslBackend\", \"schannel\" },\n #endif\n-\t\t/* Optional */\n-\t\t{ \"status.aheadBehind\", \"false\" },\n-\t\t{ \"commitGraph.changedPaths\", \"true\" },\n-\t\t{ \"commitGraph.generationVersion\", \"1\" },\n-\t\t{ \"core.autoCRLF\", \"false\" },\n-\t\t{ \"core.safeCRLF\", \"false\" },\n-\t\t{ \"fetch.showForcedUpdates\", \"false\" },\n-\t\t{ \"pack.usePathWalk\", \"true\" },\n \t\t{ NULL, NULL },\n \t};\n \tint i;\n-- \ngitgitgadget\n\n"},{"id":"532084","messageId":"f062b0e0773b9d168c031bb1f35538665394a077.1765552528.git.gitgitgadget@gmail.com","threadId":"64538","inReplyTo":"pull.2010.v3.git.1765552528.gitgitgadget@gmail.com","subject":"[PATCH v3 5/5] scalar: document config settings","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-12-12T15:15:28Z","receivedAt":"2025-12-12T15:15:39Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <stolee@gmail.com>\n\nAdd user-facing documentation that justifies the values being set by\n'scalar clone', 'scalar register', and 'scalar reconfigure'.\n\nHelped-by: Junio C Hamano <gitster@pobox.com>\nHelped-by: Patrick Steinhardt <ps@pks.im>\nSigned-off-by: Derrick Stolee <stolee@gmail.com>\n---\n Documentation/scalar.adoc | 164 ++++++++++++++++++++++++++++++++++++++\n scalar.c                  |   4 +\n 2 files changed, 168 insertions(+)\n\ndiff --git a/Documentation/scalar.adoc b/Documentation/scalar.adoc\nindex f81b2832f8..ee9fc0ac0c 100644\n--- a/Documentation/scalar.adoc\n+++ b/Documentation/scalar.adoc\n@@ -197,6 +197,170 @@ delete <enlistment>::\n \tThis subcommand lets you delete an existing Scalar enlistment from your\n \tlocal file system, unregistering the repository.\n \n+RECOMMENDED CONFIG VALUES\n+-------------------------\n+\n+As part of both `scalar clone` and `scalar register`, certain Git config\n+values are set to optimize for large repositories or cross-platform support.\n+These options are updated in new Git versions according to the best known\n+advice for large repositories, and users can get the latest recommendations\n+by running `scalar reconfigure [--all]`.\n+\n+This section lists justifications for the config values that are set in the\n+latest version.\n+\n+am.keepCR=true::\n+\tThis setting is important for cross-platform development across Windows\n+\tand non-Windows platforms and keeping carriage return (`\\r`) characters\n+\tin certain workflows.\n+\n+commitGraph.changedPaths=true::\n+\tThis setting helps the background maintenance steps that compute the\n+\tserialized commit-graph to also store changed-path Bloom filters. This\n+\taccelerates file history commands and allows users to automatically\n+\tbenefit without running a foreground command.\n+\n+commitGraph.generationVersion=1::\n+\tWhile the preferred version is 2 for performance reasons, existing users\n+\tthat had version 1 by default will need special care in upgrading to\n+\tversion 2. This is likely to change in the future as the upgrade story\n+\tsolidifies.\n+\n+core.autoCRLF=false::\n+\tThis removes the transformation of worktree files to add CRLF line\n+\tendings when only LF line endings exist. This is removed for performance\n+\treasons. Repositories that use tools that care about CRLF line endings\n+\tshould commit the necessary files with those line endings instead.\n+\n+core.logAllRefUpdates=true::\n+\tThis enables the reflog on all branches. While this is a performance\n+\tcost for large repositories, it is frequently an important data source\n+\tfor users to get out of bad situations or to seek support from experts.\n+\n+core.safeCRLF=false::\n+\tSimilar to `core.autoCRLF=false`, this disables checks around whether\n+\tthe CRLF conversion is reversible. This is a performance improvement,\n+\tbut can be dangerous if `core.autoCRLF` is reenabled by the user.\n+\n+credential.https://dev.azure.com.useHttpPath=true::\n+\tThis setting enables the `credential.useHttpPath` feature only for web\n+\tURLs for Azure DevOps. This is important for users interacting with that\n+\tservice using multiple organizations and thus multiple credential\n+\ttokens.\n+\n+feature.experimental=false::\n+\tThis disables the \"experimental\" optimizations grouped under this\n+\tfeature config. The expectation is that all valuable optimizations are\n+\talso set explicitly by Scalar config, and any differences are\n+\tintentional. Notable differences include several bitmap-related config\n+\toptions which are disabled for client-focused Scalar repos.\n+\n+feature.manyFiles=false::\n+\tThis disables the \"many files\" optimizations grouped under this feature\n+\tconfig. The expectation is that all valuable optimizations are also set\n+\texplicitly by Scalar config, and any differences are intentional.\n+\n+fetch.showForcedUpdates=false::\n+\tThis disables the check at the end of `git fetch` that notifies the user\n+\tif the ref update was a forced update (one where the previous position\n+\tis not reachable from the latest position). This check can be very\n+\texpensive in large repositories, so is disabled and replaced with an\n+\tadvice message. Set `advice.fetchShowForcedUpdates=false` to disable\n+\tthis advice message.\n+\n+fetch.unpackLimit=1::\n+\tThis setting prevents Git from unpacking packfiles into loose objects\n+\tas they are downloaded from the server. The default limit of 100 was\n+\tintended as a way to prevent performance issues from too many packfiles,\n+\tbut Scalar uses background maintenance to group packfiles and cover them\n+\twith a multi-pack-index, removing this issue.\n+\n+fetch.writeCommitGraph=false::\n+\tThis config setting was created to help users automatically update their\n+\tcommit-graph files as they perform fetches. However, this takes time\n+\tfrom foreground fetches and pulls and Scalar uses background maintenance\n+\tfor this function instead.\n+\n+gc.auto=0::\n+\tThis disables automatic garbage collection, since Scalar uses background\n+\tmaintenance to keep the repository data in good shape.\n+\n+gui.GCWarning=false::\n+\tSince Scalar disables garbage collection by setting `gc.auto=0`, the\n+\t`git-gui` tool may start to warn about this setting. Disable this\n+\twarning as Scalar's background maintenance configuration makes the\n+\twarning irrelevant.\n+\n+index.skipHash=true::\n+\tDisable computing the hash of the index contents as it is being written.\n+\tThis assists with performance, especially for large index files.\n+\n+index.threads=true::\n+\tThis tells Git to automatically detect how many threads it should use\n+\twhen reading the index due the default value of\t`core.preloadIndex`,\n+\twhich enables parallel index reads. This explicit setting also enables\n+\t`index.recordOffsetTable=true` to speed up parallel index reads.\n+\n+index.version=4::\n+\tThis index version adds compression to the path names, reducing the size\n+\tof the index in a significant way for large repos. This is an important\n+\tperformance boost.\n+\n+log.excludeDecoration=refs/prefetch/*::\n+\tSince Scalar enables background maintenance with the `incremental`\n+\tstrategy, this setting avoids polluting `git log` output with refs\n+\tstored by the background prefetch operations.\n+\n+merge.renames=true::\n+\tWhen computing merges in large repos, it is particularly important to\n+\tdetect renames to maximize the potential for a result that will validate\n+\tcorrectly. Users performing merges locally are more likely to be doing\n+\tso because a server-side merge (via pull request or similar) resulted in\n+\tconflicts. While this is the default setting, it is set specifically to\n+\toverride a potential change to `diff.renames` which a user may set for\n+\tperformance reasons.\n+\n+merge.stat=false::\n+\tThis disables a diff output after computing a merge. This improves\n+\tperformance of `git merge` for large repos while reducing noisy output.\n+\n+pack.useBitmaps=false::\n+\tThis disables the use of `.bitmap` files attached to packfiles. Bitmap\n+\tfiles are optimized for server-side use, not client-side use. Scalar\n+\tdisables this to avoid some performance issues that can occur if a user\n+\taccidentally creates `.bitmap` files.\n+\n+pack.usePathWalk=true::\n+\tThis enables the `--path-walk` option to `git pack-objects` by default.\n+\tThis can accelerate the computation and compression of packfiles created\n+\tby `git push` and other repack operations.\n+\n+receive.autoGC=false::\n+\tSimilar to `gc.auto`, this setting is disabled in preference of\n+\tbackground maintenance.\n+\n+status.aheadBehind=false::\n+\tThis disables the ahead/behind calculation that would normally happen\n+\tduring a `git status` command. This information is frequently ignored by\n+\tusers but can be expensive to calculate in large repos that receive\n+\tthousands of commits per day. The calculation is replaced with an advice\n+\tmessage that can be disabled by disabling the `advice.statusAheadBehind`\n+\tconfig.\n+\n+The following settings are different based on which platform is in use:\n+\n+core.untrackedCache=(true|false)::\n+\tThe untracked cache feature is important for performance benefits on\n+\tlarge repositories, but has demonstrated some bugs on Windows\n+\tfilesystems. Thus, this is set for other platforms but disabled on\n+\tWindows.\n+\n+http.sslBackend=schannel::\n+\tOn Windows, the `openssl` backend has some issues with certain types of\n+\tremote providers and certificate types. Override the default setting to\n+\tavoid these common problems.\n+\n+\n SEE ALSO\n --------\n linkgit:git-clone[1], linkgit:git-maintenance[1].\ndiff --git a/scalar.c b/scalar.c\nindex 3b25fd3f35..21ab1dba89 100644\n--- a/scalar.c\n+++ b/scalar.c\n@@ -132,6 +132,10 @@ static int have_fsmonitor_support(void)\n \n static int set_recommended_config(int reconfigure)\n {\n+\t/*\n+\t * Be sure to update Documentation/scalar.adoc if you add, update,\n+\t * or remove any of these recommended settings.\n+\t */\n \tstruct scalar_config config[] = {\n \t\t{ \"am.keepCR\", \"true\" },\n \t\t{ \"commitGraph.changedPaths\", \"true\" },\n-- \ngitgitgadget\n"},{"id":"532106","messageId":"xmqqecozb6rl.fsf@gitster.g","threadId":"64538","inReplyTo":"pull.2010.v3.git.1765552528.gitgitgadget@gmail.com","subject":"Re: [PATCH v3 0/5] Audit and document Scalar config","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-12-12T23:49:18Z","receivedAt":"2025-12-12T23:49:21Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Derrick Stolee via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> Updates in V3\n> =============\n>\n>  * Updated method names when setting recommended config.\n>  * Updated documentation section title now that nothing is \"required\".\n>  * Made distinction for index.threads=true as explicit setting.\n>  * Added documentation for log.exludeDecoration.\n\nLooking good.\n\n>       +index.threads=true::\n>       +\tThis tells Git to automatically detect how many threads it should use\n>      -+\twhen reading the index due to the default value of `core.preloadIndex`,\n>      -+\twhich enables parallel index reads.\n>      ++\twhen reading the index due the default value of\t`core.preloadIndex`,\n>      ++\twhich enables parallel index reads. This explicit setting also enables\n>      ++\t`index.recordOffsetTable=true` to speed up parallel index reads.\n\nI understood the previous \"due to\" version (from the middle school\nEnglish class I took eons ago), but not the updated one.\n\nOther than that, there weren't anything iffy in the new version.\nWill replace.  Thanks.\n\n"},{"id":"532186","messageId":"df0641d3-33d6-4d11-a931-0a8b12ab1c5a@igalia.com","threadId":"64538","inReplyTo":"e1d51a8f-582f-425e-9682-c93411b4d090@gmail.com","subject":"Re: [PATCH v2 5/5] scalar: document config settings","fromName":"Henrique Ferreiro","fromEmail":"hferreiro@igalia.com","sentAt":"2025-12-15T12:14:55Z","receivedAt":"2025-12-15T12:15:00Z","isPatch":true,"sender":{"key":"hferreiro@igalia.com","avatar":"https://avatars.githubusercontent.com/u/984737?v=4"},"body":"\n\nOn 12/12/25 3:06 PM, Derrick Stolee wrote:\n> On 12/11/2025 9:20 AM, Henrique Ferreiro wrote:\n>> On 12/1/25 5:50 PM, Derrick Stolee via GitGitGadget wrote:\n>>> From: Derrick Stolee <stolee@gmail.com>\n>>>\n>>> Add user-facing documentation that justifies the values being set by\n>>> 'scalar clone', 'scalar register', and 'scalar reconfigure'.\n>>\n>> Hi Derrick. I was planning to contribute a patch removing some config\n>> options so I'll take this opportunity to just discuss those here.\n>>\n>> My motivation is that some of the options seem to be related to things\n>> other than performance and the list is huge, so I believe that some\n>> options don't belong to scalar.\n>>\n>>> +REQUIRED AND RECOMMENDED CONFIG\n>>> +-------------------------------\n>>\n>> There's no mention on which configs are required and which are\n>> recommended, and it looks like none are actually required so maybe just\n>> remove REQUIRED.\n> \n> You're absolutely right. Good eye! I started this documentation before\n> going back and removing the \"required\" configs.\n>   \n>>> +am.keepCR=true::\n>>> +core.logAllRefUpdates=true::\n>>> +credential.https://dev.azure.com.useHttpPath=true::\n>>> +http.sslBackend=schannel::\n>>\n>> These options are not related to performance. Why not keeping them out\n>> of scalar?\n\nIt appears you missed my question above.\n\n>>> +core.autoCRLF=false::\n>>> +core.safeCRLF=false::\n>>> +index.threads=true::\n>>\n>> These options just duplicate the default settings.\n> \n> We did find that index.threads=true gives something more when explicitly\n> set, so there is currently value in keeping it explicit.\n> \n> The CRLF configs are sometimes set globally on Windows systems, but we\n> want the local repository to override those global settings for\n> performance reasons.\n\nGiven that this is just a possibility, and also that it only affects a\nsubset of users, wouldn't it make more sense to instead check for those\nsettings in the global config, and only if they are enabled override\ntheir value or just show a warning?\n\n>>> +feature.manyFiles=false::\n>>> +    This disables the \"many files\" optimizations grouped under this feature\n>>> +    config. The expectation is that all valuable optimizations are also set\n>>> +    explicitly by Scalar config, and any differences are intentional.\n>>\n>> I disagree with this reasoning. This thread was actually brought to my\n>> attention when working on setting manyFiles to true in scalar:\n>> https://github.com/git/git/pull/2125.\n>>\n>> Do you foresee any features that would apply to scalar but not to\n>> manyFiles? I'd even say that some scalar options could be moved to\n>> manyFiles instead, so that people that don't use scalar can benefit too.\n> \n> I suppose that the default reason is that registering a repo with Scalar\n> already enables some config in an \"indirect\" way and having it rely on\n> features.manyFiles would be another layer of indirection.\n> \n> The historical reason is that we initially didn't want changes to the\n> features.* config settings to automatically be assigned to Scalar. I\n> think this is more important on the features.experimental side, as\n> the intention of features.manyFiles is very similar to the intention of\n> cloning/registering with Scalar.\n> \n> For now, I'm going to leave this as-is, because we have enough changes\n> to the config settings and documentation. You can submit a change on top\n> of this one to demonstrate the value of setting features.manyFiles=true\n> and how that impacts the code in its new shape.\n\nOK. I'll do that, thanks!\n\n> Thanks,\n> -Stolee\n> \n\n"},{"id":"532187","messageId":"9b770540-6791-41e2-9548-48b42c7f644b@igalia.com","threadId":"64538","inReplyTo":"f062b0e0773b9d168c031bb1f35538665394a077.1765552528.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v3 5/5] scalar: document config settings","fromName":"Henrique Ferreiro","fromEmail":"hferreiro@igalia.com","sentAt":"2025-12-15T12:33:32Z","receivedAt":"2025-12-15T12:33:36Z","isPatch":true,"sender":{"key":"hferreiro@igalia.com","avatar":"https://avatars.githubusercontent.com/u/984737?v=4"},"body":"On 12/12/25 4:15 PM, Derrick Stolee via GitGitGadget wrote:\n> From: Derrick Stolee <stolee@gmail.com>\n> \n> Add user-facing documentation that justifies the values being set by\n> 'scalar clone', 'scalar register', and 'scalar reconfigure'.\n> \n> Helped-by: Junio C Hamano <gitster@pobox.com>\n> Helped-by: Patrick Steinhardt <ps@pks.im>\n> Signed-off-by: Derrick Stolee <stolee@gmail.com>\n> ---\n>   Documentation/scalar.adoc | 164 ++++++++++++++++++++++++++++++++++++++\n>   scalar.c                  |   4 +\n>   2 files changed, 168 insertions(+)\n> \n> diff --git a/Documentation/scalar.adoc b/Documentation/scalar.adoc\n> index f81b2832f8..ee9fc0ac0c 100644\n> --- a/Documentation/scalar.adoc\n> +++ b/Documentation/scalar.adoc\n> @@ -197,6 +197,170 @@ delete <enlistment>::\n>   \tThis subcommand lets you delete an existing Scalar enlistment from your\n>   \tlocal file system, unregistering the repository.\n>   \n> +RECOMMENDED CONFIG VALUES\n> +-------------------------\n> +\n> +As part of both `scalar clone` and `scalar register`, certain Git config\n> +values are set to optimize for large repositories or cross-platform support.\n> +These options are updated in new Git versions according to the best known\n> +advice for large repositories, and users can get the latest recommendations\n> +by running `scalar reconfigure [--all]`.\n> +\n> +This section lists justifications for the config values that are set in the\n> +latest version.\n> +\n> +am.keepCR=true::\n> +\tThis setting is important for cross-platform development across Windows\n> +\tand non-Windows platforms and keeping carriage return (`\\r`) characters\n> +\tin certain workflows.\n> +\n> +commitGraph.changedPaths=true::\n> +\tThis setting helps the background maintenance steps that compute the\n> +\tserialized commit-graph to also store changed-path Bloom filters. This\n> +\taccelerates file history commands and allows users to automatically\n> +\tbenefit without running a foreground command.\n> +\n> +commitGraph.generationVersion=1::\n> +\tWhile the preferred version is 2 for performance reasons, existing users\n> +\tthat had version 1 by default will need special care in upgrading to\n> +\tversion 2. This is likely to change in the future as the upgrade story\n> +\tsolidifies.\n\nI missed this in a previous email. Given the above reasoning, wouldn't\nit make more sense to check for a previous value of 1, instead of\nforcing 1 also on new enlistments?\n\n> +core.autoCRLF=false::\n> +\tThis removes the transformation of worktree files to add CRLF line\n> +\tendings when only LF line endings exist. This is removed for performance\n> +\treasons. Repositories that use tools that care about CRLF line endings\n> +\tshould commit the necessary files with those line endings instead.\n> +\n> +core.logAllRefUpdates=true::\n> +\tThis enables the reflog on all branches. While this is a performance\n> +\tcost for large repositories, it is frequently an important data source\n> +\tfor users to get out of bad situations or to seek support from experts.\n> +\n> +core.safeCRLF=false::\n> +\tSimilar to `core.autoCRLF=false`, this disables checks around whether\n> +\tthe CRLF conversion is reversible. This is a performance improvement,\n> +\tbut can be dangerous if `core.autoCRLF` is reenabled by the user.\n> +\n> +credential.https://dev.azure.com.useHttpPath=true::\n> +\tThis setting enables the `credential.useHttpPath` feature only for web\n> +\tURLs for Azure DevOps. This is important for users interacting with that\n> +\tservice using multiple organizations and thus multiple credential\n> +\ttokens.\n> +\n> +feature.experimental=false::\n> +\tThis disables the \"experimental\" optimizations grouped under this\n> +\tfeature config. The expectation is that all valuable optimizations are\n> +\talso set explicitly by Scalar config, and any differences are\n> +\tintentional. Notable differences include several bitmap-related config\n> +\toptions which are disabled for client-focused Scalar repos.\n> +\n> +feature.manyFiles=false::\n> +\tThis disables the \"many files\" optimizations grouped under this feature\n> +\tconfig. The expectation is that all valuable optimizations are also set\n> +\texplicitly by Scalar config, and any differences are intentional.\n> +\n> +fetch.showForcedUpdates=false::\n> +\tThis disables the check at the end of `git fetch` that notifies the user\n> +\tif the ref update was a forced update (one where the previous position\n> +\tis not reachable from the latest position). This check can be very\n> +\texpensive in large repositories, so is disabled and replaced with an\n> +\tadvice message. Set `advice.fetchShowForcedUpdates=false` to disable\n> +\tthis advice message.\n> +\n> +fetch.unpackLimit=1::\n> +\tThis setting prevents Git from unpacking packfiles into loose objects\n> +\tas they are downloaded from the server. The default limit of 100 was\n> +\tintended as a way to prevent performance issues from too many packfiles,\n> +\tbut Scalar uses background maintenance to group packfiles and cover them\n> +\twith a multi-pack-index, removing this issue.\n> +\n> +fetch.writeCommitGraph=false::\n> +\tThis config setting was created to help users automatically update their\n> +\tcommit-graph files as they perform fetches. However, this takes time\n> +\tfrom foreground fetches and pulls and Scalar uses background maintenance\n> +\tfor this function instead.\n> +\n> +gc.auto=0::\n> +\tThis disables automatic garbage collection, since Scalar uses background\n> +\tmaintenance to keep the repository data in good shape.\n> +\n> +gui.GCWarning=false::\n> +\tSince Scalar disables garbage collection by setting `gc.auto=0`, the\n> +\t`git-gui` tool may start to warn about this setting. Disable this\n> +\twarning as Scalar's background maintenance configuration makes the\n> +\twarning irrelevant.\n> +\n> +index.skipHash=true::\n> +\tDisable computing the hash of the index contents as it is being written.\n> +\tThis assists with performance, especially for large index files.\n> +\n> +index.threads=true::\n> +\tThis tells Git to automatically detect how many threads it should use\n> +\twhen reading the index due the default value of\t`core.preloadIndex`,\n> +\twhich enables parallel index reads. This explicit setting also enables\n> +\t`index.recordOffsetTable=true` to speed up parallel index reads.\n\nA quick look at preload-index.c doesn't show any references to reading \nindex.threads but I might have missed it. On the other hand, it looks \nlike index.recordEndOfIndexEntries is also affected by index.threads, so \nit might be worth explicitly mentioning it.\n\n> +index.version=4::\n> +\tThis index version adds compression to the path names, reducing the size\n> +\tof the index in a significant way for large repos. This is an important\n> +\tperformance boost.\n> +\n> +log.excludeDecoration=refs/prefetch/*::\n> +\tSince Scalar enables background maintenance with the `incremental`\n> +\tstrategy, this setting avoids polluting `git log` output with refs\n> +\tstored by the background prefetch operations.\n> +\n> +merge.renames=true::\n> +\tWhen computing merges in large repos, it is particularly important to\n> +\tdetect renames to maximize the potential for a result that will validate\n> +\tcorrectly. Users performing merges locally are more likely to be doing\n> +\tso because a server-side merge (via pull request or similar) resulted in\n> +\tconflicts. While this is the default setting, it is set specifically to\n> +\toverride a potential change to `diff.renames` which a user may set for\n> +\tperformance reasons.\n> +\n> +merge.stat=false::\n> +\tThis disables a diff output after computing a merge. This improves\n> +\tperformance of `git merge` for large repos while reducing noisy output.\n> +\n> +pack.useBitmaps=false::\n> +\tThis disables the use of `.bitmap` files attached to packfiles. Bitmap\n> +\tfiles are optimized for server-side use, not client-side use. Scalar\n> +\tdisables this to avoid some performance issues that can occur if a user\n> +\taccidentally creates `.bitmap` files.\n> +\n> +pack.usePathWalk=true::\n> +\tThis enables the `--path-walk` option to `git pack-objects` by default.\n> +\tThis can accelerate the computation and compression of packfiles created\n> +\tby `git push` and other repack operations.\n> +\n> +receive.autoGC=false::\n> +\tSimilar to `gc.auto`, this setting is disabled in preference of\n> +\tbackground maintenance.\n> +\n> +status.aheadBehind=false::\n> +\tThis disables the ahead/behind calculation that would normally happen\n> +\tduring a `git status` command. This information is frequently ignored by\n> +\tusers but can be expensive to calculate in large repos that receive\n> +\tthousands of commits per day. The calculation is replaced with an advice\n> +\tmessage that can be disabled by disabling the `advice.statusAheadBehind`\n> +\tconfig.\n> +\n> +The following settings are different based on which platform is in use:\n> +\n> +core.untrackedCache=(true|false)::\n> +\tThe untracked cache feature is important for performance benefits on\n> +\tlarge repositories, but has demonstrated some bugs on Windows\n> +\tfilesystems. Thus, this is set for other platforms but disabled on\n> +\tWindows.\n> +\n> +http.sslBackend=schannel::\n> +\tOn Windows, the `openssl` backend has some issues with certain types of\n> +\tremote providers and certificate types. Override the default setting to\n> +\tavoid these common problems.\n> +\n> +\n>   SEE ALSO\n>   --------\n>   linkgit:git-clone[1], linkgit:git-maintenance[1].\n> diff --git a/scalar.c b/scalar.c\n> index 3b25fd3f35..21ab1dba89 100644\n> --- a/scalar.c\n> +++ b/scalar.c\n> @@ -132,6 +132,10 @@ static int have_fsmonitor_support(void)\n>   \n>   static int set_recommended_config(int reconfigure)\n>   {\n> +\t/*\n> +\t * Be sure to update Documentation/scalar.adoc if you add, update,\n> +\t * or remove any of these recommended settings.\n> +\t */\n>   \tstruct scalar_config config[] = {\n>   \t\t{ \"am.keepCR\", \"true\" },\n>   \t\t{ \"commitGraph.changedPaths\", \"true\" },\n\n"},{"id":"532189","messageId":"ee4acbe5-5efb-4bd2-a361-dc7f183b4f41@gmail.com","threadId":"64538","inReplyTo":"xmqqecozb6rl.fsf@gitster.g","subject":"Re: [PATCH v3 0/5] Audit and document Scalar config","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2025-12-15T14:33:55Z","receivedAt":"2025-12-15T14:33:58Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"On 12/12/2025 6:49 PM, Junio C Hamano wrote:\n> \"Derrick Stolee via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n> \n>> Updates in V3\n>> =============\n>>\n>>  * Updated method names when setting recommended config.\n>>  * Updated documentation section title now that nothing is \"required\".\n>>  * Made distinction for index.threads=true as explicit setting.\n>>  * Added documentation for log.exludeDecoration.\n> \n> Looking good.\n> \n>>       +index.threads=true::\n>>       +\tThis tells Git to automatically detect how many threads it should use\n>>      -+\twhen reading the index due to the default value of `core.preloadIndex`,\n>>      -+\twhich enables parallel index reads.\n>>      ++\twhen reading the index due the default value of\t`core.preloadIndex`,\n>>      ++\twhich enables parallel index reads. This explicit setting also enables\n>>      ++\t`index.recordOffsetTable=true` to speed up parallel index reads.\n> \n> I understood the previous \"due to\" version (from the middle school\n> English class I took eons ago), but not the updated one.\n> \n> Other than that, there weren't anything iffy in the new version.\n> Will replace.  Thanks.\n\nIndeed, I don't know how I dropped that \"to\".\n\nThanks,\n-Stolee\n\n"},{"id":"532224","messageId":"xmqq5xa76z0o.fsf@gitster.g","threadId":"64538","inReplyTo":"ee4acbe5-5efb-4bd2-a361-dc7f183b4f41@gmail.com","subject":"Re: [PATCH v3 0/5] Audit and document Scalar config","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-12-16T00:39:19Z","receivedAt":"2025-12-16T00:39:21Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Derrick Stolee <stolee@gmail.com> writes:\n\n>>>      -+\twhich enables parallel index reads.\n>>>      ++\twhen reading the index due the default value of\t`core.preloadIndex`,\n>>>      ++\twhich enables parallel index reads. This explicit setting also enables\n>>>      ++\t`index.recordOffsetTable=true` to speed up parallel index reads.\n>> \n>> I understood the previous \"due to\" version (from the middle school\n>> English class I took eons ago), but not the updated one.\n>> \n>> Other than that, there weren't anything iffy in the new version.\n>> Will replace.  Thanks.\n>\n> Indeed, I don't know how I dropped that \"to\".\n\nWill locally amend, then.  Also on the same line, \"value of\n`core.preloadIndex`\" has a tab (instead of a space) after `of`,\nwhich looked funny.\n\nI wonder if there a need for a new whitespace error class that spots\na HT at the 7th column and has non-whitespace characters on both\nsides.  #leftoverbits\n\n"}]}