* [PATCHv2 0/2] Fix resolvable rename + D/F conflict testcases
@ 2010-09-08 6:40 Elijah Newren
2010-09-08 6:40 ` [PATCHv2 1/2] t3509: Add rename + D/F conflict testcase that recursive strategy fails Elijah Newren
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Elijah Newren @ 2010-09-08 6:40 UTC (permalink / raw)
To: git; +Cc: gitster, oinksocket, Elijah Newren
This fixes an issue reported by Nick (no lastname given) on the
mailing list, as well as a closely related issue in the handling of
rename + directory/file conflicts, namely where a filename on one side
of the rename is a directory name on the other side of the merge.
Change since v1:
* Split unrelated 2/3 patch out into a separate submission
Elijah Newren (2):
t3509: Add rename + D/F conflict testcase that recursive strategy
fails
merge-recursive: D/F conflicts where was_a_dir/file -> was_a_dir
merge-recursive.c | 16 +++++-----
t/t3509-cherry-pick-merge-df.sh | 66 +++++++++++++++++++++++++++++++++++++++
2 files changed, 74 insertions(+), 8 deletions(-)
--
1.7.3.rc0.8.g2ec3f
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCHv2 1/2] t3509: Add rename + D/F conflict testcase that recursive strategy fails
2010-09-08 6:40 [PATCHv2 0/2] Fix resolvable rename + D/F conflict testcases Elijah Newren
@ 2010-09-08 6:40 ` Elijah Newren
2010-09-08 6:40 ` [PATCHv2 2/2] merge-recursive: D/F conflicts where was_a_dir/file -> was_a_dir Elijah Newren
2010-09-08 6:41 ` [PATCHv2 0/2] Fix resolvable rename + D/F conflict testcases Elijah Newren
2 siblings, 0 replies; 5+ messages in thread
From: Elijah Newren @ 2010-09-08 6:40 UTC (permalink / raw)
To: git; +Cc: gitster, oinksocket, Elijah Newren
When one side of a file rename matches a directory name on the other side,
the recursive merge strategy will fail. This is true even if the merge is
trivially resolvable.
Signed-off-by: Elijah Newren <newren@gmail.com>
---
t/t3509-cherry-pick-merge-df.sh | 66 +++++++++++++++++++++++++++++++++++++++
1 files changed, 66 insertions(+), 0 deletions(-)
diff --git a/t/t3509-cherry-pick-merge-df.sh b/t/t3509-cherry-pick-merge-df.sh
index a5ccdbf..eb5826f 100755
--- a/t/t3509-cherry-pick-merge-df.sh
+++ b/t/t3509-cherry-pick-merge-df.sh
@@ -32,4 +32,70 @@ test_expect_success SYMLINKS 'Cherry-pick succeeds with rename across D/F confli
git cherry-pick branch
'
+test_expect_success 'Setup rename with file on one side matching directory name on other' '
+ git checkout --orphan nick-testcase &&
+ git rm -rf . &&
+
+ >empty &&
+ git add empty &&
+ git commit -m "Empty file" &&
+
+ git checkout -b simple &&
+ mv empty file &&
+ mkdir empty &&
+ mv file empty &&
+ git add empty/file &&
+ git commit -m "Empty file under empty dir" &&
+
+ echo content >newfile &&
+ git add newfile &&
+ git commit -m "New file"
+'
+
+test_expect_success 'Cherry-pick succeeds with was_a_dir/file -> was_a_dir (resolve)' '
+ git reset --hard &&
+ git checkout -q nick-testcase^0 &&
+ git cherry-pick --strategy=resolve simple
+'
+
+test_expect_failure 'Cherry-pick succeeds with was_a_dir/file -> was_a_dir (recursive)' '
+ git reset --hard &&
+ git checkout -q nick-testcase^0 &&
+ git cherry-pick --strategy=recursive simple
+'
+
+test_expect_success 'Setup rename with file on one side matching different dirname on other' '
+ git reset --hard &&
+ git checkout --orphan mergeme &&
+ git rm -rf . &&
+
+ mkdir sub &&
+ mkdir othersub &&
+ echo content > sub/file &&
+ echo foo > othersub/whatever &&
+ git add -A &&
+ git commit -m "Common commmit" &&
+
+ git rm -rf othersub &&
+ git mv sub/file othersub &&
+ git commit -m "Commit to merge" &&
+
+ git checkout -b newhead mergeme~1 &&
+ >independent-change &&
+ git add independent-change &&
+ git commit -m "Completely unrelated change"
+'
+
+test_expect_success 'Cherry-pick with rename to different D/F conflict succeeds (resolve)' '
+ git reset --hard &&
+ git checkout -q newhead^0 &&
+ git cherry-pick --strategy=resolve mergeme
+'
+
+test_expect_failure 'Cherry-pick with rename to different D/F conflict succeeds (recursive)' '
+ git reset --hard &&
+ git checkout -q newhead^0 &&
+ git cherry-pick --strategy=recursive mergeme
+'
+
test_done
--
1.7.3.rc0.8.g2ec3f
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCHv2 2/2] merge-recursive: D/F conflicts where was_a_dir/file -> was_a_dir
2010-09-08 6:40 [PATCHv2 0/2] Fix resolvable rename + D/F conflict testcases Elijah Newren
2010-09-08 6:40 ` [PATCHv2 1/2] t3509: Add rename + D/F conflict testcase that recursive strategy fails Elijah Newren
@ 2010-09-08 6:40 ` Elijah Newren
2010-09-10 0:26 ` Junio C Hamano
2010-09-08 6:41 ` [PATCHv2 0/2] Fix resolvable rename + D/F conflict testcases Elijah Newren
2 siblings, 1 reply; 5+ messages in thread
From: Elijah Newren @ 2010-09-08 6:40 UTC (permalink / raw)
To: git; +Cc: gitster, oinksocket, Elijah Newren
In merge-recursive.c, whenever there was a rename where a file name on one
side of the rename matches a directory name on the other side of the merge,
then the very first check that
string_list_has_string(&o->current_directory_set, ren1_dst)
would trigger forcing it into marking it as a rename/directory conflict.
However, if the path is only renamed on one side and a simple three-way
merge between the separate files resolves cleanly, then we don't need to
mark it as a rename/directory conflict. So, we can simply move the check
for rename/directory conflicts after we've verified that there isn't a
rename/rename conflict and that a threeway content merge doesn't work.
This changes the particular error message one gets in the case where the
directory name that a file on one side of the rename matches is not also
part of the rename pair. For example, with commits containing the files:
COMMON -> (HEAD, MERGE )
--------- --------------- -------
sub/file1 -> (sub/file1, newsub)
<NULL> -> (newsub/newfile, <NULL>)
then previously when one tried to merge MERGE into HEAD, one would get
CONFLICT (rename/directory): Rename sub/file1->newsub in HEAD directory newsub added in merge
Renaming sub/file1 to newsub~HEAD instead
Adding newsub/newfile
Automatic merge failed; fix conflicts and then commit the result.
After this patch, the error message will instead become:
Removing newsub
Adding newsub/newfile
CONFLICT (file/directory): There is a directory with name newsub in merge. Adding newsub as newsub~HEAD
Automatic merge failed; fix conflicts and then commit the result.
That makes more sense to me, because git can't know that there's a conflict
until after it's tried resolving paths involving newsub/newfile to see if
they are still in the way at the end (and if newsub/newfile is not in the
way at the end, there should be no conflict at all, which did not hold with
git previously).
Signed-off-by: Elijah Newren <newren@gmail.com>
---
merge-recursive.c | 16 ++++++++--------
t/t3509-cherry-pick-merge-df.sh | 4 ++--
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/merge-recursive.c b/merge-recursive.c
index 20e1779..5ea6d11 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -935,14 +935,7 @@ static int process_renames(struct merge_options *o,
try_merge = 0;
- if (string_list_has_string(&o->current_directory_set, ren1_dst)) {
- clean_merge = 0;
- output(o, 1, "CONFLICT (rename/directory): Rename %s->%s in %s "
- " directory %s added in %s",
- ren1_src, ren1_dst, branch1,
- ren1_dst, branch2);
- conflict_rename_dir(o, ren1, branch1);
- } else if (sha_eq(src_other.sha1, null_sha1)) {
+ if (sha_eq(src_other.sha1, null_sha1)) {
clean_merge = 0;
output(o, 1, "CONFLICT (rename/delete): Rename %s->%s in %s "
"and deleted in %s",
@@ -1034,6 +1027,13 @@ static int process_renames(struct merge_options *o,
if (!ren1->dst_entry->stages[2].mode !=
!ren1->dst_entry->stages[3].mode)
ren1->dst_entry->processed = 0;
+ } else if (string_list_has_string(&o->current_directory_set, ren1_dst)) {
+ clean_merge = 0;
+ output(o, 1, "CONFLICT (rename/directory): Rename %s->%s in %s "
+ " directory %s added in %s",
+ ren1_src, ren1_dst, branch1,
+ ren1_dst, branch2);
+ conflict_rename_dir(o, ren1, branch1);
} else {
if (mfi.merge || !mfi.clean)
output(o, 1, "Renaming %s => %s", ren1_src, ren1_dst);
diff --git a/t/t3509-cherry-pick-merge-df.sh b/t/t3509-cherry-pick-merge-df.sh
index eb5826f..948ca1b 100755
--- a/t/t3509-cherry-pick-merge-df.sh
+++ b/t/t3509-cherry-pick-merge-df.sh
@@ -58,7 +58,7 @@ test_expect_success 'Cherry-pick succeeds with was_a_dir/file -> was_a_dir (reso
git cherry-pick --strategy=resolve simple
'
-test_expect_failure 'Cherry-pick succeeds with was_a_dir/file -> was_a_dir (recursive)' '
+test_expect_success 'Cherry-pick succeeds with was_a_dir/file -> was_a_dir (recursive)' '
git reset --hard &&
git checkout -q nick-testcase^0 &&
git cherry-pick --strategy=recursive simple
@@ -92,7 +92,7 @@ test_expect_success 'Cherry-pick with rename to different D/F conflict succeeds
git cherry-pick --strategy=resolve mergeme
'
-test_expect_failure 'Cherry-pick with rename to different D/F conflict succeeds (recursive)' '
+test_expect_success 'Cherry-pick with rename to different D/F conflict succeeds (recursive)' '
git reset --hard &&
git checkout -q newhead^0 &&
git cherry-pick --strategy=recursive mergeme
--
1.7.3.rc0.8.g2ec3f
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCHv2 0/2] Fix resolvable rename + D/F conflict testcases
2010-09-08 6:40 [PATCHv2 0/2] Fix resolvable rename + D/F conflict testcases Elijah Newren
2010-09-08 6:40 ` [PATCHv2 1/2] t3509: Add rename + D/F conflict testcase that recursive strategy fails Elijah Newren
2010-09-08 6:40 ` [PATCHv2 2/2] merge-recursive: D/F conflicts where was_a_dir/file -> was_a_dir Elijah Newren
@ 2010-09-08 6:41 ` Elijah Newren
2 siblings, 0 replies; 5+ messages in thread
From: Elijah Newren @ 2010-09-08 6:41 UTC (permalink / raw)
To: git; +Cc: gitster, oinksocket, Elijah Newren
On Wed, Sep 8, 2010 at 12:40 AM, Elijah Newren <newren@gmail.com> wrote:
> This fixes an issue reported by Nick (no lastname given) on the
> mailing list, as well as a closely related issue in the handling of
> rename + directory/file conflicts, namely where a filename on one side
> of the rename is a directory name on the other side of the merge.
>
> Change since v1:
> * Split unrelated 2/3 patch out into a separate submission
...oh, and now the series is based on master instead of next. (I
would base it on maint, but since I was adding another testcase to
t3509 and t3509 does not yet exist in maint, I couldn't as easily put
it there.)
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCHv2 2/2] merge-recursive: D/F conflicts where was_a_dir/file -> was_a_dir
2010-09-08 6:40 ` [PATCHv2 2/2] merge-recursive: D/F conflicts where was_a_dir/file -> was_a_dir Elijah Newren
@ 2010-09-10 0:26 ` Junio C Hamano
0 siblings, 0 replies; 5+ messages in thread
From: Junio C Hamano @ 2010-09-10 0:26 UTC (permalink / raw)
To: Elijah Newren; +Cc: git, oinksocket
Elijah Newren <newren@gmail.com> writes:
> ... git can't know that there's a conflict
> until after it's tried resolving paths involving newsub/newfile to see if
> they are still in the way at the end (and if newsub/newfile is not in the
> way at the end, there should be no conflict at all, which did not hold with
> git previously).
I'll queue this patch to 'pu', but anybody who wrote the above to
correctly arriave at the crux of the issue in his analysis would know that
this is another band-aid on top of band-aid. The approach merge-recursive
takes to first grab the set of directories and files fundamentally is
wrong---it should be resolving the paths in-core first and then look at
the result to ignore a directory that has become empty.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2010-09-10 0:27 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-09-08 6:40 [PATCHv2 0/2] Fix resolvable rename + D/F conflict testcases Elijah Newren
2010-09-08 6:40 ` [PATCHv2 1/2] t3509: Add rename + D/F conflict testcase that recursive strategy fails Elijah Newren
2010-09-08 6:40 ` [PATCHv2 2/2] merge-recursive: D/F conflicts where was_a_dir/file -> was_a_dir Elijah Newren
2010-09-10 0:26 ` Junio C Hamano
2010-09-08 6:41 ` [PATCHv2 0/2] Fix resolvable rename + D/F conflict testcases Elijah Newren
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).