Skip to content

Commit ce5b6f9

Browse files
stefanbellergitster
authored andcommitted
revision.h: introduce blob/tree walking in order of the commits
The functionality to list tree objects in the order they were seen while traversing the commits will be used in one of the next commits, where we teach `git describe` to describe not only commits, but blobs, too. The change in list-objects.c is rather minimal as we'll be re-using the infrastructure put in place of the revision walking machinery. For example one could expect that add_pending_tree is not called, but rather commit->tree is directly passed to the tree traversal function. This however requires a lot more code than just emptying the queue containing trees after each commit. Signed-off-by: Stefan Beller <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 91904f5 commit ce5b6f9

File tree

5 files changed

+94
-1
lines changed

5 files changed

+94
-1
lines changed

Documentation/rev-list-options.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,11 @@ ifdef::git-rev-list[]
686686
all object IDs which I need to download if I have the commit
687687
object _bar_ but not _foo_''.
688688

689+
--in-commit-order::
690+
Print tree and blob ids in order of the commits. The tree
691+
and blob ids are printed after they are first referenced
692+
by a commit.
693+
689694
--objects-edge::
690695
Similar to `--objects`, but also print the IDs of excluded
691696
commits prefixed with a ``-'' character. This is used by

list-objects.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,14 @@ void traverse_commit_list(struct rev_info *revs,
239239
if (commit->tree)
240240
add_pending_tree(revs, commit->tree);
241241
show_commit(commit, data);
242+
243+
if (revs->tree_blobs_in_commit_order)
244+
/*
245+
* NEEDSWORK: Adding the tree and then flushing it here
246+
* needs a reallocation for each commit. Can we pass the
247+
* tree directory without allocation churn?
248+
*/
249+
traverse_trees_and_blobs(revs, &csp, show_object, data);
242250
}
243251
traverse_trees_and_blobs(revs, &csp, show_object, data);
244252

revision.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1845,6 +1845,8 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
18451845
revs->dense = 0;
18461846
} else if (!strcmp(arg, "--show-all")) {
18471847
revs->show_all = 1;
1848+
} else if (!strcmp(arg, "--in-commit-order")) {
1849+
revs->tree_blobs_in_commit_order = 1;
18481850
} else if (!strcmp(arg, "--remove-empty")) {
18491851
revs->remove_empty_trees = 1;
18501852
} else if (!strcmp(arg, "--merges")) {

revision.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,8 @@ struct rev_info {
121121
bisect:1,
122122
ancestry_path:1,
123123
first_parent_only:1,
124-
line_level_traverse:1;
124+
line_level_traverse:1,
125+
tree_blobs_in_commit_order:1;
125126

126127
/* Diff flags */
127128
unsigned int diff:1,

t/t6100-rev-list-in-order.sh

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#!/bin/sh
2+
3+
test_description='rev-list testing in-commit-order'
4+
5+
. ./test-lib.sh
6+
7+
test_expect_success 'setup a commit history with trees, blobs' '
8+
for x in one two three four
9+
do
10+
echo $x >$x &&
11+
git add $x &&
12+
git commit -m "add file $x" ||
13+
return 1
14+
done &&
15+
for x in four three
16+
do
17+
git rm $x &&
18+
git commit -m "remove $x" ||
19+
return 1
20+
done
21+
'
22+
23+
test_expect_success 'rev-list --in-commit-order' '
24+
git rev-list --in-commit-order --objects HEAD >actual.raw &&
25+
cut -c 1-40 >actual <actual.raw &&
26+
27+
git cat-file --batch-check="%(objectname)" >expect.raw <<-\EOF &&
28+
HEAD^{commit}
29+
HEAD^{tree}
30+
HEAD^{tree}:one
31+
HEAD^{tree}:two
32+
HEAD~1^{commit}
33+
HEAD~1^{tree}
34+
HEAD~1^{tree}:three
35+
HEAD~2^{commit}
36+
HEAD~2^{tree}
37+
HEAD~2^{tree}:four
38+
HEAD~3^{commit}
39+
# HEAD~3^{tree} skipped, same as HEAD~1^{tree}
40+
HEAD~4^{commit}
41+
# HEAD~4^{tree} skipped, same as HEAD^{tree}
42+
HEAD~5^{commit}
43+
HEAD~5^{tree}
44+
EOF
45+
grep -v "#" >expect <expect.raw &&
46+
47+
test_cmp expect actual
48+
'
49+
50+
test_expect_success 'rev-list lists blobs and trees after commits' '
51+
git rev-list --objects HEAD >actual.raw &&
52+
cut -c 1-40 >actual <actual.raw &&
53+
54+
git cat-file --batch-check="%(objectname)" >expect.raw <<-\EOF &&
55+
HEAD^{commit}
56+
HEAD~1^{commit}
57+
HEAD~2^{commit}
58+
HEAD~3^{commit}
59+
HEAD~4^{commit}
60+
HEAD~5^{commit}
61+
HEAD^{tree}
62+
HEAD^{tree}:one
63+
HEAD^{tree}:two
64+
HEAD~1^{tree}
65+
HEAD~1^{tree}:three
66+
HEAD~2^{tree}
67+
HEAD~2^{tree}:four
68+
# HEAD~3^{tree} skipped, same as HEAD~1^{tree}
69+
# HEAD~4^{tree} skipped, same as HEAD^{tree}
70+
HEAD~5^{tree}
71+
EOF
72+
grep -v "#" >expect <expect.raw &&
73+
74+
test_cmp expect actual
75+
'
76+
77+
test_done

0 commit comments

Comments
 (0)