{"thread":{"id":"5552","subject":"[RFC] Merge strategy 'applyreject'","startedAt":"2006-09-13T21:08:17Z","lastAt":"2006-09-13T22:26:08Z","messageCount":10,"participants":["Shawn Pearce","Petr Baudis","Jakub Narebski","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"26830","messageId":"20060913210817.GA30782@spearce.org","threadId":"5552","inReplyTo":null,"subject":"[RFC] Merge strategy 'applyreject'","fromName":"Shawn Pearce","fromEmail":"spearce@spearce.org","sentAt":"2006-09-13T21:08:17Z","receivedAt":"2006-09-13T21:08:17Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Any thoughts on something like the following?\n\nI was talking with Jakub Narebski on #git today about using a\ndiff/apply pipeline as a merge strategy.\n\nI was talking about implementing this within the merge-recur driver\nas an alternative to invoking the RCS 'merge' program.  The idea\nwould be to take the current branch's file and try to apply the\ndiff of merge_base and the other branch to it.  If that has any\nrejects then try the other direction (apply diff of merge_base and\ncurrent to other) and leave the user with whichever one resulted\nin the smallest number of rejected lines.\n\nBut that's a little bit more work, this is a quick hack.  :-)  \n\n\n-- >8 --\nCreate merge strategy 'applyreject'.\n\nThe applyreject merge strategy is a two head merge strategy which performs\nthe merge by obtaining the diff between the common base and the branch\nbeing merged and applies it to the current branch using git-apply --reject.\nConsequently any failures are written to .rej files, rather than using\nthe RCS <<<<<<< ======= >>>>>>> format.\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n .gitignore               |    1 +\n Makefile                 |    1 +\n git-merge-applyreject.sh |   26 ++++++++++++++++++++++++++\n git-merge.sh             |    2 +-\n 4 files changed, 29 insertions(+), 1 deletions(-)\n\ndiff --git a/.gitignore b/.gitignore\nindex 0d608fe..0f43ece 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -56,6 +56,7 @@ git-ls-tree\n git-mailinfo\n git-mailsplit\n git-merge\n+git-merge-applyreject\n git-merge-base\n git-merge-index\n git-merge-tree\ndiff --git a/Makefile b/Makefile\nindex 7b3114f..a57dab5 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -161,6 +161,7 @@ SCRIPT_SH = \\\n \tgit-tag.sh git-verify-tag.sh \\\n \tgit-applymbox.sh git-applypatch.sh git-am.sh \\\n \tgit-merge.sh git-merge-stupid.sh git-merge-octopus.sh \\\n+\tgit-merge-applyreject.sh \\\n \tgit-merge-resolve.sh git-merge-ours.sh \\\n \tgit-lost-found.sh git-quiltimport.sh\n \ndiff --git a/git-merge-applyreject.sh b/git-merge-applyreject.sh\nnew file mode 100755\nindex 0000000..e4c8703\n--- /dev/null\n+++ b/git-merge-applyreject.sh\n@@ -0,0 +1,26 @@\n+#!/bin/sh\n+#\n+# Simple merge strategy which produces reject files on failed merges.\n+# Only handles two heads and one merge base, thus the command line\n+# parameters must be:  base -- head1 head2\n+\n+base=\"$1\"; shift; [ -z \"$base\" ] && exit 2\n+while [ $# -gt 2 -a \"X$1\" != \"X--\" ]\n+do\n+\tshift\n+done\n+if [ \"X$1\" = \"X--\" ]\n+then\n+\tshift\n+else\n+\texit 2\n+fi\n+current=\"$1\"; shift; [ -z \"$current\" ] && exit 2\n+incoming=\"$1\"; shift; [ -z \"$incoming\" ] && exit 2\n+[ $# -gt 0 ] && exit 2\n+\n+git-read-tree --reset $current || exit 2\n+git-update-index --refresh 2>/dev/null\n+git-diff --binary -M $base $incoming \\\n+\t| git-apply --index --reject --verbose\n+[ $? = 0 ] || exit 1\ndiff --git a/git-merge.sh b/git-merge.sh\nindex d049e16..e39de0a 100755\n--- a/git-merge.sh\n+++ b/git-merge.sh\n@@ -9,7 +9,7 @@ USAGE='[-n] [--no-commit] [--squash] [-s\n LF='\n '\n \n-all_strategies='recursive recur octopus resolve stupid ours'\n+all_strategies='recursive recur octopus resolve stupid ours applyreject'\n case \"${GIT_USE_RECUR_FOR_RECURSIVE}\" in\n '')\n \tdefault_twohead_strategies=recursive ;;\n-- \n1.4.2.gc52f\n"},{"id":"26834","messageId":"20060913211617.GJ23891@pasky.or.cz","threadId":"5552","inReplyTo":"20060913210817.GA30782@spearce.org","subject":"Re: [RFC] Merge strategy 'applyreject'","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2006-09-13T21:16:17Z","receivedAt":"2006-09-13T21:16:17Z","isPatch":false,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"Dear diary, on Wed, Sep 13, 2006 at 11:08:17PM CEST, I got a letter\nwhere Shawn Pearce <spearce@spearce.org> said that...\n> Create merge strategy 'applyreject'.\n> \n> The applyreject merge strategy is a two head merge strategy which performs\n> the merge by obtaining the diff between the common base and the branch\n> being merged and applies it to the current branch using git-apply --reject.\n> Consequently any failures are written to .rej files, rather than using\n> the RCS <<<<<<< ======= >>>>>>> format.\n\nSo, it's essentially the same as the classic resolve strategy, just\nhandling rejects differently? I think that should be more obvious from\nits name, perhaps resolve-rej?\n\n.rej files, what a nuisance to handle those... :)\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\nSnow falling on Perl. White noise covering line noise.\nHides all the bugs too. -- J. Putnam\n"},{"id":"26835","messageId":"ee9spf$h98$1@sea.gmane.org","threadId":"5552","inReplyTo":"20060913210817.GA30782@spearce.org","subject":"Re: [RFC] Merge strategy 'applyreject'","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-09-13T21:22:10Z","receivedAt":"2006-09-13T21:22:10Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Shawn Pearce wrote:\n\n> -- >8 --\n> Create merge strategy 'applyreject'.\n> \n> The applyreject merge strategy is a two head merge strategy which performs\n> the merge by obtaining the diff between the common base and the branch\n> being merged and applies it to the current branch using git-apply --reject.\n> Consequently any failures are written to .rej files, rather than using\n> the RCS <<<<<<< ======= >>>>>>> format.\n\nNice.\n\n> ---\n>  .gitignore               |    1 +\n>  Makefile                 |    1 +\n>  git-merge-applyreject.sh |   26 ++++++++++++++++++++++++++\n>  git-merge.sh             |    2 +-\n>  4 files changed, 29 insertions(+), 1 deletions(-)\n\nBut where documentation (Documentation/merge-strategies.txt)? \n\n> +#!/bin/sh\n> +#\n> +# Simple merge strategy which produces reject files on failed merges.\n> +# Only handles two heads and one merge base, thus the command line\n> +# parameters must be:  base -- head1 head2\n\nWe can always get the base using git-merge-base, so the arguments could\nbe either \"base -- head1 head2\", or just \"head1 head2\".\n\nDoes \"git pull -s applyreject . head2\" works (when on head1) with\nthis patch? Does the unified driver git-merge works correctly?\n\n> +git-diff --binary -M $base $incoming \\\n> +     | git-apply --index --reject --verbose\n\n--index or --cached?\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"26838","messageId":"20060913213820.GC30782@spearce.org","threadId":"5552","inReplyTo":"ee9spf$h98$1@sea.gmane.org","subject":"Re: [RFC] Merge strategy 'applyreject'","fromName":"Shawn Pearce","fromEmail":"spearce@spearce.org","sentAt":"2006-09-13T21:38:20Z","receivedAt":"2006-09-13T21:38:20Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Jakub Narebski <jnareb@gmail.com> wrote:\n> > ---\n> >  .gitignore               |    1 +\n> >  Makefile                 |    1 +\n> >  git-merge-applyreject.sh |   26 ++++++++++++++++++++++++++\n> >  git-merge.sh             |    2 +-\n> >  4 files changed, 29 insertions(+), 1 deletions(-)\n> \n> But where documentation (Documentation/merge-strategies.txt)? \n\nIf its interesting I'll document it.  I just threw it together and\ntossed it out there to see what others thought of the general idea.\n \n> > +#!/bin/sh\n> > +#\n> > +# Simple merge strategy which produces reject files on failed merges.\n> > +# Only handles two heads and one merge base, thus the command line\n> > +# parameters must be:  base -- head1 head2\n> \n> We can always get the base using git-merge-base, so the arguments could\n> be either \"base -- head1 head2\", or just \"head1 head2\".\n\nActually the merge driver (git-merge.sh) feeds us the arguments like\nthat.\n \n> Does \"git pull -s applyreject . head2\" works (when on head1) with\n> this patch? Does the unified driver git-merge works correctly?\n\nYes.  That's how I tested it.\n\n> > +git-diff --binary -M $base $incoming \\\n> > +     | git-apply --index --reject --verbose\n> \n> --index or --cached?\n\nI believe that --index is correct.  I want to patch the file in\nthe working directory, not the one that's currently in the index.\nI also want to update the index if the patch applied cleanly.\n\n-- \nShawn.\n"},{"id":"26839","messageId":"7v1wqf789j.fsf@assigned-by-dhcp.cox.net","threadId":"5552","inReplyTo":"20060913211617.GJ23891@pasky.or.cz","subject":"Re: [RFC] Merge strategy 'applyreject'","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-09-13T21:43:04Z","receivedAt":"2006-09-13T21:43:04Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Petr Baudis <pasky@suse.cz> writes:\n\n> Dear diary, on Wed, Sep 13, 2006 at 11:08:17PM CEST, I got a letter\n> where Shawn Pearce <spearce@spearce.org> said that...\n>> Create merge strategy 'applyreject'.\n>> \n>> The applyreject merge strategy is a two head merge strategy which performs\n>> the merge by obtaining the diff between the common base and the branch\n>> being merged and applies it to the current branch using git-apply --reject.\n>> Consequently any failures are written to .rej files, rather than using\n>> the RCS <<<<<<< ======= >>>>>>> format.\n>\n> So, it's essentially the same as the classic resolve strategy, just\n> handling rejects differently? I think that should be more obvious from\n> its name, perhaps resolve-rej?\n>\n> .rej files, what a nuisance to handle those... :)\n\nYou were who asked for \"apply --reject\", weren't you?\n\nI am not interested in this merge strategy myself.  Having said\nthat, if it is cleanly done, I do not have much objection adding\nit for other people's use, at least in principle.\n"},{"id":"26840","messageId":"20060913214654.GD30782@spearce.org","threadId":"5552","inReplyTo":"20060913211617.GJ23891@pasky.or.cz","subject":"Re: [RFC] Merge strategy 'applyreject'","fromName":"Shawn Pearce","fromEmail":"spearce@spearce.org","sentAt":"2006-09-13T21:46:54Z","receivedAt":"2006-09-13T21:46:54Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Petr Baudis <pasky@suse.cz> wrote:\n> Dear diary, on Wed, Sep 13, 2006 at 11:08:17PM CEST, I got a letter\n> where Shawn Pearce <spearce@spearce.org> said that...\n> > Create merge strategy 'applyreject'.\n> > \n> > The applyreject merge strategy is a two head merge strategy which performs\n> > the merge by obtaining the diff between the common base and the branch\n> > being merged and applies it to the current branch using git-apply --reject.\n> > Consequently any failures are written to .rej files, rather than using\n> > the RCS <<<<<<< ======= >>>>>>> format.\n> \n> So, it's essentially the same as the classic resolve strategy, just\n> handling rejects differently? I think that should be more obvious from\n> its name, perhaps resolve-rej?\n\nUnfortunately.  More ideally it would be a configurable feature\nof merge-recur that gets used rather than invoking the RCS merge.\nThis is just a quick and dirty 3 line shell script to propose\nthe concept.\n\n> .rej files, what a nuisance to handle those... :)\n\nA matter of opinion. :)\n\n-- \nShawn.\n"},{"id":"26841","messageId":"20060913215043.GE30782@spearce.org","threadId":"5552","inReplyTo":"7v1wqf789j.fsf@assigned-by-dhcp.cox.net","subject":"Re: [RFC] Merge strategy 'applyreject'","fromName":"Shawn Pearce","fromEmail":"spearce@spearce.org","sentAt":"2006-09-13T21:50:43Z","receivedAt":"2006-09-13T21:50:43Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Junio C Hamano <junkio@cox.net> wrote:\n> Petr Baudis <pasky@suse.cz> writes:\n> \n> > Dear diary, on Wed, Sep 13, 2006 at 11:08:17PM CEST, I got a letter\n> > where Shawn Pearce <spearce@spearce.org> said that...\n> >> Create merge strategy 'applyreject'.\n> >> \n> >> The applyreject merge strategy is a two head merge strategy which performs\n> >> the merge by obtaining the diff between the common base and the branch\n> >> being merged and applies it to the current branch using git-apply --reject.\n> >> Consequently any failures are written to .rej files, rather than using\n> >> the RCS <<<<<<< ======= >>>>>>> format.\n> >\n> > So, it's essentially the same as the classic resolve strategy, just\n> > handling rejects differently? I think that should be more obvious from\n> > its name, perhaps resolve-rej?\n> >\n> > .rej files, what a nuisance to handle those... :)\n> \n> You were who asked for \"apply --reject\", weren't you?\n> \n> I am not interested in this merge strategy myself.  Having said\n> that, if it is cleanly done, I do not have much objection adding\n> it for other people's use, at least in principle.\n\nI'll clean it up, document it and and resubmit the patch if others\nwant it as a top-level merge strategy.\n\nBut I don't really want this as a merge strategy in its own right.\nI want it as part of merge-recur, so I can drop into my .git/config\nfile:\n\n\t[merge-recursive]\n\t\tconflictFormat = rejects\n\n(for example) and not deal with the RCS merge program.  This however\nwill require some hacking in merge-recursive.c and apply.c but I\nthink its workable.\n\n-- \nShawn.\n"},{"id":"26842","messageId":"20060913215049.GP18896@pasky.or.cz","threadId":"5552","inReplyTo":"7v1wqf789j.fsf@assigned-by-dhcp.cox.net","subject":"Re: [RFC] Merge strategy 'applyreject'","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2006-09-13T21:50:49Z","receivedAt":"2006-09-13T21:50:49Z","isPatch":false,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"Dear diary, on Wed, Sep 13, 2006 at 11:43:04PM CEST, I got a letter\nwhere Junio C Hamano <junkio@cox.net> said that...\n> Petr Baudis <pasky@suse.cz> writes:\n> > .rej files, what a nuisance to handle those... :)\n> \n> You were who asked for \"apply --reject\", weren't you?\n\nYes, but the point of that was obviously different. (It's a nuisance,\nbut only when compared to the conflict markers (yes, a matter of opinion\nof course).)\n\nThanks for it, BTW!\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\nSnow falling on Perl. White noise covering line noise.\nHides all the bugs too. -- J. Putnam\n"},{"id":"26843","messageId":"ee9ult$mtn$1@sea.gmane.org","threadId":"5552","inReplyTo":"20060913215043.GE30782@spearce.org","subject":"Re: [RFC] Merge strategy 'applyreject'","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-09-13T21:54:23Z","receivedAt":"2006-09-13T21:54:23Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Shawn Pearce wrote:\n\n> But I don't really want this as a merge strategy in its own right.\n> I want it as part of merge-recur (...)\n\nWouldn't it be better to have pluggable way to deal with conflicts,\nbe it diff3/merge with conflict markers, .rej files, or invoking\ngraphical merge tool (vimdiff, Emacs Emerge, xxdiff, Meld, KDiff3)?\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"26844","messageId":"20060913222608.GG30782@spearce.org","threadId":"5552","inReplyTo":"ee9ult$mtn$1@sea.gmane.org","subject":"Re: [RFC] Merge strategy 'applyreject'","fromName":"Shawn Pearce","fromEmail":"spearce@spearce.org","sentAt":"2006-09-13T22:26:08Z","receivedAt":"2006-09-13T22:26:08Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Jakub Narebski <jnareb@gmail.com> wrote:\n> Shawn Pearce wrote:\n> \n> > But I don't really want this as a merge strategy in its own right.\n> > I want it as part of merge-recur (...)\n> \n> Wouldn't it be better to have pluggable way to deal with conflicts,\n> be it diff3/merge with conflict markers, .rej files, or invoking\n> graphical merge tool (vimdiff, Emacs Emerge, xxdiff, Meld, KDiff3)?\n\nYes.  :-)\n\nRight now I think the user could just \"plug in\" their own \"merge\"\nprogram earlier in PATH than the real one.  :-)\n\nIt would be nice to get the speed of being able to just run the\nxdiff code and the Git apply code directly on the file blobs in\nmemory, without forking, but I think pluggable file content merging\nprograms is a very good idea, for lots of different reasons.\n\n-- \nShawn.\n"}]}