{"thread":{"id":"7466","subject":"SEGV in git-merge recursive:","startedAt":"2007-03-29T07:50:10Z","lastAt":"2007-03-31T20:03:43Z","messageCount":31,"participants":["Tom Prince","Alex Riesen","Linus Torvalds","Johannes Schindelin","Jakub Narebski","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"38287","messageId":"20070329075010.GA3493@hermes","threadId":"7466","inReplyTo":null,"subject":"SEGV in git-merge recursive:","fromName":"Tom Prince","fromEmail":"tom.prince@ualberta.net","sentAt":"2007-03-29T07:50:10Z","receivedAt":"2007-03-29T07:50:10Z","isPatch":false,"sender":{"key":"tom.prince@ualberta.net","avatar":"https://gravatar.com/avatar/a0ad19caee7618876339485106ec994f5202505eecd210ba5c0bd869feaa555a?d=mp&s=160"},"body":"I have been keeping my Maildir in git, a non-trivial merge that causes a\nsegfault in git-merge-recursive.\n\nIt does not appear to matter which direction I try to merge.\n\nI have a bundle of the relevant portion (rewritten with\ncg-admin-rewritehist) which still exhibits the problem.\nIt is about 160M, but has private email in it.\n\n  Tom Prince\n\n# git-rev-list --parents head merge\n922ee6e3f1222c8e171e6ea0b6ac0f28fb1f0683 2405850f1f347e471e040039672489573532582b # head\n2405850f1f347e471e040039672489573532582b 490451aa36da8dc35db59b68a5dc2dfa1a38d9b9\n0134d595adb023841750f1ce84ecb94dd4e4c9cb a85b502a7e827667bc84df06f0eb10a8abdd9a91 # merge\n490451aa36da8dc35db59b68a5dc2dfa1a38d9b9 e3870054c7f67aa401dbf830b5297c91add076d6\ne3870054c7f67aa401dbf830b5297c91add076d6 c14f3b6fef2727c26c993c8565f50047b036cedf\na85b502a7e827667bc84df06f0eb10a8abdd9a91 93c2854d90bd126b594594df3d5eb921361844ba\nc14f3b6fef2727c26c993c8565f50047b036cedf c96c42fca513eb782e0f9905ff8649a1800fc628\nc96c42fca513eb782e0f9905ff8649a1800fc628 7f1260b89b194b09f11f4d7f4a10dfd27c75ad59\n93c2854d90bd126b594594df3d5eb921361844ba a711bb1b8b4fd38d980235e662f801bf31af5782\n7f1260b89b194b09f11f4d7f4a10dfd27c75ad59 cc71e5ab9c70c1a3a018abfd770acbe823cc3746\ncc71e5ab9c70c1a3a018abfd770acbe823cc3746 1b21b61d2ebe6f54c258d9d1a846690145c408bc\na711bb1b8b4fd38d980235e662f801bf31af5782 29e722de58df3cd82600fa5215ec26f80a8c0f9a 2c3490d82610d12d8dfde36b29c4ec5a50955b89\n1b21b61d2ebe6f54c258d9d1a846690145c408bc 2c3490d82610d12d8dfde36b29c4ec5a50955b89 29e722de58df3cd82600fa5215ec26f80a8c0f9a\n29e722de58df3cd82600fa5215ec26f80a8c0f9a e2123cfd9a53e441c7c715627953606c6093e0e4\n2c3490d82610d12d8dfde36b29c4ec5a50955b89 3eb95ece931c80b50ad182c602ada3f35e240916\n3eb95ece931c80b50ad182c602ada3f35e240916 5a8eaa887ec82657fcf42a25db928ec263946018\n5a8eaa887ec82657fcf42a25db928ec263946018 e2123cfd9a53e441c7c715627953606c6093e0e4\ne2123cfd9a53e441c7c715627953606c6093e0e4\n"},{"id":"38290","messageId":"81b0412b0703290118q3e602a7bx650ac41241855546@mail.gmail.com","threadId":"7466","inReplyTo":"20070329075010.GA3493@hermes","subject":"Re: SEGV in git-merge recursive:","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-03-29T08:18:14Z","receivedAt":"2007-03-29T08:18:14Z","isPatch":false,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"On 3/29/07, Tom Prince <tom.prince@ualberta.net> wrote:\n> I have been keeping my Maildir in git, a non-trivial merge that causes a\n> segfault in git-merge-recursive.\n\nCan you try and get a stack trace? Do, for example, GIT_TRACE=1 git merge ...\n... find the call to git-merge-recursive and start that in gdb.\nWait until it crash.\n"},{"id":"38297","messageId":"20070329083219.GA6421@hermes","threadId":"7466","inReplyTo":"81b0412b0703290118q3e602a7bx650ac41241855546@mail.gmail.com","subject":"Re: SEGV in git-merge recursive:","fromName":"Tom Prince","fromEmail":"tom.prince@ualberta.net","sentAt":"2007-03-29T08:32:19Z","receivedAt":"2007-03-29T08:32:19Z","isPatch":false,"sender":{"key":"tom.prince@ualberta.net","avatar":"https://gravatar.com/avatar/a0ad19caee7618876339485106ec994f5202505eecd210ba5c0bd869feaa555a?d=mp&s=160"},"body":"On Thu, Mar 29, 2007 at 10:18:14AM +0200, Alex Riesen wrote:\n> On 3/29/07, Tom Prince <tom.prince@ualberta.net> wrote:\n> >I have been keeping my Maildir in git, a non-trivial merge that causes a\n> >segfault in git-merge-recursive.\n> \n> Can you try and get a stack trace? Do, for example, GIT_TRACE=1 git merge \n> ...\n> ... find the call to git-merge-recursive and start that in gdb.\n> Wait until it crash.\n\n\nHere is the backtrace.\n\n#0  0x0000000000402d29 in sha_eq (a=0xfefefefefefefeff <Address 0xfefefefefefefeff out of bounds>,\n    b=0x563cdc \"�6Cq�\\234�w:0T��\\177�\\023p\\214Q,\") at cache.h:259\n#1  0x000000000040456e in merge (h1=0x553ca0, h2=0x553d20, branch1=0x7fff92e5c27b \"HEAD\",\n    branch2=0x7fff92e5c3ee \"merge\", ca=0x5528a0, result=0x7fff92e5ab90) at merge-recursive.c:1115\n#2  0x0000000000405d89 in main (argc=-1830435858, argv=0x8) at merge-recursive.c:1362\n\nI actually got this backtrace with the following script in git-merge-gdb\n\n#!/bin/zsh\n\nexec gdb -x =(print run $@) =git-merge-recursive\n"},{"id":"38307","messageId":"81b0412b0703290429k63642a34u6bea1e08803ffba7@mail.gmail.com","threadId":"7466","inReplyTo":"20070329075010.GA3493@hermes","subject":"Re: SEGV in git-merge recursive:","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-03-29T11:29:46Z","receivedAt":"2007-03-29T11:29:46Z","isPatch":false,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"On 3/29/07, Tom Prince <tom.prince@ualberta.net> wrote:\n> I have been keeping my Maildir in git, a non-trivial merge that causes a\n> segfault in git-merge-recursive.\n>\n> It does not appear to matter which direction I try to merge.\n>\n\nBTW, what git do you have? git --version?\n"},{"id":"38310","messageId":"20070329125803.GA16739@hermes","threadId":"7466","inReplyTo":"81b0412b0703290429k63642a34u6bea1e08803ffba7@mail.gmail.com","subject":"Re: SEGV in git-merge recursive:","fromName":"Tom Prince","fromEmail":"tom.prince@ualberta.net","sentAt":"2007-03-29T12:58:03Z","receivedAt":"2007-03-29T12:58:03Z","isPatch":false,"sender":{"key":"tom.prince@ualberta.net","avatar":"https://gravatar.com/avatar/a0ad19caee7618876339485106ec994f5202505eecd210ba5c0bd869feaa555a?d=mp&s=160"},"body":"On Thu, Mar 29, 2007 at 01:29:46PM +0200, Alex Riesen wrote:\n> On 3/29/07, Tom Prince <tom.prince@ualberta.net> wrote:\n> >I have been keeping my Maildir in git, a non-trivial merge that causes a\n> >segfault in git-merge-recursive.\n> >\n> >It does not appear to matter which direction I try to merge.\n> >\n> \n> BTW, what git do you have? git --version?\n\n1.5.1.rc3\n"},{"id":"38311","messageId":"81b0412b0703290634j6e62ba89tce3c8c963be3fb92@mail.gmail.com","threadId":"7466","inReplyTo":"20070329125803.GA16739@hermes","subject":"Re: SEGV in git-merge recursive:","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-03-29T13:34:00Z","receivedAt":"2007-03-29T13:34:00Z","isPatch":false,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"On 3/29/07, Tom Prince <tom.prince@ualberta.net> wrote:\n> On Thu, Mar 29, 2007 at 01:29:46PM +0200, Alex Riesen wrote:\n> > On 3/29/07, Tom Prince <tom.prince@ualberta.net> wrote:\n> > >I have been keeping my Maildir in git, a non-trivial merge that causes a\n> > >segfault in git-merge-recursive.\n> > >\n> > >It does not appear to matter which direction I try to merge.\n> > >\n> >\n> > BTW, what git do you have? git --version?\n>\n> 1.5.1.rc3\n>\n\nDid it crash before? If it didn't, is it possible for you to bisect\nthe commit which caused the problem?\n"},{"id":"38313","messageId":"20070329141230.GB16739@hermes","threadId":"7466","inReplyTo":"81b0412b0703290634j6e62ba89tce3c8c963be3fb92@mail.gmail.com","subject":"Re: SEGV in git-merge recursive:","fromName":"Tom Prince","fromEmail":"tom.prince@ualberta.net","sentAt":"2007-03-29T14:12:30Z","receivedAt":"2007-03-29T14:12:30Z","isPatch":false,"sender":{"key":"tom.prince@ualberta.net","avatar":"https://gravatar.com/avatar/a0ad19caee7618876339485106ec994f5202505eecd210ba5c0bd869feaa555a?d=mp&s=160"},"body":"On Thu, Mar 29, 2007 at 03:34:00PM +0200, Alex Riesen wrote:\n> On 3/29/07, Tom Prince <tom.prince@ualberta.net> wrote:\n> >On Thu, Mar 29, 2007 at 01:29:46PM +0200, Alex Riesen wrote:\n> >> On 3/29/07, Tom Prince <tom.prince@ualberta.net> wrote:\n> >> >I have been keeping my Maildir in git, a non-trivial merge that causes a\n> >> >segfault in git-merge-recursive.\n> >> >\n> >> >It does not appear to matter which direction I try to merge.\n> >> >\n> >>\n> >> BTW, what git do you have? git --version?\n> >\n> >1.5.1.rc3\n> >\n> \n> Did it crash before? If it didn't, is it possible for you to bisect\n> the commit which caused the problem?\n\nIt occurs running\n\ngit merge -s recur test HEAD merge\n\nwith\n\n6c711269d4e49072703255ce29bd4d8c53e4f4ba\n\nwhich introduced the C version of merge-recursive.\n\nHere is the output from that more verbose version:\n\nMerging HEAD with 0134d595adb023841750f1ce84ecb94dd4e4c9cb\nMerging:\n922ee6e3f1222c8e171e6ea0b6ac0f28fb1f0683 Mail.\n0134d595adb023841750f1ce84ecb94dd4e4c9cb Mail.\nfound 2 common ancestor(s):\n29e722de58df3cd82600fa5215ec26f80a8c0f9a Mail.\n2c3490d82610d12d8dfde36b29c4ec5a50955b89 Mail.\n  Merging:\n  29e722de58df3cd82600fa5215ec26f80a8c0f9a Mail.\n  2c3490d82610d12d8dfde36b29c4ec5a50955b89 Mail.\n  found 1 common ancestor(s):\n  e2123cfd9a53e441c7c715627953606c6093e0e4 Merge commit 'origin'\n  CONFLICT (rename/rename): Rename .drafts/new/1175001142.P509Q1.hermes->.mom/cur/1175098106.P18146Q0M209985.socrates:2,S in branch Temporary merge branch 1 rename .drafts/new/1175001142.P509Q1.hermes->.drafts/cur/1175001142.P509Q1.hermes:2, in Temporary merge branch 2\n/Users/cougar/local/bin/git-merge: line 311: 25426 Segmentation fault      git-merge-$strategy $common -- \"$head_arg\" \"$@\"\nNo merge strategy handled the merge.\n\n\n-- \n  Tom\n"},{"id":"38316","messageId":"81b0412b0703290744h34b6ef01s4e6f90b1d7ed231b@mail.gmail.com","threadId":"7466","inReplyTo":"20070329141230.GB16739@hermes","subject":"Re: SEGV in git-merge recursive:","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-03-29T14:44:51Z","receivedAt":"2007-03-29T14:44:51Z","isPatch":false,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"On 3/29/07, Tom Prince <tom.prince@ualberta.net> wrote:\n> > Did it crash before? If it didn't, is it possible for you to bisect\n> > the commit which caused the problem?\n>\n> It occurs running\n>\n> git merge -s recur test HEAD merge\n>\n> with\n>\n> 6c711269d4e49072703255ce29bd4d8c53e4f4ba\n>\n> which introduced the C version of merge-recursive.\n\nSo, it _always_ crashed for you.\n\n> Here is the output from that more verbose version:\n>\n> Merging HEAD with 0134d595adb023841750f1ce84ecb94dd4e4c9cb\n> Merging:\n> 922ee6e3f1222c8e171e6ea0b6ac0f28fb1f0683 Mail.\n> 0134d595adb023841750f1ce84ecb94dd4e4c9cb Mail.\n> found 2 common ancestor(s):\n> 29e722de58df3cd82600fa5215ec26f80a8c0f9a Mail.\n> 2c3490d82610d12d8dfde36b29c4ec5a50955b89 Mail.\n>   Merging:\n>   29e722de58df3cd82600fa5215ec26f80a8c0f9a Mail.\n>   2c3490d82610d12d8dfde36b29c4ec5a50955b89 Mail.\n>   found 1 common ancestor(s):\n>   e2123cfd9a53e441c7c715627953606c6093e0e4 Merge commit 'origin'\n>   CONFLICT (rename/rename): Rename .drafts/new/1175001142.P509Q1.hermes->.mom/cur/1175098106.P18146Q0M209985.socrates:2,S in branch Temporary merge branch 1 rename .drafts/new/1175001142.P509Q1.hermes->.drafts/cur/1175001142.P509Q1.hermes:2, in Temporary merge branch 2\n\nRename conflict... Will see, if I can reproduce it without your repo.\nIn the mean time, how about\n\n> /Users/cougar/local/bin/git-merge: line 311: 25426 Segmentation fault      git-merge-$strategy $common -- \"$head_arg\" \"$@\"\n> No merge strategy handled the merge.\n\nIs it MacOSX, by any chance? On 64bit? just collating data\n"},{"id":"38317","messageId":"81b0412b0703290745n63eca3acn3b8dd271194c20fe@mail.gmail.com","threadId":"7466","inReplyTo":"81b0412b0703290744h34b6ef01s4e6f90b1d7ed231b@mail.gmail.com","subject":"Re: SEGV in git-merge recursive:","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-03-29T14:45:30Z","receivedAt":"2007-03-29T14:45:30Z","isPatch":false,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"On 3/29/07, Alex Riesen <raa.lkml@gmail.com> wrote:\n>\n> Rename conflict... Will see, if I can reproduce it without your repo.\n> In the mean time, how about\n>\n\nYes, how about -O0 -ggdb stack trace?\n"},{"id":"38318","messageId":"20070329150423.GD16739@hermes","threadId":"7466","inReplyTo":"81b0412b0703290745n63eca3acn3b8dd271194c20fe@mail.gmail.com","subject":"Re: SEGV in git-merge recursive:","fromName":"Tom Prince","fromEmail":"tom.prince@ualberta.net","sentAt":"2007-03-29T15:04:23Z","receivedAt":"2007-03-29T15:04:23Z","isPatch":false,"sender":{"key":"tom.prince@ualberta.net","avatar":"https://gravatar.com/avatar/a0ad19caee7618876339485106ec994f5202505eecd210ba5c0bd869feaa555a?d=mp&s=160"},"body":"On Thu, Mar 29, 2007 at 04:45:30PM +0200, Alex Riesen wrote:\n> On 3/29/07, Alex Riesen <raa.lkml@gmail.com> wrote:\n> >\n> >Rename conflict... Will see, if I can reproduce it without your repo.\n> >In the mean time, how about\n> >\n\nThis is no x86_64.\n> \n> Yes, how about -O0 -ggdb stack trace?\n\n#0  0x00002ac9f9029cc2 in memcmp () from /System/Links/Libraries/libc.so.6\n#1  0x0000000000402fbc in hashcmp (sha1=0x4 <Address 0x4 out of bounds>,\n    sha2=0x570cdc \"�6Cq�\\234�w:0T��\\177�\\023p\\214Q,\") at cache.h:260\n#2  0x0000000000402f84 in sha_eq (a=0x4 <Address 0x4 out of bounds>, b=0x570cdc \"�6Cq�\\234�w:0T��\\177�\\023p\\214Q,\")\n    at merge-recursive.c:53\n#3  0x0000000000405eda in merge_trees (head=0x570cb0, merge=0x570cd8, common=0x0, branch1=0x7fffb1f6427b \"HEAD\",\n    branch2=0x7fffb1f64e6d \"merge\", result=0x7fffb1f63ce8) at merge-recursive.c:1115\n#4  0x000000000040635f in merge (h1=0x560ca0, h2=0x560d20, branch1=0x7fffb1f6427b \"HEAD\",\n    branch2=0x7fffb1f64e6d \"merge\", ca=0x55f590, result=0x7fffb1f63d70) at merge-recursive.c:1249\n#5  0x0000000000406826 in main (argc=6, argv=0x7fffb1f63e88) at merge-recursive.c:1362\n"},{"id":"38319","messageId":"81b0412b0703290804n13af6f40we79f7251562c540@mail.gmail.com","threadId":"7466","inReplyTo":"81b0412b0703290744h34b6ef01s4e6f90b1d7ed231b@mail.gmail.com","subject":"Re: SEGV in git-merge recursive:","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-03-29T15:04:31Z","receivedAt":"2007-03-29T15:04:31Z","isPatch":false,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"On 3/29/07, Alex Riesen <raa.lkml@gmail.com> wrote:\n> > Here is the output from that more verbose version:\n> >\n> > Merging HEAD with 0134d595adb023841750f1ce84ecb94dd4e4c9cb\n> > Merging:\n> > 922ee6e3f1222c8e171e6ea0b6ac0f28fb1f0683 Mail.\n> > 0134d595adb023841750f1ce84ecb94dd4e4c9cb Mail.\n> > found 2 common ancestor(s):\n> > 29e722de58df3cd82600fa5215ec26f80a8c0f9a Mail.\n> > 2c3490d82610d12d8dfde36b29c4ec5a50955b89 Mail.\n> >   Merging:\n> >   29e722de58df3cd82600fa5215ec26f80a8c0f9a Mail.\n> >   2c3490d82610d12d8dfde36b29c4ec5a50955b89 Mail.\n> >   found 1 common ancestor(s):\n> >   e2123cfd9a53e441c7c715627953606c6093e0e4 Merge commit 'origin'\n> >   CONFLICT (rename/rename): Rename .drafts/new/1175001142.P509Q1.hermes->.mom/cur/1175098106.P18146Q0M209985.socrates:2,S in branch Temporary merge branch 1 rename .drafts/new/1175001142.P509Q1.hermes->.drafts/cur/1175001142.P509Q1.hermes:2, in Temporary merge branch 2\n>\n> Rename conflict... Will see, if I can reproduce it without your repo.\n\nI failed to reproduce it. My attempt attached (that's for your\nreference pleasure, Dscho).\nThe output was:\n\nGIT_MERGE_VERBOSITY=99 git merge B\nMerging HEAD with B\nMerging:\n18d0538 rename\nd4badb1 rename\nfound 2 common ancestor(s):\n962b369 change\n9cc8ebd change\n  Merging:\n  962b369 change\n  9cc8ebd change\n  found 1 common ancestor(s):\n  a46f64f init\nCONFLICT (rename/rename): Rename 1->a in branch HEAD rename 1->b in B\nAutomatic merge failed; fix conflicts and then commit the result.\n\nTom, either the stack trace of -O0 -ggdb or your repo is badly needed.\nThe stack preferred, as I have that feeling it'll just work everywhere\nelse but your system (can you try it somewhere else, BTW?).\n"},{"id":"38340","messageId":"20070329183237.GB2809@steel.home","threadId":"7466","inReplyTo":"81b0412b0703290804n13af6f40we79f7251562c540@mail.gmail.com","subject":"Re: SEGV in git-merge recursive:","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-03-29T18:32:37Z","receivedAt":"2007-03-29T18:32:37Z","isPatch":false,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"Alex Riesen, Thu, Mar 29, 2007 17:04:31 +0200:\n> CONFLICT (rename/rename): Rename 1->a in branch HEAD rename 1->b in B\n> Automatic merge failed; fix conflicts and then commit the result.\n> \n> Tom, either the stack trace of -O0 -ggdb or your repo is badly needed.\n> The stack preferred, as I have that feeling it'll just work everywhere\n> else but your system (can you try it somewhere else, BTW?).\n\nOk-key... Thanks Tom, for the testcase. I believe we haven't had this\none yet: the merge base in the second (inner) merge is the initial\ncommit. Which is strange:\n\n(gdb) p *merged_common_ancestors\n$4 = {\n  object = {\n    parsed = 1,\n    used = 0,\n    type = 0,\n    flags = 0,\n    sha1 = \"\\001\", '\\0' <repeats 18 times>\n  },\n  util = 0x8082b40,\n  date = 0,\n  parents = 0x8ff5180,\n  tree = 0x0,\n  buffer = 0x0\n}\n\ntree == 0x0? Strange, I don't get why it is NULL, the initial commit\ndefinitely hase a tree (git cat-file -p initial-commit shows a tree\nname and there is a tree with that object name).\n\nThe structure looks like this:\n\n    o---o-o-o---o-o-o-o-o\n     \\   ____\\_/\n      \\ /     \\\n       o-------o-o-o-o\n\nFsck reports no errors.\nStill looking into it.\n"},{"id":"38341","messageId":"20070329185501.GC2809@steel.home","threadId":"7466","inReplyTo":"20070329183237.GB2809@steel.home","subject":"Re: SEGV in git-merge recursive:","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-03-29T18:55:01Z","receivedAt":"2007-03-29T18:55:01Z","isPatch":false,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"Alex Riesen, Thu, Mar 29, 2007 20:32:37 +0200:\n> \n> The structure looks like this:\n> \n>     o---o-o-o---o-o-o-o-o\n>      \\   ____\\_/\n>       \\ /     \\\n>        o-------o-o-o-o\n> \n\nAnd this is a repo (reconstructed, not the original, of course) which\nshows the problem. Just run \"git merge merge\" while on master.\n\n"},{"id":"38342","messageId":"Pine.LNX.4.64.0703291232190.6730@woody.linux-foundation.org","threadId":"7466","inReplyTo":"20070329183237.GB2809@steel.home","subject":"Re: SEGV in git-merge recursive:","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-03-29T19:34:49Z","receivedAt":"2007-03-29T19:34:49Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Thu, 29 Mar 2007, Alex Riesen wrote:\n> \n> tree == 0x0? Strange, I don't get why it is NULL, the initial commit\n> definitely hase a tree (git cat-file -p initial-commit shows a tree\n> name and there is a tree with that object name).\n\nIt's not the initial commit. It's a criss-cross merge, and it's a virtual \ncommit created by a previous level of merging.\n\nApply this patch to see it blow up much earlier, when that bogus commit \nwith a NULL tree is created.\n\n(I didn't debug *why* that happens, but maybe this gets somebody further)\n\n\t\tLinus\n\n---\n merge-recursive.c |    1 +\n 1 files changed, 1 insertions(+), 0 deletions(-)\n\ndiff --git a/merge-recursive.c b/merge-recursive.c\nindex c96e1a7..28f0c30 100644\n--- a/merge-recursive.c\n+++ b/merge-recursive.c\n@@ -34,6 +34,7 @@ static struct commit *make_virtual_commit(struct tree *tree, const char *comment\n {\n \tstruct commit *commit = xcalloc(1, sizeof(struct commit));\n \tstatic unsigned virtual_id = 1;\n+\tassert(tree);\n \tcommit->tree = tree;\n \tcommit->util = (void*)comment;\n \t*(int*)commit->object.sha1 = virtual_id++;\n"},{"id":"38343","messageId":"Pine.LNX.4.64.0703291237240.6730@woody.linux-foundation.org","threadId":"7466","inReplyTo":"Pine.LNX.4.64.0703291232190.6730@woody.linux-foundation.org","subject":"Re: SEGV in git-merge recursive:","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-03-29T19:40:53Z","receivedAt":"2007-03-29T19:40:53Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Thu, 29 Mar 2007, Linus Torvalds wrote:\n> \n> It's not the initial commit. It's a criss-cross merge, and it's a virtual \n> commit created by a previous level of merging.\n> \n> Apply this patch to see it blow up much earlier, when that bogus commit \n> with a NULL tree is created.\n> \n> (I didn't debug *why* that happens, but maybe this gets somebody further)\n\nWell, it happens because \"git_write_tree()\" returns NULL. Which in turn is \nbecause \"unmerged_index()\" returns true. \n\nmerge_trees() tries to clean up the unmerged index, but apparently doesn't \ndo good enough of a job, so git_write_tree() is called with entries still \nunmerged..\n\n\t\tLinus\n"},{"id":"38344","messageId":"20070329195546.GB8830@hermes","threadId":"7466","inReplyTo":"20070329183237.GB2809@steel.home","subject":"Re: SEGV in git-merge recursive:","fromName":"Tom Prince","fromEmail":"tom.prince@ualberta.net","sentAt":"2007-03-29T19:55:46Z","receivedAt":"2007-03-29T19:55:46Z","isPatch":false,"sender":{"key":"tom.prince@ualberta.net","avatar":"https://gravatar.com/avatar/a0ad19caee7618876339485106ec994f5202505eecd210ba5c0bd869feaa555a?d=mp&s=160"},"body":"On Thu, Mar 29, 2007 at 08:32:37PM +0200, Alex Riesen wrote:\n> Alex Riesen, Thu, Mar 29, 2007 17:04:31 +0200:\n> > CONFLICT (rename/rename): Rename 1->a in branch HEAD rename 1->b in B\n> > Automatic merge failed; fix conflicts and then commit the result.\n> > \n> > Tom, either the stack trace of -O0 -ggdb or your repo is badly needed.\n> > The stack preferred, as I have that feeling it'll just work everywhere\n> > else but your system (can you try it somewhere else, BTW?).\n> \n> Ok-key... Thanks Tom, for the testcase. I believe we haven't had this\n> one yet: the merge base in the second (inner) merge is the initial\n> commit. Which is strange:\n\nThe actual case that caused the error didn't have the initial commit, I\nused cg-admin-rewritehist to create a (slightly) smaller test case that\nexhibited the behavior.\n\n  Tom\n"},{"id":"38348","messageId":"20070329204458.GD2809@steel.home","threadId":"7466","inReplyTo":"Pine.LNX.4.64.0703291237240.6730@woody.linux-foundation.org","subject":"Re: SEGV in git-merge recursive:","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-03-29T20:44:58Z","receivedAt":"2007-03-29T20:44:58Z","isPatch":false,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"Linus Torvalds, Thu, Mar 29, 2007 21:40:53 +0200:\n> \n> \n> On Thu, 29 Mar 2007, Linus Torvalds wrote:\n> > \n> > It's not the initial commit. It's a criss-cross merge, and it's a virtual \n> > commit created by a previous level of merging.\n> > \n> > Apply this patch to see it blow up much earlier, when that bogus commit \n> > with a NULL tree is created.\n> > \n> > (I didn't debug *why* that happens, but maybe this gets somebody further)\n> \n> Well, it happens because \"git_write_tree()\" returns NULL. Which in turn is \n> because \"unmerged_index()\" returns true. \n\nwhich in turn is because the inner merge has a rename/rename conflict.\nSee the repo in the tarball from <20070329185501.GC2809@steel.home>\n\n> merge_trees() tries to clean up the unmerged index, but apparently doesn't \n> do good enough of a job, so git_write_tree() is called with entries still \n> unmerged..\n\nI see no \"job\" at all: no index cleanup there (merge_trees).\n"},{"id":"38366","messageId":"20070329230156.GE2809@steel.home","threadId":"7466","inReplyTo":"20070329185501.GC2809@steel.home","subject":"[PATCH] An attempt to resolve a rename/rename conflict in recursive merge","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-03-29T23:01:56Z","receivedAt":"2007-03-29T23:01:56Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"The structure looks like this:\n\n     o---A-o-o---o-o-o-o-AA\n      \\   ____\\_/\n       \\ /     \\\n        B-------o-o-o-BB\n\nThere is a rename/rename conflict somewhere around A and B commits.\nThe conflict was resolved at the merge points. Now, the problem is\nthat when the merge-recursive generates that virtual merge there seem\nto be no way to get to the resolved state. The ends up resolving the\nconflict again, and of course does not do it without intelligent help,\nleaving index with unresolved entries. git_write_tree fails, returning\nNULL and the rest breaks.\n\nI just left all three entries in the index for the virtual commit to\npick them up: it'll usually(always?) generate a conflict which has to\nbe resolved manually. Many times, perhaps.\n\nThe small change in git_write_tree() was useful to see the relevant\nportion of the index. The output in rename/rename conflict handling\ncode modified to improve its readability: it can be a lot of text.\n\n---\n merge-recursive.c |   37 +++++++++++++++++++++++++++++++------\n 1 files changed, 31 insertions(+), 6 deletions(-)\n\ndiff --git a/merge-recursive.c b/merge-recursive.c\nindex c96e1a7..2568c4e 100644\n--- a/merge-recursive.c\n+++ b/merge-recursive.c\n@@ -278,8 +278,16 @@ static struct tree *git_write_tree(void)\n {\n \tstruct tree *result = NULL;\n \n-\tif (unmerged_index())\n+\tif (unmerged_index()) {\n+\t\toutput(0, \"There are unmerged index entries:\");\n+\t\tint i;\n+\t\tfor (i = 0; i < active_nr; i++) {\n+\t\t\tstruct cache_entry *ce = active_cache[i];\n+\t\t\tif (ce_stage(ce))\n+\t\t\t\toutput(0, \"%d %.*s\", ce_stage(ce), ce_namelen(ce), ce->name);\n+\t\t}\n \t\treturn NULL;\n+\t}\n \n \tif (!active_cache_tree)\n \t\tactive_cache_tree = cache_tree();\n@@ -735,8 +743,17 @@ static void conflict_rename_rename(struct rename *ren1,\n \t\t       ren2_dst, branch1, dst_name2);\n \t\tremove_file(0, ren2_dst, 0);\n \t}\n-\tupdate_stages(dst_name1, NULL, ren1->pair->two, NULL, 1);\n-\tupdate_stages(dst_name2, NULL, NULL, ren2->pair->two, 1);\n+\tif (index_only) {\n+\t\tremove_file_from_cache(dst_name1);\n+\t\tremove_file_from_cache(dst_name2);\n+\t\tadd_cacheinfo(ren1->pair->two->mode, ren1->pair->two->sha1, dst_name1,\n+\t\t\t      0, 0, ADD_CACHE_OK_TO_ADD);\n+\t\tadd_cacheinfo(ren1->pair->two->mode, ren2->pair->two->sha1, dst_name2,\n+\t\t\t      0, 0, ADD_CACHE_OK_TO_ADD);\n+\t} else {\n+\t\tupdate_stages(dst_name1, NULL, ren1->pair->two, NULL, 1);\n+\t\tupdate_stages(dst_name2, NULL, NULL, ren2->pair->two, 1);\n+\t}\n \twhile (delp--)\n \t\tfree(del[delp]);\n }\n@@ -852,10 +869,18 @@ static int process_renames(struct path_list *a_renames,\n \t\t\tif (strcmp(ren1_dst, ren2_dst) != 0) {\n \t\t\t\tclean_merge = 0;\n \t\t\t\toutput(1, \"CONFLICT (rename/rename): \"\n-\t\t\t\t       \"Rename %s->%s in branch %s \"\n-\t\t\t\t       \"rename %s->%s in %s\",\n+\t\t\t\t       \"Rename \\\"%s\\\"->\\\"%s\\\" in branch \\\"%s\\\" \"\n+\t\t\t\t       \"rename \\\"%s\\\"->\\\"%s\\\" in \\\"%s\\\"%s\",\n \t\t\t\t       src, ren1_dst, branch1,\n-\t\t\t\t       src, ren2_dst, branch2);\n+\t\t\t\t       src, ren2_dst, branch2,\n+\t\t\t\t       index_only ? \" (left unresolved)\": \"\");\n+\t\t\t\tif (index_only) {\n+\t\t\t\t\tremove_file_from_cache(src);\n+\t\t\t\t\tadd_cacheinfo(ren1->pair->one->mode,\n+\t\t\t\t\t\t      ren1->pair->one->sha1,\n+\t\t\t\t\t\t      src,\n+\t\t\t\t\t\t      0, 0, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE);\n+\t\t\t\t}\n \t\t\t\tconflict_rename_rename(ren1, branch1, ren2, branch2);\n \t\t\t} else {\n \t\t\t\tstruct merge_file_info mfi;\n-- \n1.5.1.rc2.18.g157b4\n"},{"id":"38368","messageId":"20070329231308.GF2809@steel.home","threadId":"7466","inReplyTo":"20070329230156.GE2809@steel.home","subject":"Re: [PATCH] An attempt to resolve a rename/rename conflict in recursive merge","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-03-29T23:13:08Z","receivedAt":"2007-03-29T23:13:08Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"Alex Riesen, Fri, Mar 30, 2007 01:01:56 +0200:\n> \n> I just left all three entries in the index for the virtual commit to\n> pick them up: it'll usually(always?) generate a conflict which has to\n> be resolved manually. Many times, perhaps.\n> \n\nNah, doesn't do anything good. Does not crash, though.\n"},{"id":"38416","messageId":"Pine.LNX.4.63.0703302239050.4045@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"7466","inReplyTo":"Pine.LNX.4.64.0703291237240.6730@woody.linux-foundation.org","subject":"Re: SEGV in git-merge recursive:","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-03-30T21:00:43Z","receivedAt":"2007-03-30T21:00:43Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Thu, 29 Mar 2007, Linus Torvalds wrote:\n\n> On Thu, 29 Mar 2007, Linus Torvalds wrote:\n> \n> > It's not the initial commit. It's a criss-cross merge, and it's a \n> > virtual commit created by a previous level of merging.\n> > \n> > Apply this patch to see it blow up much earlier, when that bogus \n> > commit with a NULL tree is created.\n> > \n> > (I didn't debug *why* that happens, but maybe this gets somebody \n> > further)\n> \n> Well, it happens because \"git_write_tree()\" returns NULL. Which in turn \n> is because \"unmerged_index()\" returns true.\n> \n> merge_trees() tries to clean up the unmerged index, but apparently \n> doesn't do good enough of a job, so git_write_tree() is called with \n> entries still unmerged..\n\nActually, this is not the complete truth.\n\nThis particular case has a conflicting rename/rename in an _intermediate_ \ncommit. This _cannot_ be resolved automatically, not even by putting \nconflict markers into the appropriate files (*1*).\n\nIMHO, there is actually no way merge_trees() can fix the conflicts enough \nto write a tree.\n\nSo, the only way I see to avoid that SEGV is to something like this:\n\ndiff --git a/merge-recursive.c b/merge-recursive.c\nindex ece2238..cbc39e9 100644\n--- a/merge-recursive.c\n+++ b/merge-recursive.c\n@@ -1135,8 +1135,13 @@ static int merge_trees(struct tree *head,\n \telse\n \t\tclean = 1;\n \n-\tif (index_only)\n+\tif (index_only) {\n \t\t*result = git_write_tree();\n+\t\tif (!*result) {\n+\t\t\tflush_output();\n+\t\t\tdie (\"cannot continue merging.\");\n+\t\t}\n+\t}\n \n \treturn clean;\n }\n\nNOTE: I will not make the error again _not_ to point out that this is \n_just_ a hint at what a proper patch would look like.\n\nFor example, a proper patch would include a test case, _and_ would print a \nproper hint about GIT_MERGE_VERBOSITY (otherwise, you will only get a \nfatal error \"cannot continue merging\", without any hint about what went \nwrong).\n\nCiao,\nDscho\n\n*1* I played with the idea to do a threeway merge of the conflicting files \n(src->dst1,dst2, using src as common version), but I am not quite sure if \nit is worth the confusion it seeds.\n\nBesides, there is another type of rename/rename conflict, which _cannot_ \nbe solved in that manner: (src1,src2->dst). And for this case, we have to \nhave a sane way out anyway.\n"},{"id":"38394","messageId":"Pine.LNX.4.64.0703301728510.6730@woody.linux-foundation.org","threadId":"7466","inReplyTo":"Pine.LNX.4.63.0703302239050.4045@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: SEGV in git-merge recursive:","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-03-31T00:35:51Z","receivedAt":"2007-03-31T00:35:51Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Fri, 30 Mar 2007, Johannes Schindelin wrote:\n> \n> IMHO, there is actually no way merge_trees() can fix the conflicts enough \n> to write a tree.\n> \n> So, the only way I see to avoid that SEGV is to something like this:\n\nI disagree.\n\nIt's much better to give a bad intermediate tree than to give up entirely.\n\nIf you give up entirely, the merge is basically impossible to complete.\n\nIf you give a bad intermediate, the merge will just have potentially \nmore-than-necessary conflicts in the end.\n\n> +\t\t\tdie (\"cannot continue merging.\");\n\nThis really isn't acceptable. We're not monotone or one of those projects \nthat thinks that merging is hard. Merging is *easy*.\n\nWe're looking for a base version for a merge - think of a three-way merge \non a file level. And the easiest base version is actually an empty base \nfile (or, when it comes to a rename conflict, no base names at all).\n\nSure, that will make all changes conflict, but that's a *hell* of a lot \nbetter than giving up. It just means that now the user has to figure out \nwhat the end result should be - exactly the same way that if you have an \nempty file as a base version, a three-way merge will basically generate a \nconflict marker that looks like\n\n\t<<<<\n\tone version of the file\n\t====\n\tthe other version of the file\n\t>>>>\n\nRule #1 when merging should *always* be: \"never leave the user high and \ndry\". You don't give up and say \"I can't merge this\". You say \"I couldn't \nmerge this, but here's the mess I left for you to show me how it's done!\"\n\n\t\tLinus\n"},{"id":"38397","messageId":"Pine.LNX.4.64.0703301754590.6730@woody.linux-foundation.org","threadId":"7466","inReplyTo":"Pine.LNX.4.64.0703301728510.6730@woody.linux-foundation.org","subject":"Re: SEGV in git-merge recursive:","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-03-31T01:03:36Z","receivedAt":"2007-03-31T01:03:36Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Fri, 30 Mar 2007, Linus Torvalds wrote:\n> \n> We're looking for a base version for a merge - think of a three-way merge \n> on a file level. And the easiest base version is actually an empty base \n> file (or, when it comes to a rename conflict, no base names at all).\n\nNote that \"easiest\" isn't \"best\".\n\nFor data conflicts in intermediate merges, we use the conficted file, \nconflict markers and all, as the base.\n\nI suspect we should do exactly the same for filename conflicts. Write the \nintermediate tree with *both* files, including conflict markers. I'd \nsuggest writing out the conflicting names to the intermediate tree \n*exactly* the same way we do for the final tree in the working tree, but \nmayne we could just write them with the SHA of the content appended to the \nfilename or something..)\n\n\t\tLinus\n"},{"id":"38423","messageId":"20070331104947.GA4377@steel.home","threadId":"7466","inReplyTo":"Pine.LNX.4.64.0703301754590.6730@woody.linux-foundation.org","subject":"Re: SEGV in git-merge recursive:","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-03-31T10:49:47Z","receivedAt":"2007-03-31T10:49:47Z","isPatch":false,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"Linus Torvalds, Sat, Mar 31, 2007 03:03:36 +0200:\n> > \n> > We're looking for a base version for a merge - think of a three-way merge \n> > on a file level. And the easiest base version is actually an empty base \n> > file (or, when it comes to a rename conflict, no base names at all).\n> \n> Note that \"easiest\" isn't \"best\".\n> \n> For data conflicts in intermediate merges, we use the conficted file, \n> conflict markers and all, as the base.\n> \n> I suspect we should do exactly the same for filename conflicts. Write the \n> intermediate tree with *both* files, including conflict markers. I'd \n> suggest writing out the conflicting names to the intermediate tree \n> *exactly* the same way we do for the final tree in the working tree, but \n> mayne we could just write them with the SHA of the content appended to the \n> filename or something..)\n> \n\nThe names are already different (base->a, base->b), what is the SHA for?\nI tried leaving all three names in the computed tree (base, a and b).\nThe result is sometimes spectacular, but seldom useful.\n"},{"id":"38425","messageId":"Pine.LNX.4.63.0703311319190.4045@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"7466","inReplyTo":"Pine.LNX.4.64.0703301728510.6730@woody.linux-foundation.org","subject":"Re: SEGV in git-merge recursive:","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-03-31T11:22:27Z","receivedAt":"2007-03-31T11:22:27Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Fri, 30 Mar 2007, Linus Torvalds wrote:\n\n> On Fri, 30 Mar 2007, Johannes Schindelin wrote:\n> \n> > IMHO, there is actually no way merge_trees() can fix the conflicts \n> > enough to write a tree.\n> > \n> > So, the only way I see to avoid that SEGV is to something like this:\n> \n> I disagree.\n> \n> It's much better to give a bad intermediate tree than to give up entirely.\n\nHmm.\n\nWhat we _could_ do: if the index still contains unmerged entries, then we \ncollapse these into files with conflict markers (in case the file cannot \nbe written, because a directory of the same name exists, we have to save \nwith a unique name, complaining loudly about it, i.e. without using \noutput()).\n\nI will not have time to implement this until later this week, though.\n\nCiao,\nDscho\n"},{"id":"38427","messageId":"20070331114938.GB4377@steel.home","threadId":"7466","inReplyTo":"20070331104947.GA4377@steel.home","subject":"[PATCH] Keep rename/rename conflicts of intermediate merges while doing recursive merge","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-03-31T11:49:38Z","receivedAt":"2007-03-31T11:49:38Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"This patch leaves the base name in the resulting intermediate tree, to\npropagate the conflict from intermediate merges up to the top-level merge.\n---\n\nThe result seem to be at least predictable. Still, doesn't it mean\nthat once a rename/rename conflict is in it has to be resolved\nmanually forever?\n\n merge-recursive.c |   37 +++++++++++++++++++++++++++++++------\n 1 files changed, 31 insertions(+), 6 deletions(-)\n\ndiff --git a/merge-recursive.c b/merge-recursive.c\nindex c96e1a7..080b714 100644\n--- a/merge-recursive.c\n+++ b/merge-recursive.c\n@@ -278,8 +278,16 @@ static struct tree *git_write_tree(void)\n {\n \tstruct tree *result = NULL;\n \n-\tif (unmerged_index())\n+\tif (unmerged_index()) {\n+\t\toutput(0, \"There are unmerged index entries:\");\n+\t\tint i;\n+\t\tfor (i = 0; i < active_nr; i++) {\n+\t\t\tstruct cache_entry *ce = active_cache[i];\n+\t\t\tif (ce_stage(ce))\n+\t\t\t\toutput(0, \"%d %.*s\", ce_stage(ce), ce_namelen(ce), ce->name);\n+\t\t}\n \t\treturn NULL;\n+\t}\n \n \tif (!active_cache_tree)\n \t\tactive_cache_tree = cache_tree();\n@@ -735,8 +743,19 @@ static void conflict_rename_rename(struct rename *ren1,\n \t\t       ren2_dst, branch1, dst_name2);\n \t\tremove_file(0, ren2_dst, 0);\n \t}\n-\tupdate_stages(dst_name1, NULL, ren1->pair->two, NULL, 1);\n-\tupdate_stages(dst_name2, NULL, NULL, ren2->pair->two, 1);\n+\tif (index_only) {\n+\t\tremove_file_from_cache(dst_name1);\n+\t\tremove_file_from_cache(dst_name2);\n+\t\t/*\n+\t\t * Uncomment to leave the conflicting names in the resulting tree\n+\t\t *\n+\t\t * update_file(0, ren1->pair->two->sha1, ren1->pair->two->mode, dst_name1);\n+\t\t * update_file(0, ren2->pair->two->sha1, ren2->pair->two->mode, dst_name2);\n+\t\t */\n+\t} else {\n+\t\tupdate_stages(dst_name1, NULL, ren1->pair->two, NULL, 1);\n+\t\tupdate_stages(dst_name2, NULL, NULL, ren2->pair->two, 1);\n+\t}\n \twhile (delp--)\n \t\tfree(del[delp]);\n }\n@@ -852,10 +871,16 @@ static int process_renames(struct path_list *a_renames,\n \t\t\tif (strcmp(ren1_dst, ren2_dst) != 0) {\n \t\t\t\tclean_merge = 0;\n \t\t\t\toutput(1, \"CONFLICT (rename/rename): \"\n-\t\t\t\t       \"Rename %s->%s in branch %s \"\n-\t\t\t\t       \"rename %s->%s in %s\",\n+\t\t\t\t       \"Rename \\\"%s\\\"->\\\"%s\\\" in branch \\\"%s\\\" \"\n+\t\t\t\t       \"rename \\\"%s\\\"->\\\"%s\\\" in \\\"%s\\\"%s\",\n \t\t\t\t       src, ren1_dst, branch1,\n-\t\t\t\t       src, ren2_dst, branch2);\n+\t\t\t\t       src, ren2_dst, branch2,\n+\t\t\t\t       index_only ? \" (left unresolved)\": \"\");\n+\t\t\t\tif (index_only) {\n+\t\t\t\t\tremove_file_from_cache(src);\n+\t\t\t\t\tupdate_file(0, ren1->pair->one->sha1,\n+\t\t\t\t\t\t    ren1->pair->one->mode, src);\n+\t\t\t\t}\n \t\t\t\tconflict_rename_rename(ren1, branch1, ren2, branch2);\n \t\t\t} else {\n \t\t\t\tstruct merge_file_info mfi;\n-- \n1.5.1.rc2.38.g8d5bf-dirty\n"},{"id":"38429","messageId":"eulimv$369$1@sea.gmane.org","threadId":"7466","inReplyTo":"20070331114938.GB4377@steel.home","subject":"Re: [PATCH] Keep rename/rename conflicts of intermediate merges while doing recursive merge","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2007-03-31T12:06:58Z","receivedAt":"2007-03-31T12:06:58Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Alex Riesen wrote:\n\n> The result seem to be at least predictable. Still, doesn't it mean\n> that once a rename/rename conflict is in it has to be resolved\n> manually forever?\n\nWhat about git-rerere2 idea (recording resolving of tree-level conflicts,\ni.e. rename/rename and such)?\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"38430","messageId":"Pine.LNX.4.63.0703311445190.4045@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"7466","inReplyTo":"20070331114938.GB4377@steel.home","subject":"Re: [PATCH] Keep rename/rename conflicts of intermediate merges while doing recursive merge","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-03-31T12:50:46Z","receivedAt":"2007-03-31T12:50:46Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sat, 31 Mar 2007, Alex Riesen wrote:\n\n> This patch leaves the base name in the resulting intermediate tree, to\n> propagate the conflict from intermediate merges up to the top-level merge.\n\nI'd rather have conflict files, i.e.\n\n\tfor each entry in the index which is unmerged,\n\t\twrite the file in this form:\n\t\t<<<<<<\n\t\t[stage2]\n\t\t======\n\t\t[stage3]\n\t\t>>>>>>\n\n\t\tmark as merged (i.e. remove stages 1--3 from the index, \n\t\tand add the conflicted file as stage 0)\n\nThe big problem is that you _cannot_ leave unmerged entries in \nintermediate stages, because then, you could not write the tree. OTOH, you \n_need_ to mark them as unmerged _in the end_.\n\t\t\nThat problem keeps me from just whipping up a patch in a few minutes, \nsending it untested to the list, and get all the blame for it.\n\nCiao,\nDscho\n"},{"id":"38432","messageId":"Pine.LNX.4.63.0703311452300.4045@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"7466","inReplyTo":"Pine.LNX.4.63.0703311445190.4045@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: [PATCH] Keep rename/rename conflicts of intermediate merges while doing recursive merge","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-03-31T12:53:47Z","receivedAt":"2007-03-31T12:53:47Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sat, 31 Mar 2007, Johannes Schindelin wrote:\n\n> On Sat, 31 Mar 2007, Alex Riesen wrote:\n> \n> > This patch leaves the base name in the resulting intermediate tree, to\n> > propagate the conflict from intermediate merges up to the top-level merge.\n> \n> I'd rather have conflict files, i.e.\n> \n> \tfor each entry in the index which is unmerged,\n> \t\twrite the file in this form:\n> \t\t<<<<<<\n> \t\t[stage2]\n> \t\t======\n> \t\t[stage3]\n> \t\t>>>>>>\n> \n> \t\tmark as merged (i.e. remove stages 1--3 from the index, \n> \t\tand add the conflicted file as stage 0)\n\nSide note: for the \"src->dest1,dest2\" case, I really would like to see a \nthreeway merge. But I would want the above-mentioned behaviour _before_ \nthat, to make sure that we have a reasonable fallback for hard cases.\n\nCiao,\nDscho\n"},{"id":"38440","messageId":"Pine.LNX.4.64.0703310856070.6730@woody.linux-foundation.org","threadId":"7466","inReplyTo":"20070331114938.GB4377@steel.home","subject":"Re: [PATCH] Keep rename/rename conflicts of intermediate merges while doing recursive merge","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-03-31T16:07:56Z","receivedAt":"2007-03-31T16:07:56Z","isPatch":true,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Sat, 31 Mar 2007, Alex Riesen wrote:\n> \n> The result seem to be at least predictable. Still, doesn't it mean\n> that once a rename/rename conflict is in it has to be resolved\n> manually forever?\n\nNo. It means that that particular rename/rename conflict has to be \nresolved *once*, since after that, the new merge will become the \nmerge-base for future merges.\n\nNow, that doesn't mean that you may not end up having that same conflict \nshow up over and over again, because the new merge-base may (obviously) \nend up being a situation where the rename/rename conflict will continue to \nexist later on (because it conflicts with what the repo you pulled from \nwill continue to have), but that's really no different from any other \nconflict..\n\nThe only way to resolve some conflicts in the long run is to either \n - converge on some common case (ie normally by merging both ways \n   eventually, or just try to converge otherwise)\n - remember the conflict resolution and re-doing it automatically (ie \n   \"git rerere\" for rename conflicts)\n\nThat's very fundamental, btw. I don't think there *is* any other way to do \nautomatic merges in the long run, it has nothing to do with this \nparticular issue, it's a generic property of automatic merging.\n\nJunio - I think Alex' patch is better than what we have right now (which \nis dying - whether with a SIGSEGV or a die() doesn't much matter), so it \nshould be applied. It probably isn't perfect, and I bet we can tweak the \nresolution to something much better - Dscho seems to have ideas in that \nareas. But:\n\n\tAcked-by: Linus Torvalds <torvalds@linux-foundation.org>\n\nin the meantime.\n\nOne thing we could/probably should do is to perhaps just add a flag about \n\"intermediate merges had complex issues\", and refuse to commit the result \neven if it looked \"clean\" in the end. It's better to make people perhaps \nhave to do an \"unnecessary\" extra git-commit, than to silently commit \nsomething that might have been mis-merged. Just ask people to \"please \nverify the end result\" kind of thing..\n\n\t\tLinus\n"},{"id":"38442","messageId":"20070331173445.GA7696@steel.home","threadId":"7466","inReplyTo":"Pine.LNX.4.64.0703310856070.6730@woody.linux-foundation.org","subject":"Re: [PATCH] Keep rename/rename conflicts of intermediate merges while doing recursive merge","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-03-31T17:34:45Z","receivedAt":"2007-03-31T17:34:45Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"Linus Torvalds, Sat, Mar 31, 2007 18:07:56 +0200:\n> > \n> > The result seem to be at least predictable. Still, doesn't it mean\n> > that once a rename/rename conflict is in it has to be resolved\n> > manually forever?\n> \n> The only way to resolve some conflicts in the long run is to either \n>  - converge on some common case (ie normally by merging both ways \n>    eventually, or just try to converge otherwise)\n>  - remember the conflict resolution and re-doing it automatically (ie \n>    \"git rerere\" for rename conflicts)\n> \n> That's very fundamental, btw. I don't think there *is* any other way to do \n> automatic merges in the long run, it has nothing to do with this \n> particular issue, it's a generic property of automatic merging.\n> \n> Junio - I think Alex' patch is better than what we have right now (which \n> is dying - whether with a SIGSEGV or a die() doesn't much matter), so it \n> should be applied. It probably isn't perfect, and I bet we can tweak the \n> resolution to something much better - Dscho seems to have ideas in that \n> areas. But:\n> \n> \tAcked-by: Linus Torvalds <torvalds@linux-foundation.org>\n> \n> in the meantime.\n\nSigned-off-by: Alex Riesen <raa.lkml@gmail.com>\n\n> One thing we could/probably should do is to perhaps just add a flag about \n> \"intermediate merges had complex issues\", and refuse to commit the result \n> even if it looked \"clean\" in the end. It's better to make people perhaps \n> have to do an \"unnecessary\" extra git-commit, than to silently commit \n> something that might have been mis-merged. Just ask people to \"please \n> verify the end result\" kind of thing..\n\nThat'd be using the return value of inner merge which we historically\ndo not do. Corresponding comment is in place: \"The cleanness flag is\nignored, it was never actually used, as result of merge_trees has\nalways overwritten it: the committed conflicts were already resolved\".\nSomehow it does not help to understand \"why\" the cleanliness of the\ninner merge does not matter...\n"},{"id":"38447","messageId":"7vwt0xuqn4.fsf@assigned-by-dhcp.cox.net","threadId":"7466","inReplyTo":"20070331114938.GB4377@steel.home","subject":"Re: [PATCH] Keep rename/rename conflicts of intermediate merges while doing recursive merge","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-03-31T20:03:43Z","receivedAt":"2007-03-31T20:03:43Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Alex Riesen <raa.lkml@gmail.com> writes:\n\n> This patch leaves the base name in the resulting intermediate tree, to\n> propagate the conflict from intermediate merges up to the top-level merge.\n> ---\n\nI've eyeballed not your patch but the entire merge-recursive\nagain, to make sure that the codepath you are touching is the\nonly one that can potentially leave higher stages in the index\nfor intermediate merge.  Anything that calls update_file() for\nintermediate merge ends up doing add_cacheinfo() hence drops\nhigher stages for that path, and it seems that the function you\nare changing, conflict_rename_rename, is the only one that\nleaves unmerged entries in the tree, so I think thi is good.\nThe assertion you added to git_write_tree() is good way to catch\nif the above assumption was wrong and we missed other codepaths.\n\n> The result seem to be at least predictable. Still, doesn't it mean\n> that once a rename/rename conflict is in it has to be resolved\n> manually forever?\n\nThat's certainly better than segfaulting, and in my opinion, it\nis much better than silently giving a wrong merge result\nassuming one conflict resolution.\n\nWe've been resolving other cases that we should not usually\nresolve for intermediate merges, leaning on the safer side.  For\nexample, look at what delete/modify does for an intermediate\nmerge.  It leaves the modified contents in the index.\n\nThe reason an intermediate merge conflicts is because the two\nbranches resolved the same (not necessarily \"exactly the same\")\nmerges differently earlier.  That means the two people who made\nthose ancestor merges could not agree on something.  Because\nthey could not agree on, you end up being responsible for\nreconciling their differences in opinion.  I do not think it is\na bad thing -- in fact, I even think it is a good thing.  Forks\ndo not have to converge and you have an opportunity to decide\nwhich side you are on for yourself.\n\nAn illustration.\n\nSuppose there is a project that has incorrect documentation, and\nAlice and Bob worked on it separately.  Alice finds the\ndocumentation's language horrible and makes typofixes, while in\nBob's opinion its contents, even if its language were to be\nimproved, keeping the incorrect documentation spreads\nmisinformation and it is worthless.  Bob deletes the incorrect\ndocumentation and keeps working on other things.\n\n         .------------A1--A2------------A\n        /   modify doc \\ / take \"modify\"\n       /                X  and later improve          \n      /                / \\           \n  ---o---------------B1---B2------------B\n           delete doc     take \"delete\"\n\nIn short, Alice modified and Bob deleted, and reached point A1\nand B1, respectively.\n\nNow Alice pulls from Bob, hand-resolves the delete/modify and\nimproves the contents to make it not just language clean (which\nshe did in the previous steps leading to A1) but technically\naccurate.  She now is at point A2, but haven't pushed her\nchanges out yet.  She continues to work and reaches A\n\nIn the meantime Bob is making further changes to the parts of\nthe system the documentation used to describe.  Bob commits his\nchanges, pulls from Alice's last published one A1, and gets\ndelete/modify conflict in the doc, and he takes the deletion and\nmerge result is B2.  He continues to work and reaches B.\n\nLater Charlie clones from Bob's B, and tries to merge from\nAlice's A.  There are two merge bases (A1 and B1), so an attempt\nto merge the merge bases is made by recursive.  This gives\ndelete/modify conflict.  We leave the modified contents in this\nintermediate \"virtual ancestor\" tree, but the end result is that\nCharlie has a chance to resolve this delete/modify conflict\nAlice and Bob could not agree on for himself.\n\nIf Charlie thinks the same way as Alice and it is a good idea to\nkeep the documentation up to date, he might do something like\nAlice did at A2.  If on the other hand Charlie agrees with Bob\nat B2, he might take delete.  I think leaving that decision up\nto Charlie is not necessarily a bad thing.\n"}]}