]> git.ipfire.org Git - thirdparty/git.git/commitdiff
path-walk: add new 'edge_aggressive' option
authorDerrick Stolee <stolee@gmail.com>
Fri, 16 May 2025 18:12:02 +0000 (18:12 +0000)
committerJunio C Hamano <gitster@pobox.com>
Fri, 16 May 2025 19:15:40 +0000 (12:15 -0700)
In preparation for allowing both the --shallow and --path-walk options
in the 'git pack-objects' builtin, create a new 'edge_aggressive' option
in the path-walk API. This option will help walk the boundary more
thoroughly and help avoid sending extra objects during fetches and
pushes.

The only use of the 'edge_hint_aggressive' option in the revision API is
within mark_edges_uninteresting(), which is usually called before
between prepare_revision_walk() and before visiting commits with
get_revision(). In prepare_revision_walk(), the UNINTERESTING commits
are walked until a boundary is found.

Signed-off-by: Derrick Stolee <stolee@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/technical/api-path-walk.adoc
path-walk.c
path-walk.h
t/helper/test-path-walk.c
t/t6601-path-walk.sh

index e522695dd9fafec8bff0c8a4345745962776e87c..34c905eb9c313080fb3dd5f7c2be67adc9cfb90d 100644 (file)
@@ -56,6 +56,14 @@ better off using the revision walk API instead.
        the revision walk so that the walk emits commits marked with the
        `UNINTERESTING` flag.
 
+`edge_aggressive`::
+       For performance reasons, usually only the boundary commits are
+       explored to find UNINTERESTING objects. However, in the case of
+       shallow clones it can be helpful to mark all trees and blobs
+       reachable from UNINTERESTING tip commits as UNINTERESTING. This
+       matches the behavior of `--objects-edge-aggressive` in the
+       revision API.
+
 `pl`::
        This pattern list pointer allows focusing the path-walk search to
        a set of patterns, only emitting paths that match the given
index 341bdd2ba4ef469f81cda380004beabc8478e3e3..2d4ddbadd50f78e958f1a79a78fae475c5ff1296 100644 (file)
@@ -503,7 +503,11 @@ int walk_objects_by_path(struct path_walk_info *info)
        if (prepare_revision_walk(info->revs))
                die(_("failed to setup revision walk"));
 
-       /* Walk trees to mark them as UNINTERESTING. */
+       /*
+        * Walk trees to mark them as UNINTERESTING.
+        * This is particularly important when 'edge_aggressive' is set.
+        */
+       info->revs->edge_hint_aggressive = info->edge_aggressive;
        edge_repo = info->revs->repo;
        edge_tree_list = root_tree_list;
        mark_edges_uninteresting(info->revs, show_edge,
index 473ee9d361c86455d5dd6766206892bf83a6c45c..5ef5a8440e6b5e6eff24b4ec27f8741c4c708080 100644 (file)
@@ -50,6 +50,13 @@ struct path_walk_info {
         */
        int prune_all_uninteresting;
 
+       /**
+        * When 'edge_aggressive' is set, then the revision walk will use
+        * the '--object-edge-aggressive' option to mark even more objects
+        * as uninteresting.
+        */
+       int edge_aggressive;
+
        /**
         * Specify a sparse-checkout definition to match our paths to. Do not
         * walk outside of this sparse definition. If the patterns are in
index 61e845e5ec2560de827d9b2ab9442676dfa36dd8..fe63002c2be27d28ab3b0180978b97f407480cf7 100644 (file)
@@ -82,6 +82,8 @@ int cmd__path_walk(int argc, const char **argv)
                         N_("toggle inclusion of tree objects")),
                OPT_BOOL(0, "prune", &info.prune_all_uninteresting,
                         N_("toggle pruning of uninteresting paths")),
+               OPT_BOOL(0, "edge-aggressive", &info.edge_aggressive,
+                        N_("toggle aggressive edge walk")),
                OPT_BOOL(0, "stdin-pl", &stdin_pl,
                         N_("read a pattern list over stdin")),
                OPT_END(),
index c89b0f1e19d9fbd6cf33e205f69479c3a8c76c5d..785c2f22373d547933827c4bfc25d3fa26197a06 100755 (executable)
@@ -378,6 +378,26 @@ test_expect_success 'topic, not base, boundary with pruning' '
        test_cmp_sorted expect out
 '
 
+test_expect_success 'topic, not base, --edge-aggressive with pruning' '
+       test-tool path-walk --prune --edge-aggressive -- topic --not base >out &&
+
+       cat >expect <<-EOF &&
+       0:commit::$(git rev-parse topic)
+       1:tree::$(git rev-parse topic^{tree})
+       1:tree::$(git rev-parse base^{tree}):UNINTERESTING
+       2:tree:right/:$(git rev-parse topic:right)
+       2:tree:right/:$(git rev-parse base:right):UNINTERESTING
+       3:blob:right/c:$(git rev-parse base:right/c):UNINTERESTING
+       3:blob:right/c:$(git rev-parse topic:right/c)
+       blobs:2
+       commits:1
+       tags:0
+       trees:4
+       EOF
+
+       test_cmp_sorted expect out
+'
+
 test_expect_success 'trees are reported exactly once' '
        test_when_finished "rm -rf unique-trees" &&
        test_create_repo unique-trees &&