Skip to content

Commit f2cfc9c

Browse files
committed
Merge branch 'en/object-list-with-pathspec' into 'nd/struct-pathspec'
This is to improve the process_tree() function defined in list-objects.c * en/object-list-with-pathspec: Add testcases showing how pathspecs are handled with rev-list --objects Make rev-list --objects work together with pathspecs
2 parents 9ddf172 + a97a96f commit f2cfc9c

File tree

2 files changed

+79
-2
lines changed

2 files changed

+79
-2
lines changed

list-objects.c

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,15 @@ static void process_tree(struct rev_info *revs,
6161
struct tree *tree,
6262
show_object_fn show,
6363
struct name_path *path,
64+
struct strbuf *base,
6465
const char *name)
6566
{
6667
struct object *obj = &tree->object;
6768
struct tree_desc desc;
6869
struct name_entry entry;
6970
struct name_path me;
71+
int all_interesting = (revs->diffopt.pathspec.nr == 0);
72+
int baselen = base->len;
7073

7174
if (!revs->tree_objects)
7275
return;
@@ -82,13 +85,32 @@ static void process_tree(struct rev_info *revs,
8285
me.elem = name;
8386
me.elem_len = strlen(name);
8487

88+
if (!all_interesting) {
89+
strbuf_addstr(base, name);
90+
if (base->len)
91+
strbuf_addch(base, '/');
92+
}
93+
8594
init_tree_desc(&desc, tree->buffer, tree->size);
8695

8796
while (tree_entry(&desc, &entry)) {
97+
if (!all_interesting) {
98+
int showit = tree_entry_interesting(&entry,
99+
base, 0,
100+
&revs->diffopt.pathspec);
101+
102+
if (showit < 0)
103+
break;
104+
else if (!showit)
105+
continue;
106+
else if (showit == 2)
107+
all_interesting = 1;
108+
}
109+
88110
if (S_ISDIR(entry.mode))
89111
process_tree(revs,
90112
lookup_tree(entry.sha1),
91-
show, &me, entry.path);
113+
show, &me, base, entry.path);
92114
else if (S_ISGITLINK(entry.mode))
93115
process_gitlink(revs, entry.sha1,
94116
show, &me, entry.path);
@@ -97,6 +119,7 @@ static void process_tree(struct rev_info *revs,
97119
lookup_blob(entry.sha1),
98120
show, &me, entry.path);
99121
}
122+
strbuf_setlen(base, baselen);
100123
free(tree->buffer);
101124
tree->buffer = NULL;
102125
}
@@ -146,7 +169,9 @@ void traverse_commit_list(struct rev_info *revs,
146169
{
147170
int i;
148171
struct commit *commit;
172+
struct strbuf base;
149173

174+
strbuf_init(&base, PATH_MAX);
150175
while ((commit = get_revision(revs)) != NULL) {
151176
add_pending_tree(revs, commit->tree);
152177
show_commit(commit, data);
@@ -164,7 +189,7 @@ void traverse_commit_list(struct rev_info *revs,
164189
}
165190
if (obj->type == OBJ_TREE) {
166191
process_tree(revs, (struct tree *)obj, show_object,
167-
NULL, name);
192+
NULL, &base, name);
168193
continue;
169194
}
170195
if (obj->type == OBJ_BLOB) {
@@ -181,4 +206,5 @@ void traverse_commit_list(struct rev_info *revs,
181206
revs->pending.alloc = 0;
182207
revs->pending.objects = NULL;
183208
}
209+
strbuf_release(&base);
184210
}

t/t6000-rev-list-misc.sh

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#!/bin/sh
2+
3+
test_description='miscellaneous rev-list tests'
4+
5+
. ./test-lib.sh
6+
7+
test_expect_success setup '
8+
echo content1 >wanted_file &&
9+
echo content2 >unwanted_file &&
10+
git add wanted_file unwanted_file &&
11+
git commit -m one
12+
'
13+
14+
test_expect_success 'rev-list --objects heeds pathspecs' '
15+
git rev-list --objects HEAD -- wanted_file >output &&
16+
grep wanted_file output &&
17+
! grep unwanted_file output
18+
'
19+
20+
test_expect_success 'rev-list --objects with pathspecs and deeper paths' '
21+
mkdir foo &&
22+
>foo/file &&
23+
git add foo/file &&
24+
git commit -m two &&
25+
26+
git rev-list --objects HEAD -- foo >output &&
27+
grep foo/file output &&
28+
29+
git rev-list --objects HEAD -- foo/file >output &&
30+
grep foo/file output &&
31+
! grep unwanted_file output
32+
'
33+
34+
test_expect_success 'rev-list --objects with pathspecs and copied files' '
35+
git checkout --orphan junio-testcase &&
36+
git rm -rf . &&
37+
38+
mkdir two &&
39+
echo frotz >one &&
40+
cp one two/three &&
41+
git add one two/three &&
42+
test_tick &&
43+
git commit -m that &&
44+
45+
ONE=$(git rev-parse HEAD:one)
46+
git rev-list --objects HEAD two >output &&
47+
grep "$ONE two/three" output &&
48+
! grep one output
49+
'
50+
51+
test_done

0 commit comments

Comments
 (0)