Skip to content

Commit 7da656f

Browse files
committed
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
2 parents 8e3ec76 + 957876f commit 7da656f

File tree

2 files changed

+96
-2
lines changed

2 files changed

+96
-2
lines changed

combine-diff.c

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1450,6 +1450,42 @@ static struct combine_diff_path *find_paths_multitree(
14501450
return paths_head.next;
14511451
}
14521452

1453+
static int match_objfind(struct combine_diff_path *path,
1454+
int num_parent,
1455+
const struct oidset *set)
1456+
{
1457+
int i;
1458+
if (oidset_contains(set, &path->oid))
1459+
return 1;
1460+
for (i = 0; i < num_parent; i++) {
1461+
if (oidset_contains(set, &path->parent[i].oid))
1462+
return 1;
1463+
}
1464+
return 0;
1465+
}
1466+
1467+
static struct combine_diff_path *combined_objfind(struct diff_options *opt,
1468+
struct combine_diff_path *paths,
1469+
int num_parent)
1470+
{
1471+
struct combine_diff_path *ret = NULL, **tail = &ret;
1472+
struct combine_diff_path *p = paths;
1473+
1474+
while (p) {
1475+
struct combine_diff_path *next = p->next;
1476+
1477+
if (match_objfind(p, num_parent, opt->objfind)) {
1478+
p->next = NULL;
1479+
*tail = p;
1480+
tail = &p->next;
1481+
} else {
1482+
free(p);
1483+
}
1484+
p = next;
1485+
}
1486+
1487+
return ret;
1488+
}
14531489

14541490
void diff_tree_combined(const struct object_id *oid,
14551491
const struct oid_array *parents,
@@ -1504,10 +1540,10 @@ void diff_tree_combined(const struct object_id *oid,
15041540
opt->flags.follow_renames ||
15051541
opt->break_opt != -1 ||
15061542
opt->detect_rename ||
1507-
(opt->pickaxe_opts & DIFF_PICKAXE_KINDS_MASK) ||
1543+
(opt->pickaxe_opts &
1544+
(DIFF_PICKAXE_KINDS_MASK & ~DIFF_PICKAXE_KIND_OBJFIND)) ||
15081545
opt->filter;
15091546

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

1560+
if (opt->pickaxe_opts & DIFF_PICKAXE_KIND_OBJFIND)
1561+
paths = combined_objfind(opt, paths, num_parent);
1562+
15241563
/*
15251564
* show stat against the first parent even
15261565
* when doing combined diff.

t/t4064-diff-oidfind.sh

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,59 @@ test_expect_success 'find a submodule' '
6565
test_cmp expect actual
6666
'
6767

68+
test_expect_success 'set up merge tests' '
69+
test_commit base &&
70+
71+
git checkout -b boring base^ &&
72+
echo boring >file &&
73+
git add file &&
74+
git commit -m boring &&
75+
76+
git checkout -b interesting base^ &&
77+
echo interesting >file &&
78+
git add file &&
79+
git commit -m interesting &&
80+
81+
blob=$(git rev-parse interesting:file)
82+
'
83+
84+
test_expect_success 'detect merge which introduces blob' '
85+
git checkout -B merge base &&
86+
git merge --no-commit boring &&
87+
echo interesting >file &&
88+
git commit -am "introduce blob" &&
89+
git diff-tree --format=%s --find-object=$blob -c --name-status HEAD >actual &&
90+
cat >expect <<-\EOF &&
91+
introduce blob
92+
93+
AM file
94+
EOF
95+
test_cmp expect actual
96+
'
97+
98+
test_expect_success 'detect merge which removes blob' '
99+
git checkout -B merge interesting &&
100+
git merge --no-commit base &&
101+
echo boring >file &&
102+
git commit -am "remove blob" &&
103+
git diff-tree --format=%s --find-object=$blob -c --name-status HEAD >actual &&
104+
cat >expect <<-\EOF &&
105+
remove blob
106+
107+
MA file
108+
EOF
109+
test_cmp expect actual
110+
'
111+
112+
test_expect_success 'do not detect merge that does not touch blob' '
113+
git checkout -B merge interesting &&
114+
git merge -m "untouched blob" base &&
115+
git diff-tree --format=%s --find-object=$blob -c --name-status HEAD >actual &&
116+
cat >expect <<-\EOF &&
117+
untouched blob
118+
119+
EOF
120+
test_cmp expect actual
121+
'
122+
68123
test_done

0 commit comments

Comments
 (0)