зеркало из https://github.com/microsoft/git.git
Merge branch 'en/remerge-diff-fixes'
Fix a few "git log --remerge-diff" bugs. * en/remerge-diff-fixes: diff: fix filtering of merge commits under --remerge-diff diff: fix filtering of additional headers under --remerge-diff diff: have submodule_format logic avoid additional diff headers
This commit is contained in:
Коммит
d878d83ff0
32
diff.c
32
diff.c
|
@ -3399,6 +3399,21 @@ static void add_formatted_headers(struct strbuf *msg,
|
||||||
line_prefix, meta, reset);
|
line_prefix, meta, reset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int diff_filepair_is_phoney(struct diff_filespec *one,
|
||||||
|
struct diff_filespec *two)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* This function specifically looks for pairs injected by
|
||||||
|
* create_filepairs_for_header_only_notifications(). Such
|
||||||
|
* pairs are "phoney" in that they do not represent any
|
||||||
|
* content or even mode difference, but were inserted because
|
||||||
|
* diff_queued_diff previously had no pair associated with
|
||||||
|
* that path but we needed some pair to avoid losing the
|
||||||
|
* "remerge CONFLICT" header associated with the path.
|
||||||
|
*/
|
||||||
|
return !DIFF_FILE_VALID(one) && !DIFF_FILE_VALID(two);
|
||||||
|
}
|
||||||
|
|
||||||
static void builtin_diff(const char *name_a,
|
static void builtin_diff(const char *name_a,
|
||||||
const char *name_b,
|
const char *name_b,
|
||||||
struct diff_filespec *one,
|
struct diff_filespec *one,
|
||||||
|
@ -3430,14 +3445,16 @@ static void builtin_diff(const char *name_a,
|
||||||
|
|
||||||
if (o->submodule_format == DIFF_SUBMODULE_LOG &&
|
if (o->submodule_format == DIFF_SUBMODULE_LOG &&
|
||||||
(!one->mode || S_ISGITLINK(one->mode)) &&
|
(!one->mode || S_ISGITLINK(one->mode)) &&
|
||||||
(!two->mode || S_ISGITLINK(two->mode))) {
|
(!two->mode || S_ISGITLINK(two->mode)) &&
|
||||||
|
(!diff_filepair_is_phoney(one, two))) {
|
||||||
show_submodule_diff_summary(o, one->path ? one->path : two->path,
|
show_submodule_diff_summary(o, one->path ? one->path : two->path,
|
||||||
&one->oid, &two->oid,
|
&one->oid, &two->oid,
|
||||||
two->dirty_submodule);
|
two->dirty_submodule);
|
||||||
return;
|
return;
|
||||||
} else if (o->submodule_format == DIFF_SUBMODULE_INLINE_DIFF &&
|
} else if (o->submodule_format == DIFF_SUBMODULE_INLINE_DIFF &&
|
||||||
(!one->mode || S_ISGITLINK(one->mode)) &&
|
(!one->mode || S_ISGITLINK(one->mode)) &&
|
||||||
(!two->mode || S_ISGITLINK(two->mode))) {
|
(!two->mode || S_ISGITLINK(two->mode)) &&
|
||||||
|
(!diff_filepair_is_phoney(one, two))) {
|
||||||
show_submodule_inline_diff(o, one->path ? one->path : two->path,
|
show_submodule_inline_diff(o, one->path ? one->path : two->path,
|
||||||
&one->oid, &two->oid,
|
&one->oid, &two->oid,
|
||||||
two->dirty_submodule);
|
two->dirty_submodule);
|
||||||
|
@ -3457,12 +3474,12 @@ static void builtin_diff(const char *name_a,
|
||||||
b_two = quote_two(b_prefix, name_b + (*name_b == '/'));
|
b_two = quote_two(b_prefix, name_b + (*name_b == '/'));
|
||||||
lbl[0] = DIFF_FILE_VALID(one) ? a_one : "/dev/null";
|
lbl[0] = DIFF_FILE_VALID(one) ? a_one : "/dev/null";
|
||||||
lbl[1] = DIFF_FILE_VALID(two) ? b_two : "/dev/null";
|
lbl[1] = DIFF_FILE_VALID(two) ? b_two : "/dev/null";
|
||||||
if (!DIFF_FILE_VALID(one) && !DIFF_FILE_VALID(two)) {
|
if (diff_filepair_is_phoney(one, two)) {
|
||||||
/*
|
/*
|
||||||
* We should only reach this point for pairs from
|
* We should only reach this point for pairs generated from
|
||||||
* create_filepairs_for_header_only_notifications(). For
|
* create_filepairs_for_header_only_notifications(). For
|
||||||
* these, we should avoid the "/dev/null" special casing
|
* these, we want to avoid the "/dev/null" special casing
|
||||||
* above, meaning we avoid showing such pairs as either
|
* above, because we do not want such pairs shown as either
|
||||||
* "new file" or "deleted file" below.
|
* "new file" or "deleted file" below.
|
||||||
*/
|
*/
|
||||||
lbl[0] = a_one;
|
lbl[0] = a_one;
|
||||||
|
@ -5853,6 +5870,7 @@ static void diff_flush_patch(struct diff_filepair *p, struct diff_options *o)
|
||||||
{
|
{
|
||||||
int include_conflict_headers =
|
int include_conflict_headers =
|
||||||
(additional_headers(o, p->one->path) &&
|
(additional_headers(o, p->one->path) &&
|
||||||
|
!o->pickaxe_opts &&
|
||||||
(!o->filter || filter_bit_tst(DIFF_STATUS_UNMERGED, o)));
|
(!o->filter || filter_bit_tst(DIFF_STATUS_UNMERGED, o)));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -5908,6 +5926,8 @@ int diff_queue_is_empty(struct diff_options *o)
|
||||||
int i;
|
int i;
|
||||||
int include_conflict_headers =
|
int include_conflict_headers =
|
||||||
(o->additional_path_headers &&
|
(o->additional_path_headers &&
|
||||||
|
strmap_get_size(o->additional_path_headers) &&
|
||||||
|
!o->pickaxe_opts &&
|
||||||
(!o->filter || filter_bit_tst(DIFF_STATUS_UNMERGED, o)));
|
(!o->filter || filter_bit_tst(DIFF_STATUS_UNMERGED, o)));
|
||||||
|
|
||||||
if (include_conflict_headers)
|
if (include_conflict_headers)
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
test_description='remerge-diff handling'
|
test_description='remerge-diff handling'
|
||||||
|
|
||||||
TEST_PASSES_SANITIZE_LEAK=true
|
|
||||||
. ./test-lib.sh
|
. ./test-lib.sh
|
||||||
|
|
||||||
# This test is ort-specific
|
# This test is ort-specific
|
||||||
|
@ -57,6 +56,11 @@ test_expect_success 'remerge-diff on a clean merge' '
|
||||||
test_cmp expect actual
|
test_cmp expect actual
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'remerge-diff on a clean merge with a filter' '
|
||||||
|
git show --oneline --remerge-diff --diff-filter=U bc_resolution >actual &&
|
||||||
|
test_must_be_empty actual
|
||||||
|
'
|
||||||
|
|
||||||
test_expect_success 'remerge-diff with both a resolved conflict and an unrelated change' '
|
test_expect_success 'remerge-diff with both a resolved conflict and an unrelated change' '
|
||||||
git log -1 --oneline ab_resolution >tmp &&
|
git log -1 --oneline ab_resolution >tmp &&
|
||||||
cat <<-EOF >>tmp &&
|
cat <<-EOF >>tmp &&
|
||||||
|
@ -90,6 +94,22 @@ test_expect_success 'remerge-diff with both a resolved conflict and an unrelated
|
||||||
test_cmp expect actual
|
test_cmp expect actual
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'pickaxe still includes additional headers for relevant changes' '
|
||||||
|
# reuses "expect" from the previous testcase
|
||||||
|
|
||||||
|
git log --oneline --remerge-diff -Sacht ab_resolution >tmp &&
|
||||||
|
sed -e "s/[0-9a-f]\{7,\}/HASH/g" tmp >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'can filter out additional headers with pickaxe' '
|
||||||
|
git show --remerge-diff --submodule=log --find-object=HEAD ab_resolution >actual &&
|
||||||
|
test_must_be_empty actual &&
|
||||||
|
|
||||||
|
git show --remerge-diff -S"not present" --all >actual &&
|
||||||
|
test_must_be_empty actual
|
||||||
|
'
|
||||||
|
|
||||||
test_expect_success 'setup non-content conflicts' '
|
test_expect_success 'setup non-content conflicts' '
|
||||||
git switch --orphan base &&
|
git switch --orphan base &&
|
||||||
|
|
||||||
|
@ -185,6 +205,14 @@ test_expect_success 'remerge-diff w/ diff-filter=U: all conflict headers, no dif
|
||||||
test_cmp expect actual
|
test_cmp expect actual
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'submodule formatting ignores additional headers' '
|
||||||
|
# Reuses "expect" from last testcase
|
||||||
|
|
||||||
|
git show --oneline --remerge-diff --diff-filter=U --submodule=log >tmp &&
|
||||||
|
sed -e "s/[0-9a-f]\{7,\}/HASH/g" tmp >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
test_expect_success 'remerge-diff w/ diff-filter=R: relevant file + conflict header' '
|
test_expect_success 'remerge-diff w/ diff-filter=R: relevant file + conflict header' '
|
||||||
git log -1 --oneline resolution >tmp &&
|
git log -1 --oneline resolution >tmp &&
|
||||||
cat <<-EOF >>tmp &&
|
cat <<-EOF >>tmp &&
|
||||||
|
|
Загрузка…
Ссылка в новой задаче