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 pathspecsmaint
commit
f2cfc9c81e
|
@ -61,12 +61,15 @@ static void process_tree(struct rev_info *revs,
|
||||||
struct tree *tree,
|
struct tree *tree,
|
||||||
show_object_fn show,
|
show_object_fn show,
|
||||||
struct name_path *path,
|
struct name_path *path,
|
||||||
|
struct strbuf *base,
|
||||||
const char *name)
|
const char *name)
|
||||||
{
|
{
|
||||||
struct object *obj = &tree->object;
|
struct object *obj = &tree->object;
|
||||||
struct tree_desc desc;
|
struct tree_desc desc;
|
||||||
struct name_entry entry;
|
struct name_entry entry;
|
||||||
struct name_path me;
|
struct name_path me;
|
||||||
|
int all_interesting = (revs->diffopt.pathspec.nr == 0);
|
||||||
|
int baselen = base->len;
|
||||||
|
|
||||||
if (!revs->tree_objects)
|
if (!revs->tree_objects)
|
||||||
return;
|
return;
|
||||||
|
@ -82,13 +85,32 @@ static void process_tree(struct rev_info *revs,
|
||||||
me.elem = name;
|
me.elem = name;
|
||||||
me.elem_len = strlen(name);
|
me.elem_len = strlen(name);
|
||||||
|
|
||||||
|
if (!all_interesting) {
|
||||||
|
strbuf_addstr(base, name);
|
||||||
|
if (base->len)
|
||||||
|
strbuf_addch(base, '/');
|
||||||
|
}
|
||||||
|
|
||||||
init_tree_desc(&desc, tree->buffer, tree->size);
|
init_tree_desc(&desc, tree->buffer, tree->size);
|
||||||
|
|
||||||
while (tree_entry(&desc, &entry)) {
|
while (tree_entry(&desc, &entry)) {
|
||||||
|
if (!all_interesting) {
|
||||||
|
int showit = tree_entry_interesting(&entry,
|
||||||
|
base, 0,
|
||||||
|
&revs->diffopt.pathspec);
|
||||||
|
|
||||||
|
if (showit < 0)
|
||||||
|
break;
|
||||||
|
else if (!showit)
|
||||||
|
continue;
|
||||||
|
else if (showit == 2)
|
||||||
|
all_interesting = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (S_ISDIR(entry.mode))
|
if (S_ISDIR(entry.mode))
|
||||||
process_tree(revs,
|
process_tree(revs,
|
||||||
lookup_tree(entry.sha1),
|
lookup_tree(entry.sha1),
|
||||||
show, &me, entry.path);
|
show, &me, base, entry.path);
|
||||||
else if (S_ISGITLINK(entry.mode))
|
else if (S_ISGITLINK(entry.mode))
|
||||||
process_gitlink(revs, entry.sha1,
|
process_gitlink(revs, entry.sha1,
|
||||||
show, &me, entry.path);
|
show, &me, entry.path);
|
||||||
|
@ -97,6 +119,7 @@ static void process_tree(struct rev_info *revs,
|
||||||
lookup_blob(entry.sha1),
|
lookup_blob(entry.sha1),
|
||||||
show, &me, entry.path);
|
show, &me, entry.path);
|
||||||
}
|
}
|
||||||
|
strbuf_setlen(base, baselen);
|
||||||
free(tree->buffer);
|
free(tree->buffer);
|
||||||
tree->buffer = NULL;
|
tree->buffer = NULL;
|
||||||
}
|
}
|
||||||
|
@ -146,7 +169,9 @@ void traverse_commit_list(struct rev_info *revs,
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct commit *commit;
|
struct commit *commit;
|
||||||
|
struct strbuf base;
|
||||||
|
|
||||||
|
strbuf_init(&base, PATH_MAX);
|
||||||
while ((commit = get_revision(revs)) != NULL) {
|
while ((commit = get_revision(revs)) != NULL) {
|
||||||
add_pending_tree(revs, commit->tree);
|
add_pending_tree(revs, commit->tree);
|
||||||
show_commit(commit, data);
|
show_commit(commit, data);
|
||||||
|
@ -164,7 +189,7 @@ void traverse_commit_list(struct rev_info *revs,
|
||||||
}
|
}
|
||||||
if (obj->type == OBJ_TREE) {
|
if (obj->type == OBJ_TREE) {
|
||||||
process_tree(revs, (struct tree *)obj, show_object,
|
process_tree(revs, (struct tree *)obj, show_object,
|
||||||
NULL, name);
|
NULL, &base, name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (obj->type == OBJ_BLOB) {
|
if (obj->type == OBJ_BLOB) {
|
||||||
|
@ -181,4 +206,5 @@ void traverse_commit_list(struct rev_info *revs,
|
||||||
revs->pending.alloc = 0;
|
revs->pending.alloc = 0;
|
||||||
revs->pending.objects = NULL;
|
revs->pending.objects = NULL;
|
||||||
}
|
}
|
||||||
|
strbuf_release(&base);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
test_description='miscellaneous rev-list tests'
|
||||||
|
|
||||||
|
. ./test-lib.sh
|
||||||
|
|
||||||
|
test_expect_success setup '
|
||||||
|
echo content1 >wanted_file &&
|
||||||
|
echo content2 >unwanted_file &&
|
||||||
|
git add wanted_file unwanted_file &&
|
||||||
|
git commit -m one
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'rev-list --objects heeds pathspecs' '
|
||||||
|
git rev-list --objects HEAD -- wanted_file >output &&
|
||||||
|
grep wanted_file output &&
|
||||||
|
! grep unwanted_file output
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'rev-list --objects with pathspecs and deeper paths' '
|
||||||
|
mkdir foo &&
|
||||||
|
>foo/file &&
|
||||||
|
git add foo/file &&
|
||||||
|
git commit -m two &&
|
||||||
|
|
||||||
|
git rev-list --objects HEAD -- foo >output &&
|
||||||
|
grep foo/file output &&
|
||||||
|
|
||||||
|
git rev-list --objects HEAD -- foo/file >output &&
|
||||||
|
grep foo/file output &&
|
||||||
|
! grep unwanted_file output
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'rev-list --objects with pathspecs and copied files' '
|
||||||
|
git checkout --orphan junio-testcase &&
|
||||||
|
git rm -rf . &&
|
||||||
|
|
||||||
|
mkdir two &&
|
||||||
|
echo frotz >one &&
|
||||||
|
cp one two/three &&
|
||||||
|
git add one two/three &&
|
||||||
|
test_tick &&
|
||||||
|
git commit -m that &&
|
||||||
|
|
||||||
|
ONE=$(git rev-parse HEAD:one)
|
||||||
|
git rev-list --objects HEAD two >output &&
|
||||||
|
grep "$ONE two/three" output &&
|
||||||
|
! grep one output
|
||||||
|
'
|
||||||
|
|
||||||
|
test_done
|
Loading…
Reference in New Issue