Browse Source

Merge branch 'jk/diff-cc-oidfind-fix'

"log -c --find-object=X" did not work well to find a merge that
involves a change to an object X from only one parent.

* jk/diff-cc-oidfind-fix:
  combine-diff: handle --find-object in multitree code path
maint
Junio C Hamano 4 years ago
parent
commit
7da656f1e0
  1. 43
      combine-diff.c
  2. 55
      t/t4064-diff-oidfind.sh

43
combine-diff.c

@ -1450,6 +1450,42 @@ static struct combine_diff_path *find_paths_multitree( @@ -1450,6 +1450,42 @@ static struct combine_diff_path *find_paths_multitree(
return paths_head.next;
}

static int match_objfind(struct combine_diff_path *path,
int num_parent,
const struct oidset *set)
{
int i;
if (oidset_contains(set, &path->oid))
return 1;
for (i = 0; i < num_parent; i++) {
if (oidset_contains(set, &path->parent[i].oid))
return 1;
}
return 0;
}

static struct combine_diff_path *combined_objfind(struct diff_options *opt,
struct combine_diff_path *paths,
int num_parent)
{
struct combine_diff_path *ret = NULL, **tail = &ret;
struct combine_diff_path *p = paths;

while (p) {
struct combine_diff_path *next = p->next;

if (match_objfind(p, num_parent, opt->objfind)) {
p->next = NULL;
*tail = p;
tail = &p->next;
} else {
free(p);
}
p = next;
}

return ret;
}

void diff_tree_combined(const struct object_id *oid,
const struct oid_array *parents,
@ -1504,10 +1540,10 @@ void diff_tree_combined(const struct object_id *oid, @@ -1504,10 +1540,10 @@ void diff_tree_combined(const struct object_id *oid,
opt->flags.follow_renames ||
opt->break_opt != -1 ||
opt->detect_rename ||
(opt->pickaxe_opts & DIFF_PICKAXE_KINDS_MASK) ||
(opt->pickaxe_opts &
(DIFF_PICKAXE_KINDS_MASK & ~DIFF_PICKAXE_KIND_OBJFIND)) ||
opt->filter;


if (need_generic_pathscan) {
/*
* NOTE generic case also handles --stat, as it computes
@ -1521,6 +1557,9 @@ void diff_tree_combined(const struct object_id *oid, @@ -1521,6 +1557,9 @@ void diff_tree_combined(const struct object_id *oid,
int stat_opt;
paths = find_paths_multitree(oid, parents, &diffopts);

if (opt->pickaxe_opts & DIFF_PICKAXE_KIND_OBJFIND)
paths = combined_objfind(opt, paths, num_parent);

/*
* show stat against the first parent even
* when doing combined diff.

55
t/t4064-diff-oidfind.sh

@ -65,4 +65,59 @@ test_expect_success 'find a submodule' ' @@ -65,4 +65,59 @@ test_expect_success 'find a submodule' '
test_cmp expect actual
'

test_expect_success 'set up merge tests' '
test_commit base &&

git checkout -b boring base^ &&
echo boring >file &&
git add file &&
git commit -m boring &&

git checkout -b interesting base^ &&
echo interesting >file &&
git add file &&
git commit -m interesting &&

blob=$(git rev-parse interesting:file)
'

test_expect_success 'detect merge which introduces blob' '
git checkout -B merge base &&
git merge --no-commit boring &&
echo interesting >file &&
git commit -am "introduce blob" &&
git diff-tree --format=%s --find-object=$blob -c --name-status HEAD >actual &&
cat >expect <<-\EOF &&
introduce blob

AM file
EOF
test_cmp expect actual
'

test_expect_success 'detect merge which removes blob' '
git checkout -B merge interesting &&
git merge --no-commit base &&
echo boring >file &&
git commit -am "remove blob" &&
git diff-tree --format=%s --find-object=$blob -c --name-status HEAD >actual &&
cat >expect <<-\EOF &&
remove blob

MA file
EOF
test_cmp expect actual
'

test_expect_success 'do not detect merge that does not touch blob' '
git checkout -B merge interesting &&
git merge -m "untouched blob" base &&
git diff-tree --format=%s --find-object=$blob -c --name-status HEAD >actual &&
cat >expect <<-\EOF &&
untouched blob

EOF
test_cmp expect actual
'

test_done

Loading…
Cancel
Save