Skip to content

Commit c9fff00

Browse files
ttaylorrgitster
authored andcommitted
revision: learn '--no-kept-objects'
A future caller will want to be able to perform a reachability traversal which terminates when visiting an object found in a kept pack. The closest existing option is '--honor-pack-keep', but this isn't quite what we want. Instead of halting the traversal midway through, a full traversal is always performed, and the results are only trimmed afterwords. Besides needing to introduce a new flag (since culling results post-facto can be different than halting the traversal as it's happening), there is an additional wrinkle handling the distinction in-core and on-disk kept packs. That is: what kinds of kept pack should stop the traversal? Introduce '--no-kept-objects[=<on-disk|in-core>]' to specify which kinds of kept packs, if any, should stop a traversal. This can be useful for callers that want to perform a reachability analysis, but want to leave certain packs alone (for e.g., when doing a geometric repack that has some "large" packs which are kept in-core that it wants to leave alone). Note that this option is not guaranteed to produce exactly the set of objects that aren't in kept packs, since it's possible the traversal order may end up in a situation where a non-kept ancestor was "cut off" by a kept object (at which point we would stop traversing). But, we don't care about absolute correctness here, since this will eventually be used as a purely additive guide in an upcoming new repack mode. Explicitly avoid documenting this new flag, since it is only used internally. In theory we could avoid even adding it rev-list, but being able to spell this option out on the command-line makes some special cases easier to test without promising to keep it behaving consistently forever. Those tricky cases are exercised in t6114. Signed-off-by: Taylor Blau <[email protected]> Reviewed-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent f62312e commit c9fff00

File tree

3 files changed

+88
-0
lines changed

3 files changed

+88
-0
lines changed

revision.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2336,6 +2336,16 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
23362336
revs->unpacked = 1;
23372337
} else if (starts_with(arg, "--unpacked=")) {
23382338
die(_("--unpacked=<packfile> no longer supported"));
2339+
} else if (!strcmp(arg, "--no-kept-objects")) {
2340+
revs->no_kept_objects = 1;
2341+
revs->keep_pack_cache_flags |= IN_CORE_KEEP_PACKS;
2342+
revs->keep_pack_cache_flags |= ON_DISK_KEEP_PACKS;
2343+
} else if (skip_prefix(arg, "--no-kept-objects=", &optarg)) {
2344+
revs->no_kept_objects = 1;
2345+
if (!strcmp(optarg, "in-core"))
2346+
revs->keep_pack_cache_flags |= IN_CORE_KEEP_PACKS;
2347+
if (!strcmp(optarg, "on-disk"))
2348+
revs->keep_pack_cache_flags |= ON_DISK_KEEP_PACKS;
23392349
} else if (!strcmp(arg, "-r")) {
23402350
revs->diff = 1;
23412351
revs->diffopt.flags.recursive = 1;
@@ -3795,6 +3805,11 @@ enum commit_action get_commit_action(struct rev_info *revs, struct commit *commi
37953805
return commit_ignore;
37963806
if (revs->unpacked && has_object_pack(&commit->object.oid))
37973807
return commit_ignore;
3808+
if (revs->no_kept_objects) {
3809+
if (has_object_kept_pack(&commit->object.oid,
3810+
revs->keep_pack_cache_flags))
3811+
return commit_ignore;
3812+
}
37983813
if (commit->object.flags & UNINTERESTING)
37993814
return commit_ignore;
38003815
if (revs->line_level_traverse && !want_ancestry(revs)) {

revision.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ struct rev_info {
148148
edge_hint_aggressive:1,
149149
limited:1,
150150
unpacked:1,
151+
no_kept_objects:1,
151152
boundary:2,
152153
count:1,
153154
left_right:1,
@@ -317,6 +318,9 @@ struct rev_info {
317318
* This is loaded from the commit-graph being used.
318319
*/
319320
struct bloom_filter_settings *bloom_filter_settings;
321+
322+
/* misc. flags related to '--no-kept-objects' */
323+
unsigned keep_pack_cache_flags;
320324
};
321325

322326
int ref_excluded(struct string_list *, const char *path);

t/t6114-keep-packs.sh

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#!/bin/sh
2+
3+
test_description='rev-list with .keep packs'
4+
. ./test-lib.sh
5+
6+
test_expect_success 'setup' '
7+
test_commit loose &&
8+
test_commit packed &&
9+
test_commit kept &&
10+
11+
KEPT_PACK=$(git pack-objects --revs .git/objects/pack/pack <<-EOF
12+
refs/tags/kept
13+
^refs/tags/packed
14+
EOF
15+
) &&
16+
MISC_PACK=$(git pack-objects --revs .git/objects/pack/pack <<-EOF
17+
refs/tags/packed
18+
^refs/tags/loose
19+
EOF
20+
) &&
21+
22+
touch .git/objects/pack/pack-$KEPT_PACK.keep
23+
'
24+
25+
rev_list_objects () {
26+
git rev-list "$@" >out &&
27+
sort out
28+
}
29+
30+
idx_objects () {
31+
git show-index <$1 >expect-idx &&
32+
cut -d" " -f2 <expect-idx | sort
33+
}
34+
35+
test_expect_success '--no-kept-objects excludes trees and blobs in .keep packs' '
36+
rev_list_objects --objects --all --no-object-names >kept &&
37+
rev_list_objects --objects --all --no-object-names --no-kept-objects >no-kept &&
38+
39+
idx_objects .git/objects/pack/pack-$KEPT_PACK.idx >expect &&
40+
comm -3 kept no-kept >actual &&
41+
42+
test_cmp expect actual
43+
'
44+
45+
test_expect_success '--no-kept-objects excludes kept non-MIDX object' '
46+
test_config core.multiPackIndex true &&
47+
48+
# Create a pack with just the commit object in pack, and do not mark it
49+
# as kept (even though it appears in $KEPT_PACK, which does have a .keep
50+
# file).
51+
MIDX_PACK=$(git pack-objects .git/objects/pack/pack <<-EOF
52+
$(git rev-parse kept)
53+
EOF
54+
) &&
55+
56+
# Write a MIDX containing all packs, but use the version of the commit
57+
# at "kept" in a non-kept pack by touching $MIDX_PACK.
58+
touch .git/objects/pack/pack-$MIDX_PACK.pack &&
59+
git multi-pack-index write &&
60+
61+
rev_list_objects --objects --no-object-names --no-kept-objects HEAD >actual &&
62+
(
63+
idx_objects .git/objects/pack/pack-$MISC_PACK.idx &&
64+
git rev-list --objects --no-object-names refs/tags/loose
65+
) | sort >expect &&
66+
test_cmp expect actual
67+
'
68+
69+
test_done

0 commit comments

Comments
 (0)