* unexpected git-cherry-pick conflict [not found] ` <6b8a91420706070252y3fd581a3w427d91e5b982d29d@mail.gmail.com> @ 2007-06-13 9:16 ` Gerrit Pape 2007-06-13 12:58 ` Johannes Schindelin 0 siblings, 1 reply; 23+ messages in thread From: Gerrit Pape @ 2007-06-13 9:16 UTC (permalink / raw) To: git; +Cc: 417885 On Thu, Jun 07, 2007 at 11:52:19AM +0200, Remi Vanicat wrote: > how to reproduce : > create a repos with a link in it, then in a branch, remove the link, > and add a directory in place of the link (same name). > > Then try to cherry pick a commit from a branch where there is the > directory into a branch where there is the link : it failed even if > the modification ave nothing to do with said link/directory. Hi, please see http://bugs.debian.org/417885 This is how I can reproduce the conflict, and I too didn't expect that. The link/dir that conflicts is not changed in the commit that's cherry-pick'ed: $ mkdir repo && cd repo $ git init Initialized empty Git repository in .git/ $ echo foo >file $ ln -s dangling link $ git add . $ git commit -mfoo Created initial commit c6a9189: foo 2 files changed, 2 insertions(+), 0 deletions(-) create mode 100644 file create mode 120000 link $ git checkout -b branch Switched to a new branch "branch" $ git rm link rm 'link' $ git commit -mremovelink Created commit 2c60f15: removelink 1 files changed, 0 insertions(+), 1 deletions(-) delete mode 120000 link $ mkdir link $ echo bar >link/file $ git add link $ git commit -m adddir Created commit d3b30b5: adddir 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 link/file $ echo bar >>file $ git commit -mfile file Created commit 8ddc4d5: file 1 files changed, 1 insertions(+), 0 deletions(-) $ git checkout master Switched to branch "master" $ git cherry-pick 8ddc4d5 CONFLICT (file/directory): There is a directory with name link in 8ddc4d5... file. Added link as link~HEAD Automatic cherry-pick failed. After resolving the conflicts, mark the corrected paths with 'git-add <paths>' and commit the result. When commiting, use the option '-c 8ddc4d5' to retain authorship and message. $ Thanks, Gerrit. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: unexpected git-cherry-pick conflict 2007-06-13 9:16 ` unexpected git-cherry-pick conflict Gerrit Pape @ 2007-06-13 12:58 ` Johannes Schindelin 2007-06-13 13:43 ` Gerrit Pape 0 siblings, 1 reply; 23+ messages in thread From: Johannes Schindelin @ 2007-06-13 12:58 UTC (permalink / raw) To: Gerrit Pape; +Cc: git, 417885 Hi, On Wed, 13 Jun 2007, Gerrit Pape wrote: > $ mkdir repo && cd repo > $ git init > Initialized empty Git repository in .git/ > $ echo foo >file > $ ln -s dangling link > $ git add . > $ git commit -mfoo > Created initial commit c6a9189: foo > 2 files changed, 2 insertions(+), 0 deletions(-) > create mode 100644 file > create mode 120000 link So, basically your master has a file and a symbolic link. > $ git checkout -b branch > Switched to a new branch "branch" > $ git rm link > rm 'link' > $ git commit -mremovelink > Created commit 2c60f15: removelink > 1 files changed, 0 insertions(+), 1 deletions(-) > delete mode 120000 link Here, you remove the link from the branch. > $ mkdir link > $ echo bar >link/file > $ git add link > $ git commit -m adddir > Created commit d3b30b5: adddir > 1 files changed, 1 insertions(+), 0 deletions(-) > create mode 100644 link/file Here you added a directory of the same name as the symbolic link has in master. > $ git checkout master > Switched to branch "master" > $ git cherry-pick 8ddc4d5 > CONFLICT (file/directory): There is a directory with name link in > 8ddc4d5... file. Added link as link~HEAD Here you _still_ have the file in master. So that conflict is really expected, since a cherry-pick will only do a three-way merge. I guess you want to use git-rebase instead. Ciao, Dscho ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: unexpected git-cherry-pick conflict 2007-06-13 12:58 ` Johannes Schindelin @ 2007-06-13 13:43 ` Gerrit Pape 2007-06-13 14:43 ` Johannes Schindelin 0 siblings, 1 reply; 23+ messages in thread From: Gerrit Pape @ 2007-06-13 13:43 UTC (permalink / raw) To: Johannes Schindelin; +Cc: git, 417885 On Wed, Jun 13, 2007 at 01:58:51PM +0100, Johannes Schindelin wrote: > On Wed, 13 Jun 2007, Gerrit Pape wrote: > > $ git checkout master > > Switched to branch "master" > > $ git cherry-pick 8ddc4d5 > > CONFLICT (file/directory): There is a directory with name link in > > 8ddc4d5... file. Added link as link~HEAD > > Here you _still_ have the file in master. So that conflict is really > expected, since a cherry-pick will only do a three-way merge. git-cherry-pick(1) states Given one existing commit, apply the change the patch introduces, and record a new commit that records it. This requires your working tree to be clean (no modifications from the HEAD commit). The patch introduced by the commit that's cherry-pick'ed has nothing to do with the link or new directory, it just changes 'file' $ git show 8ddc4d5 commit 8ddc4d59444a362261e10a3b22324818f5dd2fa7 Author: Gerrit Pape <pape@smarden.org> Date: Wed Jun 13 09:10:30 2007 +0000 file diff --git a/file b/file index 257cc56..3bd1f0e 100644 --- a/file +++ b/file @@ -1 +1,2 @@ foo +bar $ The patch applies to master just fine. Where's my thinking wrong? Thanks, Gerrit. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: unexpected git-cherry-pick conflict 2007-06-13 13:43 ` Gerrit Pape @ 2007-06-13 14:43 ` Johannes Schindelin 2007-06-25 7:18 ` Gerrit Pape 0 siblings, 1 reply; 23+ messages in thread From: Johannes Schindelin @ 2007-06-13 14:43 UTC (permalink / raw) To: Gerrit Pape; +Cc: git, 417885 Hi, On Wed, 13 Jun 2007, Gerrit Pape wrote: > On Wed, Jun 13, 2007 at 01:58:51PM +0100, Johannes Schindelin wrote: > > On Wed, 13 Jun 2007, Gerrit Pape wrote: > > > $ git checkout master > > > Switched to branch "master" > > > $ git cherry-pick 8ddc4d5 > > > CONFLICT (file/directory): There is a directory with name link in > > > 8ddc4d5... file. Added link as link~HEAD > > > > Here you _still_ have the file in master. So that conflict is really > > expected, since a cherry-pick will only do a three-way merge. > > git-cherry-pick(1) states > Given one existing commit, apply the change the patch introduces, and > record a new commit that records it. This requires your working tree to > be clean (no modifications from the HEAD commit). > > The patch introduced by the commit that's cherry-pick'ed has nothing to > do with the link or new directory, it just changes 'file' > > $ git show 8ddc4d5 > commit 8ddc4d59444a362261e10a3b22324818f5dd2fa7 > Author: Gerrit Pape <pape@smarden.org> > Date: Wed Jun 13 09:10:30 2007 +0000 > > file > > diff --git a/file b/file > index 257cc56..3bd1f0e 100644 > --- a/file > +++ b/file > @@ -1 +1,2 @@ > foo > +bar > $ > > The patch applies to master just fine. Where's my thinking wrong? Hmm. Indeed. Thanks for clearing that up. Will work on it later. Ciao, Dscho ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: unexpected git-cherry-pick conflict 2007-06-13 14:43 ` Johannes Schindelin @ 2007-06-25 7:18 ` Gerrit Pape 2007-06-25 7:55 ` Johannes Schindelin ` (2 more replies) 0 siblings, 3 replies; 23+ messages in thread From: Gerrit Pape @ 2007-06-25 7:18 UTC (permalink / raw) To: git On Wed, Jun 13, 2007 at 03:43:48PM +0100, Johannes Schindelin wrote: > On Wed, 13 Jun 2007, Gerrit Pape wrote: > > On Wed, Jun 13, 2007 at 01:58:51PM +0100, Johannes Schindelin wrote: > > > On Wed, 13 Jun 2007, Gerrit Pape wrote: > > > > $ git checkout master > > > > Switched to branch "master" > > > > $ git cherry-pick 8ddc4d5 > > > > CONFLICT (file/directory): There is a directory with name link in > > > > 8ddc4d5... file. Added link as link~HEAD > > > > > > Here you _still_ have the file in master. So that conflict is really > > > expected, since a cherry-pick will only do a three-way merge. > > > > git-cherry-pick(1) states > > Given one existing commit, apply the change the patch introduces, and > > record a new commit that records it. This requires your working tree to > > be clean (no modifications from the HEAD commit). > > > > The patch introduced by the commit that's cherry-pick'ed has nothing to > > do with the link or new directory, it just changes 'file' > > > > $ git show 8ddc4d5 > > commit 8ddc4d59444a362261e10a3b22324818f5dd2fa7 > > Author: Gerrit Pape <pape@smarden.org> > > Date: Wed Jun 13 09:10:30 2007 +0000 > > > > file > > > > diff --git a/file b/file > > index 257cc56..3bd1f0e 100644 > > --- a/file > > +++ b/file > > @@ -1 +1,2 @@ > > foo > > +bar > > $ > > > > The patch applies to master just fine. Where's my thinking wrong? > > Hmm. Indeed. Thanks for clearing that up. Will work on it later. Hi, did you get to this yet?, not to stress you, just to make sure we don't forget about it. Thanks, Gerrit. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: unexpected git-cherry-pick conflict 2007-06-25 7:18 ` Gerrit Pape @ 2007-06-25 7:55 ` Johannes Schindelin 2007-07-07 20:58 ` Johannes Schindelin 2007-07-08 0:52 ` [PATCH] merge-tree: sometimes, d/f conflict is not an issue Johannes Schindelin 2 siblings, 0 replies; 23+ messages in thread From: Johannes Schindelin @ 2007-06-25 7:55 UTC (permalink / raw) To: Gerrit Pape; +Cc: git Hi, On Mon, 25 Jun 2007, Gerrit Pape wrote: > On Wed, Jun 13, 2007 at 03:43:48PM +0100, Johannes Schindelin wrote: > > On Wed, 13 Jun 2007, Gerrit Pape wrote: > > > On Wed, Jun 13, 2007 at 01:58:51PM +0100, Johannes Schindelin wrote: > > > > On Wed, 13 Jun 2007, Gerrit Pape wrote: > > > > > $ git checkout master > > > > > Switched to branch "master" > > > > > $ git cherry-pick 8ddc4d5 > > > > > CONFLICT (file/directory): There is a directory with name link in > > > > > 8ddc4d5... file. Added link as link~HEAD > > > > > > > > Here you _still_ have the file in master. So that conflict is really > > > > expected, since a cherry-pick will only do a three-way merge. > > > > > > git-cherry-pick(1) states > > > Given one existing commit, apply the change the patch introduces, and > > > record a new commit that records it. This requires your working tree to > > > be clean (no modifications from the HEAD commit). > > > > > > The patch introduced by the commit that's cherry-pick'ed has nothing to > > > do with the link or new directory, it just changes 'file' > > > > > > $ git show 8ddc4d5 > > > commit 8ddc4d59444a362261e10a3b22324818f5dd2fa7 > > > Author: Gerrit Pape <pape@smarden.org> > > > Date: Wed Jun 13 09:10:30 2007 +0000 > > > > > > file > > > > > > diff --git a/file b/file > > > index 257cc56..3bd1f0e 100644 > > > --- a/file > > > +++ b/file > > > @@ -1 +1,2 @@ > > > foo > > > +bar > > > $ > > > > > > The patch applies to master just fine. Where's my thinking wrong? > > > > Hmm. Indeed. Thanks for clearing that up. Will work on it later. > > Hi, did you get to this yet?, not to stress you, just to make sure we > don't forget about it. I did not have time yet. Thanks for the reminder. Just for the record, if you send a reply to my message to the list, but without Cc: to me, I am very likely to miss it. Just by chance I did not, this time. Ciao, Dscho ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: unexpected git-cherry-pick conflict 2007-06-25 7:18 ` Gerrit Pape 2007-06-25 7:55 ` Johannes Schindelin @ 2007-07-07 20:58 ` Johannes Schindelin 2007-12-21 10:37 ` Gerrit Pape 2007-07-08 0:52 ` [PATCH] merge-tree: sometimes, d/f conflict is not an issue Johannes Schindelin 2 siblings, 1 reply; 23+ messages in thread From: Johannes Schindelin @ 2007-07-07 20:58 UTC (permalink / raw) To: Gerrit Pape; +Cc: git Hi, On Mon, 25 Jun 2007, Gerrit Pape wrote: > Hi, did you get to this yet?, not to stress you, just to make sure we > don't forget about it. Okay. Since now both you and Junio asked for it, and I made today a Git day for me, I looked into this. I'm not yet done, but preliminary results are: - cherry-pick calls merge-recursive, which in turn calls unpack_trees(), which in turn gives the ball to threeway_merge. But for d/f conflicts, it goes wrong. - Documentation/technical/trivial-merge.txt is maybe about a trivial merge. But the document is not trivial in and of itself. I'll keep going, Dscho ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: unexpected git-cherry-pick conflict 2007-07-07 20:58 ` Johannes Schindelin @ 2007-12-21 10:37 ` Gerrit Pape 2007-12-22 8:20 ` Junio C Hamano 0 siblings, 1 reply; 23+ messages in thread From: Gerrit Pape @ 2007-12-21 10:37 UTC (permalink / raw) To: Johannes Schindelin; +Cc: git On Sat, Jul 07, 2007 at 09:58:08PM +0100, Johannes Schindelin wrote: > On Mon, 25 Jun 2007, Gerrit Pape wrote: > > Hi, did you get to this yet?, not to stress you, just to make sure we > > don't forget about it. > > Okay. Since now both you and Junio asked for it, and I made today a Git > day for me, I looked into this. Hi, the discussion on this topic unfortunately didn't result in a patch. The problem is still true with current master, here's again how to reproduce it $ mkdir repo && cd repo $ git init Initialized empty Git repository in .git/ $ echo foo >file $ ln -s dangling link $ git add . $ git commit -mfoo Created initial commit c6a9189: foo 2 files changed, 2 insertions(+), 0 deletions(-) create mode 100644 file create mode 120000 link $ git checkout -b branch Switched to a new branch "branch" $ git rm link rm 'link' $ git commit -mremovelink Created commit 2c60f15: removelink 1 files changed, 0 insertions(+), 1 deletions(-) delete mode 120000 link $ mkdir link $ echo bar >link/file $ git add link $ git commit -m adddir Created commit d3b30b5: adddir 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 link/file $ echo bar >>file $ git commit -mfile file Created commit 8ddc4d5: file 1 files changed, 1 insertions(+), 0 deletions(-) $ git checkout master Switched to branch "master" $ git cherry-pick 8ddc4d5 CONFLICT (file/directory): There is a directory with name link in 8ddc4d5... file. Added link as link~HEAD Automatic cherry-pick failed. After resolving the conflicts, mark the corrected paths with 'git-add <paths>' and commit the result. When commiting, use the option '-c 8ddc4d5' to retain authorship and message. $ Thanks, Gerrit. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: unexpected git-cherry-pick conflict 2007-12-21 10:37 ` Gerrit Pape @ 2007-12-22 8:20 ` Junio C Hamano 0 siblings, 0 replies; 23+ messages in thread From: Junio C Hamano @ 2007-12-22 8:20 UTC (permalink / raw) To: Gerrit Pape; +Cc: Johannes Schindelin, git Gerrit Pape <pape@smarden.org> writes: > On Sat, Jul 07, 2007 at 09:58:08PM +0100, Johannes Schindelin wrote: >> On Mon, 25 Jun 2007, Gerrit Pape wrote: >> > Hi, did you get to this yet?, not to stress you, just to make sure we >> > don't forget about it. >> >> Okay. Since now both you and Junio asked for it, and I made today a Git >> day for me, I looked into this. > > Hi, the discussion on this topic unfortunately didn't result in a patch. I know. Unfortunately the code structure in merge-recursive around directory-file conflict handling needs major surgery to fix this, and it won't be until somebody really sits down and rethink the issue. I've been quietly working on some ideas and a small nascent part of it is in 'pu' (or 'offcuts', perhaps, I do not remember offhand), but it will take time. ^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH] merge-tree: sometimes, d/f conflict is not an issue 2007-06-25 7:18 ` Gerrit Pape 2007-06-25 7:55 ` Johannes Schindelin 2007-07-07 20:58 ` Johannes Schindelin @ 2007-07-08 0:52 ` Johannes Schindelin 2007-07-08 1:31 ` Junio C Hamano 2 siblings, 1 reply; 23+ messages in thread From: Johannes Schindelin @ 2007-07-08 0:52 UTC (permalink / raw) To: Gerrit Pape; +Cc: git, Rémi Vanicat, gitster [-- Attachment #1: Type: TEXT/PLAIN, Size: 3427 bytes --] When a merge has a d/f conflict on a path which was not touched between the merge base(s) and the remote HEAD, and the index and HEAD contain the same version for that path (even if empty), it is not really a conflict. Noticed by Rémi Vanicat, reported to the Git list by Gerrit Pape. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> --- The only peculiar result is that you can have an entry at stage 0 for one path, and stages 1 and 3 for another path where the first path is a prefix. This can happen now, when you have deleted a directory since the branching point, and put a file in the same place, but the other side has changed files in that directory. This change is reflected in the change to t3030. I have no idea if the change is the best there is, but after spending some hours trying to get my head around what is written in Documentation/technical/trivial-merge.txt, and what is in the function threeway_merge(), and still not understanding most of it, there is not much more that I can do. Funny note at the side: when I finally got to Gerrit's email again today, gmane said _almost_ that it was 3 weeks, 3 days, 3 hours and 3 minutes ago... t/t3030-merge-recursive.sh | 2 +- t/t3502-cherry-pick.sh | 31 +++++++++++++++++++++++++++++++ unpack-trees.c | 14 ++++++++++++++ 3 files changed, 46 insertions(+), 1 deletions(-) create mode 100755 t/t3502-cherry-pick.sh diff --git a/t/t3030-merge-recursive.sh b/t/t3030-merge-recursive.sh index 607f57f..d413af1 100755 --- a/t/t3030-merge-recursive.sh +++ b/t/t3030-merge-recursive.sh @@ -450,7 +450,7 @@ test_expect_success 'merge-recursive d/f conflict result' ' echo "100644 $o1 0 a" echo "100644 $o0 0 b" echo "100644 $o0 0 c" - echo "100644 $o6 2 d" + echo "100644 $o6 0 d" echo "100644 $o0 1 d/e" echo "100644 $o1 3 d/e" ) >expected && diff --git a/t/t3502-cherry-pick.sh b/t/t3502-cherry-pick.sh new file mode 100755 index 0000000..da3d26e --- /dev/null +++ b/t/t3502-cherry-pick.sh @@ -0,0 +1,31 @@ +#!/bin/sh + +test_description='test cherry-pick' + +. ./test-lib.sh + +test_expect_success setup ' + echo foo > file && + ln -s dangling link && + git add file link && + test_tick && + git commit -m foo && + git checkout -b branch && + git rm link && + test_tick && + git commit -m "remove link" && + mkdir link && + echo bar > link/file && + git add link/file && + test_tick && + git commit -m "add dir" && + echo bar > file && + git commit -m "change file" file && + git checkout master +' + +test_expect_success 'cherry-pick ignores unrelated dir/symlink conflict' ' + git cherry-pick branch +' + +test_done diff --git a/unpack-trees.c b/unpack-trees.c index cac2411..080b016 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -643,6 +643,20 @@ int threeway_merge(struct cache_entry **stages, index = stages[0]; head = stages[o->head_idx]; + /* + * Special case: do not care about a dir/file conflict, when + * the entries have not been touched. + * IOW if the ancestors are identical to the remote, and the + * index is the same as head, just take head. + */ + if (head && same(index, head)) { + for (i = 1; i < o->head_idx; i++) + if (!same(stages[i], remote)) + break; + if (i == o->head_idx) + return merged_entry(head, index, o); + } + if (head == o->df_conflict_entry) { df_conflict_head = 1; head = NULL; -- 1.5.3.rc0.2712.g125b7f ^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH] merge-tree: sometimes, d/f conflict is not an issue 2007-07-08 0:52 ` [PATCH] merge-tree: sometimes, d/f conflict is not an issue Johannes Schindelin @ 2007-07-08 1:31 ` Junio C Hamano 2007-07-08 2:00 ` Johannes Schindelin 0 siblings, 1 reply; 23+ messages in thread From: Junio C Hamano @ 2007-07-08 1:31 UTC (permalink / raw) To: Johannes Schindelin; +Cc: Gerrit Pape, git, Rémi Vanicat, gitster Johannes Schindelin <Johannes.Schindelin@gmx.de> writes: > @@ -643,6 +643,20 @@ int threeway_merge(struct cache_entry **stages, > index = stages[0]; > head = stages[o->head_idx]; > > + /* > + * Special case: do not care about a dir/file conflict, when > + * the entries have not been touched. > + * IOW if the ancestors are identical to the remote, and the > + * index is the same as head, just take head. > + */ Suppose paths "A" and "A/B" are involved, and you resolved with this logic to have "A" as a blob (so your HEAD does not have "A/B"). If the remote adds "A/B", what prevents the resulting index to have both "A" and "A/B" resolved at stage #0? A logic to do "if it is unchanged on one and changed in another, take changed one" already exists in later part of the code; your patch just circumvents D/F checks built into threeway_merge for this one case, and only because this one case happens to have reported. It doesn't feel right. IOW, don't make unpack-trees to make policy decisions on final resolution, unless it is operating under aggressive rule (where the caller explicitly allows it to make more than the "trivial" decisions). The caller (in this case, merge-recursive) should see A at stage #2 with A/B at stages #1 and #3 and decide what to do. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH] merge-tree: sometimes, d/f conflict is not an issue 2007-07-08 1:31 ` Junio C Hamano @ 2007-07-08 2:00 ` Johannes Schindelin 2007-07-08 2:18 ` Johannes Schindelin 2007-07-08 5:50 ` Junio C Hamano 0 siblings, 2 replies; 23+ messages in thread From: Johannes Schindelin @ 2007-07-08 2:00 UTC (permalink / raw) To: Junio C Hamano; +Cc: Gerrit Pape, git, Rémi Vanicat Hi, On Sat, 7 Jul 2007, Junio C Hamano wrote: > Johannes Schindelin <Johannes.Schindelin@gmx.de> writes: > > > @@ -643,6 +643,20 @@ int threeway_merge(struct cache_entry **stages, > > index = stages[0]; > > head = stages[o->head_idx]; > > > > + /* > > + * Special case: do not care about a dir/file conflict, when > > + * the entries have not been touched. > > + * IOW if the ancestors are identical to the remote, and the > > + * index is the same as head, just take head. > > + */ > > Suppose paths "A" and "A/B" are involved, and you resolved with > this logic to have "A" as a blob (so your HEAD does not have > "A/B"). If the remote adds "A/B", what prevents the resulting > index to have both "A" and "A/B" resolved at stage #0? Hmm. > A logic to do "if it is unchanged on one and changed in another, > take changed one" already exists in later part of the code; your > patch just circumvents D/F checks built into threeway_merge for > this one case, and only because this one case happens to have > reported. It doesn't feel right. Well, for me the code in threeway_merge does not feel right. There is a table in technical/trivial-merge.txt (which I not fully understand, since nowhere in the table, there is a mention of the index, and nowhere is explained what "ALT" is supposed to mean), but threeway_merge only references the numbers. The code is not obvious to me. I spent some hours staring on, and trying to make sense of it. Alas, I am an idiot or something, since my brain feels like a mashed potato, and I still do not understand the code. For example, it is not apparent to me why the variable "head" should be set to NULL, when it was the df_conflict_entry. So yeah, this patch was marked as "PATCH", but the subject line is not long enough for the proper prefix, which would have started like "[This PATCH works for me, and I do not know how to make it better, since I do not understand the code in threeway_merge(), and that does not make me happy, but that is the way things are, and maybe someone more intelligent than me recognizes what is meant by my little patch, and can fix it up, ...]". > IOW, don't make unpack-trees to make policy decisions on final > resolution, unless it is operating under aggressive rule (where the > caller explicitly allows it to make more than the "trivial" decisions). > The caller (in this case, merge-recursive) should see A at stage #2 with > A/B at stages #1 and #3 and decide what to do. Okay, so you're saying that merge-recursive should use the aggressive strategy? Ciao, Dscho ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH] merge-tree: sometimes, d/f conflict is not an issue 2007-07-08 2:00 ` Johannes Schindelin @ 2007-07-08 2:18 ` Johannes Schindelin 2007-07-08 4:35 ` Johannes Schindelin 2007-07-08 5:50 ` Junio C Hamano 1 sibling, 1 reply; 23+ messages in thread From: Johannes Schindelin @ 2007-07-08 2:18 UTC (permalink / raw) To: Junio C Hamano; +Cc: git Hi, On Sun, 8 Jul 2007, Johannes Schindelin wrote: > On Sat, 7 Jul 2007, Junio C Hamano wrote: > > > IOW, don't make unpack-trees to make policy decisions on final > > resolution, unless it is operating under aggressive rule (where the > > caller explicitly allows it to make more than the "trivial" > > decisions). The caller (in this case, merge-recursive) should see A > > at stage #2 with A/B at stages #1 and #3 and decide what to do. > > Okay, so you're saying that merge-recursive should use the aggressive > strategy? To refine on that: from my (limited, I admit) understanding of the code, by the time it hits that "if (o->aggressive)", in case of a df conflict, the chance has long whizzed by to decide anything useful, since either head or remote were set to NULL. So they are no longer what they would have to be in order to make any sense. Well, I try to cobble up a patch for merge-recursive like you suggested, and stay away from threeway_merge() as far as I can, for the rest of my life. However, it feels somehow wrong that I have to check all the files in the unmerged index, when unpack_trees could have easily seen that the tree did not change between all (in that case, just one) ancestors and the remote, but that head has changed that path to a file, and head agrees with index on that, and remote can stay where it is with its darned directory. Ciao, Dscho ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH] merge-tree: sometimes, d/f conflict is not an issue 2007-07-08 2:18 ` Johannes Schindelin @ 2007-07-08 4:35 ` Johannes Schindelin 0 siblings, 0 replies; 23+ messages in thread From: Johannes Schindelin @ 2007-07-08 4:35 UTC (permalink / raw) To: Junio C Hamano; +Cc: git Hi, On Sun, 8 Jul 2007, Johannes Schindelin wrote: > Well, I try to cobble up a patch for merge-recursive like you suggested, > and stay away from threeway_merge() as far as I can, for the rest of my > life. Here is a WIP. Note: it only does half of the job. For performance reasons, we do not write out the working tree changes for intermediate merges. However, in the last step, we do. And this patch does not reflect that, but only updates the index. Ciao, Dscho merge-recursive.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 88 insertions(+), 0 deletions(-) diff --git a/merge-recursive.c b/merge-recursive.c index dbd06aa..99da2bb 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -243,6 +243,92 @@ static int git_merge_trees(int index_only, return rc; } +/* + * If there were dir/file conflicts, which are not really dir/file + * conflicts, because only one side changed anything, take that + * side instead of outputting silly conflicts. + * + * NOTE! unpack_trees() would have a much better chance at resolving + * these conflicts, since it gets the _tree_ objects we have to + * reconstruct tediously, and it could get away with one simple + * comparison between sha1's, while that is not possible here. + */ +static inline int is_df(struct cache_entry *in_dir, struct cache_entry *file) +{ + int len = ce_namelen(file); + const char *name = in_dir->name; + return !memcmp(name, file->name, len) && name[len] == '/'; +} + +static int try_to_fix_up_df_conflicts_which_are_none(const unsigned char *base, + const unsigned char *head, const unsigned char *merge) +{ + int i; + for (i = 0; i + 2 < active_nr; i++) { + int last; + unsigned char sha1[20], sha2[20]; + unsigned dummy; + char *name; + struct cache_entry *ce = active_cache[i], *ce1, *ce2; + + if (ce_stage(ce) == 0) + continue; + ce1 = active_cache[i + 1]; + ce2 = active_cache[i + 2]; + if (ce_same_name(ce, ce2) || !is_df(ce2, ce)) { + /* not a d/f conflict */ + i += 2; + continue; + } + for (last = i + 3; last < active_nr && + is_df(active_cache[last], ce); last++) + ; /* do nothing */ + /* check if HEAD as an unchanged file, remote a dir */ + if (ce_same_name(ce, ce1)) { + if (ce_stage(ce) != 1 || + hashcmp(ce->sha1, ce1->sha1)) { + /* file was changed */ + i = last - 1; + continue; + } + /* other side removed file, added dir */ + if (!remove_file_from_cache(ce->name)) + return error("index error"); + for (i -= 2, last -= 2; i < last; i++) + active_cache[i]->ce_flags &= + ~ntohs(CE_STAGEMASK); + i--; + continue; + } + if (i + 1 == last) + continue; + /* check if HEAD changed dir to a file */ + if (ce_stage(ce) == 1) { + i = last - 1; + continue; + } + name = xstrndup(ce->name, ce_namelen(ce)); + if (get_tree_entry(base, name, sha1, &dummy) || + get_tree_entry(ce_stage(ce) == 2 ? + merge : head, + name, sha2, &dummy)) { + free(name); + i = last - 1; + continue; + } + free(name); + if (!hashcmp(sha1, sha2)) { + /* remove tree */ + memmove(active_cache + i + 1, active_cache + last, + (active_nr - last) * + sizeof(struct cache_entry *)); + active_nr -= last - i - 1; + ce->ce_flags &= ~ntohs(CE_STAGEMASK); + } + } + return 0; +} + static int unmerged_index(void) { int i; @@ -1520,6 +1606,8 @@ static int merge_trees(struct tree *head, sha1_to_hex(head->object.sha1), sha1_to_hex(merge->object.sha1)); + try_to_fix_up_df_conflicts_which_are_none(common->object.sha1, + head->object.sha1, merge->object.sha1); if (unmerged_index()) { struct path_list *entries, *re_head, *re_merge; int i; ^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH] merge-tree: sometimes, d/f conflict is not an issue 2007-07-08 2:00 ` Johannes Schindelin 2007-07-08 2:18 ` Johannes Schindelin @ 2007-07-08 5:50 ` Junio C Hamano 2007-07-08 6:14 ` Junio C Hamano 2007-07-08 12:53 ` [PATCH] merge-tree: sometimes, d/f conflict is not an issue Johannes Schindelin 1 sibling, 2 replies; 23+ messages in thread From: Junio C Hamano @ 2007-07-08 5:50 UTC (permalink / raw) To: Johannes Schindelin; +Cc: Gerrit Pape, git, Rémi Vanicat Johannes Schindelin <Johannes.Schindelin@gmx.de> writes: >> IOW, don't make unpack-trees to make policy decisions on final >> resolution, unless it is operating under aggressive rule (where the >> caller explicitly allows it to make more than the "trivial" decisions). >> The caller (in this case, merge-recursive) should see A at stage #2 with >> A/B at stages #1 and #3 and decide what to do. > > Okay, so you're saying that merge-recursive should use the aggressive > strategy? I do not think so. Isn't the whole "see if there are renames" thing depend on threeway_merge() not resolving "one side removes other side leaves intact" case itself? Aggressive resolves it saying "Ok that is a remove", which risks it to miss the case in which that the side that apparently "removed" the path in fact moved it somewhere else. The last time I looked at merge-recursive's D/F check, I found that it was not quite doing things right. I may be able to dig up what I posted to the list... ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH] merge-tree: sometimes, d/f conflict is not an issue 2007-07-08 5:50 ` Junio C Hamano @ 2007-07-08 6:14 ` Junio C Hamano 2007-07-08 13:16 ` Johannes Schindelin 2007-07-08 12:53 ` [PATCH] merge-tree: sometimes, d/f conflict is not an issue Johannes Schindelin 1 sibling, 1 reply; 23+ messages in thread From: Junio C Hamano @ 2007-07-08 6:14 UTC (permalink / raw) To: Johannes Schindelin; +Cc: Gerrit Pape, git, Rémi Vanicat Junio C Hamano <gitster@pobox.com> writes: > Johannes Schindelin <Johannes.Schindelin@gmx.de> writes: > ... >> Okay, so you're saying that merge-recursive should use the aggressive >> strategy? > > I do not think so. Isn't the whole "see if there are renames" thing > depend on threeway_merge() not resolving "one side removes other > side leaves intact" case itself? Aggressive resolves it saying > "Ok that is a remove", which risks it to miss the case in which > that the side that apparently "removed" the path in fact moved > it somewhere else. > > The last time I looked at merge-recursive's D/F check, I found > that it was not quite doing things right. I may be able to dig > up what I posted to the list... It was from around April 7th-10th this year. http://thread.gmane.org/gmane.comp.version-control.git/43970/focus=44158 http://thread.gmane.org/gmane.comp.version-control.git/43971/focus=43997 I think the case described in the latter message is almost the opposite case of what your patch tries to deal with. In the web interface of http://news.gmane.org/gmane.comp.version-control.git the patch series that led to my complaints are at around page 76 for me. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH] merge-tree: sometimes, d/f conflict is not an issue 2007-07-08 6:14 ` Junio C Hamano @ 2007-07-08 13:16 ` Johannes Schindelin 2007-07-08 20:02 ` Junio C Hamano 0 siblings, 1 reply; 23+ messages in thread From: Johannes Schindelin @ 2007-07-08 13:16 UTC (permalink / raw) To: Junio C Hamano; +Cc: Gerrit Pape, git, Rémi Vanicat Hi, On Sat, 7 Jul 2007, Junio C Hamano wrote: > Junio C Hamano <gitster@pobox.com> writes: > > > The last time I looked at merge-recursive's D/F check, I found that it > > was not quite doing things right. I may be able to dig up what I > > posted to the list... > > It was from around April 7th-10th this year. Unfortunately, this is way over my time budget. As well as over my intelligence budget, since I did not even succeed in understanding the code in threeway_merge _at all_. Besides, IMHO there is a deeper issue. Since merge-recursive started out as a Python script, and grew there until it was usable, and grew the rename detection therein, too, until it was finally converted to C, it accumulated a lot of features that would have been nice to have independently. Almost the same goes for unpack-trees, which (its name to the contrary) does quite a few things to merge entries, too. And it tries to detect d/f conflicts, too. So there we are, with two really big and unwieldy chunks of code, each deserving an own GSoC project to clean them up. Or maybe not even a GSoC project, but a longer project. What I would _like_ to see is something as clean as merge-tree. Which is clearly separated (code and file wise, too) into these stages: - reading the trees - determining renames - determining true d/f conflicts - threeway merge - writing the tree object - writing the work tree - recursive Ideally, merge-recursive would really have been as simple as case "$1" in --index_only) index_only=$1 shift esac a="$1" b="$2" set $(git merge-base --all $a $b) temp=$1 shift while case $# in 0) break;; esac do temp=$(git merge-recursive --index-only $temp $1) shift done git merge-non-recursive $index_only $temp -- "$a" "$b" because _read-tree -m_ should have learnt about renames, _not_ merge-recursive. As it is, both unpack_trees() and merge-recursive have a certain degree of not-quite duplicated yet wants-to-do-largely-the-same functionality. Which of course leads to much finger pointing: "it's unpack_trees() fault. no. it's merge-recursive's fault. no, vice versa." Maybe the proper way out is really to start from merge-tree.c and do something which is easy to understand, and concise, and thus has a much lesser chance of being buggy. Ciao, Dscho ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH] merge-tree: sometimes, d/f conflict is not an issue 2007-07-08 13:16 ` Johannes Schindelin @ 2007-07-08 20:02 ` Junio C Hamano 2007-07-09 15:06 ` merge-one-file, was " Johannes Schindelin ` (2 more replies) 0 siblings, 3 replies; 23+ messages in thread From: Junio C Hamano @ 2007-07-08 20:02 UTC (permalink / raw) To: Johannes Schindelin; +Cc: Gerrit Pape, git, Rémi Vanicat Johannes Schindelin <Johannes.Schindelin@gmx.de> writes: > Besides, IMHO there is a deeper issue. Since merge-recursive started out > as a Python script, and grew there until it was usable, and grew the > rename detection therein, too, until it was finally converted to C, it > accumulated a lot of features that would have been nice to have > independently. > ... > So there we are, with two really big and unwieldy chunks of code, each > deserving an own GSoC project to clean them up. Or maybe not even a GSoC > project, but a longer project. I would not disagree that tree merging part is a large piece of code with nontrivial development history. While I do agree that merge-tree approach is attractive in the longer run, I do not think the current "use read-tree for policy-neutral merge and then higher level to decide what to do with conflicts" is beyond repair. I tried a variant of cherry-pick that does _not_ use merge-recursive on the reproduction recipe from Gerrit & Rémi. Essentially, a cherry-pick with a backend is: git-merge-$backend $commit^ -- HEAD $commit It was made cumbersome to try different merge backend when cherry-pick has become built-in, but the above essentially was what we had in the shell script version. Interestingly, git-merge-resolve fails, but for an entirely different reason; there is a bug in git-merge-one-file. I am kind of surprised that this has been left undetected for a long time (this shows how everybody uses git-merge-recursive these days and not git-merge-resolve). commit ed93b449 adds tests for only the "read-tree" part, even though it makes "matching" change to merge-one-file, which was the breakage. The bug is that merge-one-file did not "resolve" an unmerged index entry when it decided what the result should be --- it decided only in its comments but not with what it does! Embarrassing (a fix is attached). With that fix, the above "cherry-pick" lookalike with $backend set to "resolve" and $commit set to "branch" in Gerrit's example reproduction recipe seems to do the right thing. > As it is, both unpack_trees() and merge-recursive have a certain degree of > not-quite duplicated yet wants-to-do-largely-the-same functionality. > Which of course leads to much finger pointing: "it's unpack_trees() fault. > no. it's merge-recursive's fault. no, vice versa." I do not think there is any pointing-fingers involved in this case. The division of labor between "read-tree -m" and its caller has been very clear from the beginning, and has not changed. The former does "uncontroversial parts of merge", and the latter uses its own policy decision to resolve conflicts. The "uncontroversial parts of merge" explicitly exclude "one side removes (or adds), other side does not do anything" case. This is cumbersome for rename-unaware merge-resolve, because its policy is "we do not worry about the case that the apparent removal is in fact it moves it to somewhere else -- if one side removes, the result will not have it", and for that policy if "read-tree -m" did so it would have less work to do. But we don't, exactly because other policy like merge-recursive may want to look at the apparently removed path and figure out if there is a rename involved. The last time I looked at merge-recursive.c, I think the problem I saw was the way it maintains and uses two lists that keeps track of the set of directories and files; get_files_dirs() is called for both head and merge at the beginning, and I did not see a code that says "Oh, we recorded the path 'link' as being potentially a directory at the beginning, but we have decided to resolve 'link/file' by removing it, and 'link' does not have to exist as a directory anymore. resolving 'link' as a symbolic link is perfectly fine" --- and the reason Gerrit's test case fails was something like that. -- >8 -- [PATCH] Fix merge-one-file for our-side-added/our-side-removed cases When commit ed93b449 changed the script so that it does not touch untracked working tree file, we forgot that we still needed to resolve the index entry (otherwise they are left unmerged). Signed-off-by: Junio C Hamano <gitster@pobox.com> --- diff --git a/git-merge-one-file.sh b/git-merge-one-file.sh index ebbb575..1e7727d 100755 --- a/git-merge-one-file.sh +++ b/git-merge-one-file.sh @@ -27,8 +27,9 @@ case "${1:-.}${2:-.}${3:-.}" in # read-tree checked that index matches HEAD already, # so we know we do not have this path tracked. # there may be an unrelated working tree file here, - # which we should just leave unmolested. - exit 0 + # which we should just leave unmolested. Make sure + # we do not have it in the index, though. + exec git update-index --remove -- "$4" fi if test -f "$4"; then rm -f -- "$4" && @@ -42,7 +43,8 @@ case "${1:-.}${2:-.}${3:-.}" in # ".$2.") # the other side did not add and we added so there is nothing - # to be done. + # to be done, except making the path merged. + exec git update-index --add --cacheinfo "$6" "$2" "$4" ;; "..$3") echo "Adding $4" @@ -50,7 +52,7 @@ case "${1:-.}${2:-.}${3:-.}" in echo "ERROR: untracked $4 is overwritten by the merge." exit 1 } - git update-index --add --cacheinfo "$6$7" "$2$3" "$4" && + git update-index --add --cacheinfo "$7" "$3" "$4" && exec git checkout-index -u -f -- "$4" ;; ^ permalink raw reply related [flat|nested] 23+ messages in thread
* merge-one-file, was Re: [PATCH] merge-tree: sometimes, d/f conflict is not an issue 2007-07-08 20:02 ` Junio C Hamano @ 2007-07-09 15:06 ` Johannes Schindelin 2007-07-17 17:13 ` [PATCH 1/2] merge-recursive: " Johannes Schindelin 2007-07-17 17:14 ` [PATCH 2/2] Add tests for cherry-pick d/f conflict which should be none Johannes Schindelin 2 siblings, 0 replies; 23+ messages in thread From: Johannes Schindelin @ 2007-07-09 15:06 UTC (permalink / raw) To: Junio C Hamano; +Cc: Gerrit Pape, git, Rémi Vanicat Hi, On Sun, 8 Jul 2007, Junio C Hamano wrote: > [PATCH] Fix merge-one-file for our-side-added/our-side-removed cases FWIW I have a patch series in my local repo, which makes merge-one-file a builtin, and even avoids fork()+exec()ing the program when called from unpack_trees(). However, I never came around to understand all the corner cases, and therefore did not write tests for it. Therefore, I am not really sure if it works as intended. So I'd be very grateful if you could write tests while you are touching it anyway... Ciao, Dscho ^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 1/2] merge-recursive: sometimes, d/f conflict is not an issue 2007-07-08 20:02 ` Junio C Hamano 2007-07-09 15:06 ` merge-one-file, was " Johannes Schindelin @ 2007-07-17 17:13 ` Johannes Schindelin 2007-08-08 14:39 ` Gerrit Pape 2007-07-17 17:14 ` [PATCH 2/2] Add tests for cherry-pick d/f conflict which should be none Johannes Schindelin 2 siblings, 1 reply; 23+ messages in thread From: Johannes Schindelin @ 2007-07-17 17:13 UTC (permalink / raw) To: Junio C Hamano; +Cc: Gerrit Pape, git, Rémi Vanicat [-- Attachment #1: Type: TEXT/PLAIN, Size: 3697 bytes --] When a merge has a d/f conflict on a path which was not touched between the merge base(s) and the remote HEAD, and the index and HEAD contain the same version for that path (even if empty), it is not really a conflict. Noticed by Rémi Vanicat, reported to the Git list by Gerrit Pape. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> --- Turns out I was wrong with my "this is only half of it" remark. AFAICT "merge-tree -u -m" does not touch the files which have unmerged entries, but merge-recursive does. And since fix_up_df_conflicts() is called before any of that, it just works. merge-recursive.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 87 insertions(+), 0 deletions(-) diff --git a/merge-recursive.c b/merge-recursive.c index c8539ec..fb487ba 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -243,6 +243,91 @@ static int git_merge_trees(int index_only, return rc; } +/* + * If there were dir/file conflicts, which are not really dir/file + * conflicts, because only one side changed anything, take that + * side instead of outputting silly conflicts. + * + * We keep it nice and easy, in that we only fix the conflicts if one + * side was renamed without changing the contents _at all_. We check that + * by comparing the hash. + */ +static inline int is_df(struct cache_entry *in_dir, struct cache_entry *file) +{ + int len = ce_namelen(file); + const char *name = in_dir->name; + return !memcmp(name, file->name, len) && name[len] == '/'; +} + +static int fix_up_df_conflicts(const unsigned char *base, + const unsigned char *head, const unsigned char *merge) +{ + int i; + for (i = 0; i + 2 < active_nr; i++) { + int last; + unsigned char sha1[20], sha2[20]; + unsigned dummy; + char *name; + struct cache_entry *ce = active_cache[i], *ce1, *ce2; + + if (ce_stage(ce) == 0) + continue; + ce1 = active_cache[i + 1]; + ce2 = active_cache[i + 2]; + if (ce_same_name(ce, ce2) || !is_df(ce2, ce)) { + /* not a d/f conflict */ + i += 2; + continue; + } + for (last = i + 3; last < active_nr && + is_df(active_cache[last], ce); last++) + ; /* do nothing */ + /* check if unchanged in HEAD */ + if (ce_same_name(ce, ce1)) { + if (ce_stage(ce) != 1 || + hashcmp(ce->sha1, ce1->sha1)) { + /* file was changed */ + i = last - 1; + continue; + } + /* other side removed file, added dir */ + if (!remove_file_from_cache(ce->name)) + return error("index error"); + for (i -= 2, last -= 2; i < last; i++) + active_cache[i]->ce_flags &= + ~ntohs(CE_STAGEMASK); + i--; + continue; + } + if (i + 1 == last) + continue; + /* check if HEAD changed type (e.g. dir->file) */ + if (ce_stage(ce) == 1) { + i = last - 1; + continue; + } + name = xstrndup(ce->name, ce_namelen(ce)); + if (get_tree_entry(base, name, sha1, &dummy) || + get_tree_entry(ce_stage(ce) == 2 ? + merge : head, + name, sha2, &dummy)) { + free(name); + i = last - 1; + continue; + } + free(name); + if (!hashcmp(sha1, sha2)) { + /* remove tree */ + memmove(active_cache + i + 1, active_cache + last, + (active_nr - last) * + sizeof(struct cache_entry *)); + active_nr -= last - i - 1; + ce->ce_flags &= ~ntohs(CE_STAGEMASK); + } + } + return 0; +} + static int unmerged_index(void) { int i; @@ -1542,6 +1627,8 @@ static int merge_trees(struct tree *head, sha1_to_hex(head->object.sha1), sha1_to_hex(merge->object.sha1)); + fix_up_df_conflicts(common->object.sha1, + head->object.sha1, merge->object.sha1); if (unmerged_index()) { struct path_list *entries, *re_head, *re_merge; int i; -- 1.5.3.rc1.16.g9d6f-dirty ^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH 1/2] merge-recursive: sometimes, d/f conflict is not an issue 2007-07-17 17:13 ` [PATCH 1/2] merge-recursive: " Johannes Schindelin @ 2007-08-08 14:39 ` Gerrit Pape 0 siblings, 0 replies; 23+ messages in thread From: Gerrit Pape @ 2007-08-08 14:39 UTC (permalink / raw) To: Johannes Schindelin; +Cc: Junio C Hamano, git On Tue, Jul 17, 2007 at 06:13:12PM +0100, Johannes Schindelin wrote: > When a merge has a d/f conflict on a path which was not touched > between the merge base(s) and the remote HEAD, and the index and > HEAD contain the same version for that path (even if empty), it > is not really a conflict. Hi, this patch solves the reported problem fine, and it didn't break anything for me yet. Can this still be considered for 1.5.3? Thanks, Gerrit. ^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 2/2] Add tests for cherry-pick d/f conflict which should be none 2007-07-08 20:02 ` Junio C Hamano 2007-07-09 15:06 ` merge-one-file, was " Johannes Schindelin 2007-07-17 17:13 ` [PATCH 1/2] merge-recursive: " Johannes Schindelin @ 2007-07-17 17:14 ` Johannes Schindelin 2 siblings, 0 replies; 23+ messages in thread From: Johannes Schindelin @ 2007-07-17 17:14 UTC (permalink / raw) To: Junio C Hamano; +Cc: Gerrit Pape, git, Rémi Vanicat This tests that we fixed the problem when a directory was renamed, and a symlink was added in its place (or for that matter, if the type changed in one branch, and the name in another). Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> --- The last test checks that also a file/symlink conflict does not break cherry-pick, if one side had a clean rename. t/t3502-cherry-pick.sh | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 43 insertions(+), 0 deletions(-) create mode 100755 t/t3502-cherry-pick.sh diff --git a/t/t3502-cherry-pick.sh b/t/t3502-cherry-pick.sh new file mode 100755 index 0000000..9921de5 --- /dev/null +++ b/t/t3502-cherry-pick.sh @@ -0,0 +1,43 @@ +#!/bin/sh + +test_description='test cherry-pick' + +. ./test-lib.sh + +test_expect_success setup ' + echo foo > file && + ln -s dangling link && + git add file link && + test_tick && + git commit -m foo && + git checkout -b branch && + git rm link && + test_tick && + git commit -m "remove link" && + mkdir link && + echo bar > link/file && + git add link/file && + test_tick && + git commit -m "add dir" && + echo bar > file && + git commit -m "change file" file && + git checkout master +' + +test_expect_success 'cherry-pick ignores unrelated dir/symlink conflict' ' + git cherry-pick branch +' + +test_expect_success 'cherry-pick ignores unrelated file/symlink conflict' ' + git checkout -b branch2 master^ && + git rm link && + test_tick && + git commit -m "remove link" && + : > link && + git add link && + test_tick && + git commit -m "add file" && + git cherry-pick master +' + +test_done -- 1.5.3.rc1.16.g9d6f-dirty ^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH] merge-tree: sometimes, d/f conflict is not an issue 2007-07-08 5:50 ` Junio C Hamano 2007-07-08 6:14 ` Junio C Hamano @ 2007-07-08 12:53 ` Johannes Schindelin 1 sibling, 0 replies; 23+ messages in thread From: Johannes Schindelin @ 2007-07-08 12:53 UTC (permalink / raw) To: Junio C Hamano; +Cc: Gerrit Pape, git, Rémi Vanicat Hi, On Sat, 7 Jul 2007, Junio C Hamano wrote: > Johannes Schindelin <Johannes.Schindelin@gmx.de> writes: > > >> IOW, don't make unpack-trees to make policy decisions on final > >> resolution, unless it is operating under aggressive rule (where the > >> caller explicitly allows it to make more than the "trivial" decisions). > >> The caller (in this case, merge-recursive) should see A at stage #2 with > >> A/B at stages #1 and #3 and decide what to do. > > > > Okay, so you're saying that merge-recursive should use the aggressive > > strategy? > > I do not think so. Yes, I realized that by running the tests with it. A rename A->B in one, and A->C in the other branch will go undetected. I should have written this into my mail posting the WIP patch, but frankly, I was too tired. Ciao, Dscho ^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2007-12-22 8:21 UTC | newest] Thread overview: 23+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- [not found] <20070405071615.2915.6837.reportbug@acer> [not found] ` <20070607074357.27760.qmail@69aef7b888effd.315fe32.mid.smarden.org> [not found] ` <6b8a91420706070252y3fd581a3w427d91e5b982d29d@mail.gmail.com> 2007-06-13 9:16 ` unexpected git-cherry-pick conflict Gerrit Pape 2007-06-13 12:58 ` Johannes Schindelin 2007-06-13 13:43 ` Gerrit Pape 2007-06-13 14:43 ` Johannes Schindelin 2007-06-25 7:18 ` Gerrit Pape 2007-06-25 7:55 ` Johannes Schindelin 2007-07-07 20:58 ` Johannes Schindelin 2007-12-21 10:37 ` Gerrit Pape 2007-12-22 8:20 ` Junio C Hamano 2007-07-08 0:52 ` [PATCH] merge-tree: sometimes, d/f conflict is not an issue Johannes Schindelin 2007-07-08 1:31 ` Junio C Hamano 2007-07-08 2:00 ` Johannes Schindelin 2007-07-08 2:18 ` Johannes Schindelin 2007-07-08 4:35 ` Johannes Schindelin 2007-07-08 5:50 ` Junio C Hamano 2007-07-08 6:14 ` Junio C Hamano 2007-07-08 13:16 ` Johannes Schindelin 2007-07-08 20:02 ` Junio C Hamano 2007-07-09 15:06 ` merge-one-file, was " Johannes Schindelin 2007-07-17 17:13 ` [PATCH 1/2] merge-recursive: " Johannes Schindelin 2007-08-08 14:39 ` Gerrit Pape 2007-07-17 17:14 ` [PATCH 2/2] Add tests for cherry-pick d/f conflict which should be none Johannes Schindelin 2007-07-08 12:53 ` [PATCH] merge-tree: sometimes, d/f conflict is not an issue Johannes Schindelin
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).