]> git.ipfire.org Git - thirdparty/git.git/commitdiff
pack-objects: enable --path-walk via config
authorDerrick Stolee <stolee@gmail.com>
Fri, 16 May 2025 18:11:58 +0000 (18:11 +0000)
committerJunio C Hamano <gitster@pobox.com>
Fri, 16 May 2025 19:15:39 +0000 (12:15 -0700)
Users may want to enable the --path-walk option for 'git pack-objects' by
default, especially underneath commands like 'git push' or 'git repack'.

This should be limited to client repositories, since the --path-walk option
disables bitmap walks, so would be bad to include in Git servers when
serving fetches and clones. There is potential that it may be helpful to
consider when repacking the repository, to take advantage of improved deltas
across historical versions of the same files.

Much like how "pack.useSparse" was introduced and included in
"feature.experimental" before being enabled by default, use the repository
settings infrastructure to make the new "pack.usePathWalk" config enabled by
"feature.experimental" and "feature.manyFiles".

In order to test that this config works, add a new trace2 region around
the path walk code that can be checked by a 'git push' command.

Signed-off-by: Derrick Stolee <stolee@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/config/feature.adoc
Documentation/config/pack.adoc
builtin/pack-objects.c
repo-settings.c
repo-settings.h
t/t5516-fetch-push.sh

index f061b64b7484497a43fba7aaac67c7f84b012582..cb49ff2604a6329f6d230a2cd2d79faa1a7b2dc9 100644 (file)
@@ -20,6 +20,10 @@ walking fewer objects.
 +
 * `pack.allowPackReuse=multi` may improve the time it takes to create a pack by
 reusing objects from multiple packs instead of just one.
++
+* `pack.usePathWalk` may speed up packfile creation and make the packfiles be
+significantly smaller in the presence of certain filename collisions with Git's
+default name-hash.
 
 feature.manyFiles::
        Enable config options that optimize for repos with many files in the
index da527377fafcb629108676ed0becc489ed25095a..75402d5579d4b2f88ad21467fce352d5b9800cfe 100644 (file)
@@ -155,6 +155,10 @@ pack.useSparse::
        commits contain certain types of direct renames. Default is
        `true`.
 
+pack.usePathWalk::
+       Enable the `--path-walk` option by default for `git pack-objects`
+       processes. See linkgit:git-pack-objects[1] for full details.
+
 pack.preferBitmapTips::
        When selecting which commits will receive bitmaps, prefer a
        commit at the tip of any reference that is a suffix of any value
index 4fd88476dd299a2c9b11c55d52b6e3655957ecf9..bdd20c074a9b50ac642ad7a3cf7762e3ce4ea561 100644 (file)
@@ -44,6 +44,7 @@
 #include "blob.h"
 #include "tree.h"
 #include "path-walk.h"
+#include "trace2.h"
 
 /*
  * Objects we are going to pack are collected in the `to_pack` structure.
@@ -4283,6 +4284,7 @@ static void get_object_list_path_walk(struct rev_info *revs)
 {
        struct path_walk_info info = PATH_WALK_INFO_INIT;
        unsigned int processed = 0;
+       int result;
 
        info.revs = revs;
        info.path_fn = add_objects_by_path;
@@ -4296,7 +4298,11 @@ static void get_object_list_path_walk(struct rev_info *revs)
         */
        info.prune_all_uninteresting = sparse;
 
-       if (walk_objects_by_path(&info))
+       trace2_region_enter("pack-objects", "path-walk", revs->repo);
+       result = walk_objects_by_path(&info);
+       trace2_region_leave("pack-objects", "path-walk", revs->repo);
+
+       if (result)
                die(_("failed to pack objects via path-walk"));
 }
 
@@ -4652,6 +4658,9 @@ int cmd_pack_objects(int argc,
                if (use_bitmap_index > 0 ||
                    !use_internal_rev_list)
                        path_walk = 0;
+               else if (the_repository->gitdir &&
+                        the_repository->settings.pack_use_path_walk)
+                       path_walk = 1;
                else
                        path_walk = git_env_bool("GIT_TEST_PACK_PATH_WALK", 0);
        }
index 67e9cfd2e63d9c7ccd0dd1cd84b1ba1cf4f2aeb3..9b5595c708e6c5379760b7b897d23a7f3e1d6bc2 100644 (file)
@@ -47,11 +47,13 @@ void prepare_repo_settings(struct repository *r)
                r->settings.fetch_negotiation_algorithm = FETCH_NEGOTIATION_SKIPPING;
                r->settings.pack_use_bitmap_boundary_traversal = 1;
                r->settings.pack_use_multi_pack_reuse = 1;
+               r->settings.pack_use_path_walk = 1;
        }
        if (manyfiles) {
                r->settings.index_version = 4;
                r->settings.index_skip_hash = 1;
                r->settings.core_untracked_cache = UNTRACKED_CACHE_WRITE;
+               r->settings.pack_use_path_walk = 1;
        }
 
        /* Commit graph config or default, does not cascade (simple) */
@@ -66,6 +68,7 @@ void prepare_repo_settings(struct repository *r)
 
        /* Boolean config or default, does not cascade (simple)  */
        repo_cfg_bool(r, "pack.usesparse", &r->settings.pack_use_sparse, 1);
+       repo_cfg_bool(r, "pack.usepathwalk", &r->settings.pack_use_path_walk, 0);
        repo_cfg_bool(r, "core.multipackindex", &r->settings.core_multi_pack_index, 1);
        repo_cfg_bool(r, "index.sparse", &r->settings.sparse_index, 0);
        repo_cfg_bool(r, "index.skiphash", &r->settings.index_skip_hash, r->settings.index_skip_hash);
index ddc11967e015df526ec94c58d8376e3bccc91f62..a31decad221169237ff80da43905ceefe75e9ece 100644 (file)
@@ -56,6 +56,7 @@ struct repo_settings {
        enum untracked_cache_setting core_untracked_cache;
 
        int pack_use_sparse;
+       int pack_use_path_walk;
        enum fetch_negotiation_setting fetch_negotiation_algorithm;
 
        int core_multi_pack_index;
index 85ed049627d2e6cf917ef1c7067c141c83779843..33cd186cd7ca454efe549e03b89f0640afb71833 100755 (executable)
@@ -1907,4 +1907,14 @@ test_expect_success 'push with config push.useBitmaps' '
                --thin --delta-base-offset -q --no-use-bitmap-index <false
 '
 
+test_expect_success 'push with config pack.usePathWalk=true' '
+       mk_test testrepo heads/main &&
+       git checkout main &&
+       test_config pack.usePathWalk true &&
+       GIT_TRACE2_EVENT="$(pwd)/path-walk.txt" \
+       git push --quiet testrepo main:test &&
+
+       test_region pack-objects path-walk path-walk.txt
+'
+
 test_done