{"thread":{"id":"10060","subject":"[PATCH] Adding rebase merge strategy","startedAt":"2007-09-28T16:15:21Z","lastAt":"2007-10-03T15:54:47Z","messageCount":19,"participants":["Tom Clarke","Johannes Schindelin","Junio C Hamano","Carl Worth","Shawn O. Pearce","J. Bruce Fields"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"54278","messageId":"11909961212172-git-send-email-tom@u2i.com","threadId":"10060","inReplyTo":null,"subject":"[PATCH] Adding rebase merge strategy","fromName":"Tom Clarke","fromEmail":"tom@u2i.com","sentAt":"2007-09-28T16:15:21Z","receivedAt":"2007-09-28T16:15:21Z","isPatch":true,"sender":{"key":"tom@u2i.com","avatar":null},"body":"In addition to adding git-merge-rebase.sh, git-merge.sh is modified\nto handle the rebase strategy specially and avoids running update-ref\nas rebase won't generate a merge commit.\n\nSigned-off-by: Tom Clarke <tom@u2i.com>\n---\n\nRe-submitting this patch as we were in a pre-release freeze last time I submitted\n\n .gitignore                         |    1 +\n Documentation/merge-strategies.txt |    6 ++++++\n Makefile                           |    2 +-\n git-merge-rebase.sh                |   34 ++++++++++++++++++++++++++++++++++\n git-merge.sh                       |   14 +++++++++++---\n t/t3031-merge-rebase.sh            |   34 ++++++++++++++++++++++++++++++++++\n 6 files changed, 87 insertions(+), 4 deletions(-)\n create mode 100755 git-merge-rebase.sh\n create mode 100755 t/t3031-merge-rebase.sh\n\ndiff --git a/.gitignore b/.gitignore\nindex e0b91be..fe5cdc4 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -73,6 +73,7 @@ git-merge-tree\n git-merge-octopus\n git-merge-one-file\n git-merge-ours\n+git-merge-rebase\n git-merge-recursive\n git-merge-resolve\n git-merge-stupid\ndiff --git a/Documentation/merge-strategies.txt b/Documentation/merge-strategies.txt\nindex 7df0266..dff1909 100644\n--- a/Documentation/merge-strategies.txt\n+++ b/Documentation/merge-strategies.txt\n@@ -33,3 +33,9 @@ ours::\n \tmerge is always the current branch head.  It is meant to\n \tbe used to supersede old development history of side\n \tbranches.\n+\n+rebase::\n+\tThis rebases the current branch based on a single head.\n+\tCommits are rewritten as with git-rebase. This doesn't\n+\tproduce a merge. The procedure for dealing with conflicts \n+\tis the same as with git-rebase.\ndiff --git a/Makefile b/Makefile\nindex 8db4dbe..e6d3812 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -215,7 +215,7 @@ SCRIPT_SH = \\\n \tgit-sh-setup.sh \\\n \tgit-am.sh \\\n \tgit-merge.sh git-merge-stupid.sh git-merge-octopus.sh \\\n-\tgit-merge-resolve.sh git-merge-ours.sh \\\n+\tgit-merge-resolve.sh git-merge-ours.sh git-merge-rebase.sh \\\n \tgit-lost-found.sh git-quiltimport.sh git-submodule.sh \\\n \tgit-filter-branch.sh \\\n \tgit-stash.sh\ndiff --git a/git-merge-rebase.sh b/git-merge-rebase.sh\nnew file mode 100755\nindex 0000000..fc07331\n--- /dev/null\n+++ b/git-merge-rebase.sh\n@@ -0,0 +1,34 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2005 Linus Torvalds\n+# Copyright (c) 2007 Tom Clarke\n+#\n+# Resolve two trees with rebase\n+\n+# The first parameters up to -- are merge bases; the rest are heads.\n+bases= head= remotes= sep_seen=\n+for arg\n+do\n+\tcase \",$sep_seen,$head,$arg,\" in\n+\t*,--,)\n+\t\tsep_seen=yes\n+\t\t;;\n+\t,yes,,*)\n+\t\thead=$arg\n+\t\t;;\n+\t,yes,*)\n+\t\tremotes=\"$remotes$arg \"\n+\t\t;;\n+\t*)\n+\t\tbases=\"$bases$arg \"\n+\t\t;;\n+\tesac\n+done\n+\n+# Give up if we are given two or more remotes -- not handling octopus.\n+case \"$remotes\" in\n+?*' '?*)\n+\texit 2 ;;\n+esac\n+\n+git rebase $remotes || exit 2\ndiff --git a/git-merge.sh b/git-merge.sh\nindex 6c513dc..ea3cc16 100755\n--- a/git-merge.sh\n+++ b/git-merge.sh\n@@ -16,11 +16,12 @@ test -z \"$(git ls-files -u)\" ||\n LF='\n '\n \n-all_strategies='recur recursive octopus resolve stupid ours subtree'\n+all_strategies='recur recursive octopus resolve stupid ours subtree rebase'\n default_twohead_strategies='recursive'\n default_octopus_strategies='octopus'\n no_fast_forward_strategies='subtree ours'\n-no_trivial_strategies='recursive recur subtree ours'\n+no_trivial_strategies='recursive recur subtree ours rebase'\n+no_update_ref='rebase'\n use_strategies=\n \n allow_fast_forward=t\n@@ -81,11 +82,18 @@ finish () {\n \t\t\techo \"No merge message -- not updating HEAD\"\n \t\t\t;;\n \t\t*)\n-\t\t\tgit update-ref -m \"$rlogm\" HEAD \"$1\" \"$head\" || exit 1\n+\t\t\tcase \" $wt_strategy \" in\n+\t\t\t*\" $no_update_ref \"*)\n+\t\t\t\t;;\n+\t\t\t*)\n+\t\t\t\tgit update-ref -m \"$rlogm\" HEAD \"$1\" \"$head\" || exit 1\n+\t\t\t\t;;\n+\t\t\tesac\n \t\t\t;;\n \t\tesac\n \t\t;;\n \tesac\n+\n \tcase \"$1\" in\n \t'')\n \t\t;;\ndiff --git a/t/t3031-merge-rebase.sh b/t/t3031-merge-rebase.sh\nnew file mode 100755\nindex 0000000..8e3641d\n--- /dev/null\n+++ b/t/t3031-merge-rebase.sh\n@@ -0,0 +1,34 @@\n+#!/bin/sh\n+\n+test_description='merge-rebase backend test'\n+\n+. ./test-lib.sh\n+\n+test_expect_success 'merging using rebase does not create merge commit' '\n+\techo hello >a &&\n+\tgit add a &&\n+\ttest_tick && git commit -m initial &&\n+\n+\tgit checkout -b branch &&\n+\techo hello >b &&\n+\tgit add b &&\n+\ttest_tick && git commit -m onbranch &&\n+\n+\tgit checkout master &&\n+\techo update >a &&\n+\tgit add a &&\n+\ttest_tick && git commit -m update &&\n+\n+\tgit checkout branch &&\n+\tgit merge -s rebase master >expect &&\n+\n+       \t( git log --pretty=oneline ) >actual &&\n+\t(\n+\t\techo \"4db7a5a013e67aa623d1fd294e8d46e89b3ace8f onbranch\"\n+\t\techo \"893371811dbd13e85c098b72d1ab42bcfd24c2db update\"\n+\t\techo \"0e960b10429bf3f1e168ee2cc7d531ac7c622580 initial\"\n+\t) >expected &&\n+\tgit diff -w -u expected actual\n+'\n+\n+test_done\n-- \n1.5.3.rc7.3.g850f-dirty\n"},{"id":"54279","messageId":"Pine.LNX.4.64.0709281751390.28395@racer.site","threadId":"10060","inReplyTo":"11909961212172-git-send-email-tom@u2i.com","subject":"Re: [PATCH] Adding rebase merge strategy","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-09-28T17:03:50Z","receivedAt":"2007-09-28T17:03:50Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Fri, 28 Sep 2007, Tom Clarke wrote:\n\n> diff --git a/git-merge-rebase.sh b/git-merge-rebase.sh\n> new file mode 100755\n> index 0000000..fc07331\n> --- /dev/null\n> +++ b/git-merge-rebase.sh\n> @@ -0,0 +1,34 @@\n> +#!/bin/sh\n> +#\n> +# Copyright (c) 2005 Linus Torvalds\n\nReally?\n\n> +# Copyright (c) 2007 Tom Clarke\n> +#\n> +# Resolve two trees with rebase\n> +\n> +# The first parameters up to -- are merge bases; the rest are heads.\n> +bases= head= remotes= sep_seen=\n> +for arg\n> +do\n> +\tcase \",$sep_seen,$head,$arg,\" in\n> +\t*,--,)\n> +\t\tsep_seen=yes\n> +\t\t;;\n> +\t,yes,,*)\n> +\t\thead=$arg\n> +\t\t;;\n> +\t,yes,*)\n> +\t\tremotes=\"$remotes$arg \"\n> +\t\t;;\n> +\t*)\n> +\t\tbases=\"$bases$arg \"\n> +\t\t;;\n> +\tesac\n> +done\n> +\n> +# Give up if we are given two or more remotes -- not handling octopus.\n> +case \"$remotes\" in\n> +?*' '?*)\n> +\texit 2 ;;\n> +esac\n\nYou can check that much earlier, no?  IOW something like\n\n\twhile test $# != 0\n\tdo\n\t\tcase \"$1\" in --) break ;; esac\n\t\tshift\n\tdone\n\n\ttest $# = 3 || die \"merge stragey rebase needs exactly one ref\"\n\n\tgit rebase \"$3\"\n\n(It's not like you need the variables...) Hmm?\n\n> +git rebase $remotes || exit 2\n> diff --git a/git-merge.sh b/git-merge.sh\n> index 6c513dc..ea3cc16 100755\n> --- a/git-merge.sh\n> +++ b/git-merge.sh\n> @@ -81,11 +82,18 @@ finish () {\n>  \t\t\techo \"No merge message -- not updating HEAD\"\n>  \t\t\t;;\n>  \t\t*)\n> -\t\t\tgit update-ref -m \"$rlogm\" HEAD \"$1\" \"$head\" || exit 1\n> +\t\t\tcase \" $wt_strategy \" in\n> +\t\t\t*\" $no_update_ref \"*)\n> +\t\t\t\t;;\n> +\t\t\t*)\n> +\t\t\t\tgit update-ref -m \"$rlogm\" HEAD \"$1\" \"$head\" || exit 1\n> +\t\t\t\t;;\n> +\t\t\tesac\n\nYou may want to warn earlier, if a message was supplied with -s rebase, or \neven error out.\n\n> diff --git a/t/t3031-merge-rebase.sh b/t/t3031-merge-rebase.sh\n> new file mode 100755\n> index 0000000..8e3641d\n> --- /dev/null\n> +++ b/t/t3031-merge-rebase.sh\n> @@ -0,0 +1,34 @@\n> +#!/bin/sh\n> +\n> +test_description='merge-rebase backend test'\n> +\n> +. ./test-lib.sh\n> +\n> +test_expect_success 'merging using rebase does not create merge commit' '\n> +\techo hello >a &&\n> +\tgit add a &&\n> +\ttest_tick && git commit -m initial &&\n> +\n> +\tgit checkout -b branch &&\n> +\techo hello >b &&\n> +\tgit add b &&\n> +\ttest_tick && git commit -m onbranch &&\n> +\n> +\tgit checkout master &&\n> +\techo update >a &&\n> +\tgit add a &&\n> +\ttest_tick && git commit -m update &&\n\nI like to have something like this in a \"test_expect_success setup\" part, \nand then have the meat of the test in its own test case.\n\nBut hey, you're the author, it's for you to decide.\n\nThanks,\nDscho\n"},{"id":"54280","messageId":"550f9510709281018h4197d942k9dcbcfbb657d1329@mail.gmail.com","threadId":"10060","inReplyTo":"Pine.LNX.4.64.0709281751390.28395@racer.site","subject":"Re: [PATCH] Adding rebase merge strategy","fromName":"Tom Clarke","fromEmail":"tom@u2i.com","sentAt":"2007-09-28T17:18:15Z","receivedAt":"2007-09-28T17:18:15Z","isPatch":true,"sender":{"key":"tom@u2i.com","avatar":null},"body":"On 9/28/07, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:\n> > +# Copyright (c) 2005 Linus Torvalds\n>\n> Really?\nWell 90% of the file was copy and pasted from one of the other merge\nstrategies which was indeed written by Linus. So it seemed\nappropriate. If that's not appropriate attribution I can remove :-).\n\n-Tom\n"},{"id":"54489","messageId":"11912513203420-git-send-email-tom@u2i.com","threadId":"10060","inReplyTo":"Pine.LNX.4.64.0709281751390.28395@racer.site","subject":"[PATCH] Adding rebase merge strategy","fromName":"Tom Clarke","fromEmail":"tom@u2i.com","sentAt":"2007-10-01T15:08:40Z","receivedAt":"2007-10-01T15:08:40Z","isPatch":true,"sender":{"key":"tom@u2i.com","avatar":null},"body":"In addition to adding git-merge-rebase.sh, git-merge.sh is modified\nto handle the rebase strategy specially and avoids running update-ref\nas rebase won't generate a merge commit. It also adds a warning\nif a message is supplied when the rebase isn't used as this\nwill be ignored.\n\nSigned-off-by: Tom Clarke <tom@u2i.com>\n---\n\nIncorporated comments from Johannes Schindlen.\n\n .gitignore                         |    1 +\n Documentation/merge-strategies.txt |    6 +++++\n Makefile                           |    2 +-\n git-merge-rebase.sh                |   17 ++++++++++++++\n git-merge.sh                       |   24 +++++++++++++++++--\n t/t3031-merge-rebase.sh            |   44 ++++++++++++++++++++++++++++++++++++\n 6 files changed, 90 insertions(+), 4 deletions(-)\n create mode 100755 git-merge-rebase.sh\n create mode 100755 t/t3031-merge-rebase.sh\n\ndiff --git a/.gitignore b/.gitignore\nindex e0b91be..fe5cdc4 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -73,6 +73,7 @@ git-merge-tree\n git-merge-octopus\n git-merge-one-file\n git-merge-ours\n+git-merge-rebase\n git-merge-recursive\n git-merge-resolve\n git-merge-stupid\ndiff --git a/Documentation/merge-strategies.txt b/Documentation/merge-strategies.txt\nindex 7df0266..dff1909 100644\n--- a/Documentation/merge-strategies.txt\n+++ b/Documentation/merge-strategies.txt\n@@ -33,3 +33,9 @@ ours::\n \tmerge is always the current branch head.  It is meant to\n \tbe used to supersede old development history of side\n \tbranches.\n+\n+rebase::\n+\tThis rebases the current branch based on a single head.\n+\tCommits are rewritten as with git-rebase. This doesn't\n+\tproduce a merge. The procedure for dealing with conflicts \n+\tis the same as with git-rebase.\ndiff --git a/Makefile b/Makefile\nindex 8db4dbe..e6d3812 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -215,7 +215,7 @@ SCRIPT_SH = \\\n \tgit-sh-setup.sh \\\n \tgit-am.sh \\\n \tgit-merge.sh git-merge-stupid.sh git-merge-octopus.sh \\\n-\tgit-merge-resolve.sh git-merge-ours.sh \\\n+\tgit-merge-resolve.sh git-merge-ours.sh git-merge-rebase.sh \\\n \tgit-lost-found.sh git-quiltimport.sh git-submodule.sh \\\n \tgit-filter-branch.sh \\\n \tgit-stash.sh\ndiff --git a/git-merge-rebase.sh b/git-merge-rebase.sh\nnew file mode 100755\nindex 0000000..b75be3f\n--- /dev/null\n+++ b/git-merge-rebase.sh\n@@ -0,0 +1,17 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2007 Tom Clarke\n+#\n+# Resolve two trees with rebase\n+\n+# The first parameters up to -- are merge bases ignore them\n+while test $1 != \"--\"; do shift; done\n+shift\n+\n+# ignore the first head, it's not needed in a rebase merge\n+shift\n+\n+# Give up if we are given two or more remotes -- not handling octopus.\n+test $# = 1 || exit 2\n+\n+git rebase $1 || exit 2\ndiff --git a/git-merge.sh b/git-merge.sh\nindex 6c513dc..b58bee2 100755\n--- a/git-merge.sh\n+++ b/git-merge.sh\n@@ -16,11 +16,12 @@ test -z \"$(git ls-files -u)\" ||\n LF='\n '\n \n-all_strategies='recur recursive octopus resolve stupid ours subtree'\n+all_strategies='recur recursive octopus resolve stupid ours subtree rebase'\n default_twohead_strategies='recursive'\n default_octopus_strategies='octopus'\n no_fast_forward_strategies='subtree ours'\n-no_trivial_strategies='recursive recur subtree ours'\n+no_trivial_strategies='recursive recur subtree ours rebase'\n+no_update_ref='rebase'\n use_strategies=\n \n allow_fast_forward=t\n@@ -81,11 +82,18 @@ finish () {\n \t\t\techo \"No merge message -- not updating HEAD\"\n \t\t\t;;\n \t\t*)\n-\t\t\tgit update-ref -m \"$rlogm\" HEAD \"$1\" \"$head\" || exit 1\n+\t\t\tcase \" $wt_strategy \" in\n+\t\t\t*\" $no_update_ref \"*)\n+\t\t\t\t;;\n+\t\t\t*)\n+\t\t\t\tgit update-ref -m \"$rlogm\" HEAD \"$1\" \"$head\" || exit 1\n+\t\t\t\t;;\n+\t\t\tesac\n \t\t\t;;\n \t\tesac\n \t\t;;\n \tesac\n+\n \tcase \"$1\" in\n \t'')\n \t\t;;\n@@ -418,6 +426,16 @@ do\n \t;;\n     esac\n \n+    # Check to see if there's a message in a merge type that won't produce a commit \n+    if test $have_message = \"t\"\n+    then\n+\tcase \" $strategy \" in\n+\t    *\" $no_update_ref \"*)\n+\t    echo >&2 \"warning: Message is not used for $strategy merge strategy\"\n+\t    ;;\n+\tesac\n+    fi\n+\n     # Remember which strategy left the state in the working tree\n     wt_strategy=$strategy\n \ndiff --git a/t/t3031-merge-rebase.sh b/t/t3031-merge-rebase.sh\nnew file mode 100755\nindex 0000000..daa03b1\n--- /dev/null\n+++ b/t/t3031-merge-rebase.sh\n@@ -0,0 +1,44 @@\n+#!/bin/sh\n+\n+test_description='merge-rebase backend test'\n+\n+. ./test-lib.sh\n+\n+test_expect_success setup '\n+\techo hello >a &&\n+\tgit add a &&\n+\ttest_tick && git commit -m initial &&\n+\n+\tgit checkout -b branch &&\n+\techo hello >b &&\n+\tgit add b &&\n+\ttest_tick && git commit -m onbranch &&\n+\n+\tgit checkout master &&\n+\techo update >a &&\n+\tgit add a &&\n+\ttest_tick && git commit -m update\n+'\n+test_expect_success 'merging using rebase does not create merge commit' '\n+\tgit checkout branch &&\n+\tgit merge -s rebase master &&\n+\n+\t( git log --pretty=oneline ) >actual &&\n+\t(\n+\t\techo \"4db7a5a013e67aa623d1fd294e8d46e89b3ace8f onbranch\"\n+\t\techo \"893371811dbd13e85c098b72d1ab42bcfd24c2db update\"\n+\t\techo \"0e960b10429bf3f1e168ee2cc7d531ac7c622580 initial\"\n+\t) >expected &&\n+\tgit diff -w -u expected actual\n+'\n+git reset --hard HEAD@{2}\n+\n+test_expect_success 'merging using rebase with message gives warning' '\n+\tgit merge -m \"a message\" -s rebase master 2> actual &&\n+\t(\n+\t\techo \"warning: Message is not used for rebase merge strategy\"\n+\t) >expected &&\n+\tgit diff -w -u expected actual\n+'\n+\n+test_done\n-- \n1.5.3.rc7.3.g850f-dirty\n"},{"id":"54493","messageId":"Pine.LNX.4.64.0710011647030.28395@racer.site","threadId":"10060","inReplyTo":"11912513203420-git-send-email-tom@u2i.com","subject":"Re: [PATCH] Adding rebase merge strategy","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-10-01T15:50:03Z","receivedAt":"2007-10-01T15:50:03Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Mon, 1 Oct 2007, Tom Clarke wrote:\n\n> Incorporated comments from Johannes Schindlen.\n\nThanks.\n\n> +# Give up if we are given two or more remotes -- not handling octopus.\n> +test $# = 1 || exit 2\n\nI think the user wants to know in this case, too.  How about\n\ntest $# = 1 || {\n\techo \"Cannot handle octopus.\" >&2\n\texit 2\n}\n\n> diff --git a/t/t3031-merge-rebase.sh b/t/t3031-merge-rebase.sh\n> new file mode 100755\n> index 0000000..daa03b1\n> --- /dev/null\n> +++ b/t/t3031-merge-rebase.sh\n>\n> [...]\n>\n> +\t( git log --pretty=oneline ) >actual &&\n\nPlease lose the parentheses here.\n\n> +\t(\n> +\t\techo \"4db7a5a013e67aa623d1fd294e8d46e89b3ace8f onbranch\"\n> +\t\techo \"893371811dbd13e85c098b72d1ab42bcfd24c2db update\"\n> +\t\techo \"0e960b10429bf3f1e168ee2cc7d531ac7c622580 initial\"\n> +\t) >expected &&\n\nWhy not do it as is done elsewhere in the test suit: use a \"cat << EOF\" \nbefore \"test_expect_success\"?\n\n> +\t(\n> +\t\techo \"warning: Message is not used for rebase merge strategy\"\n> +\t) >expected &&\n\nSame here.\n\nOther than that, I like it.\n\nCiao,\nDscho\n"},{"id":"54503","messageId":"7vr6ker1lf.fsf@gitster.siamese.dyndns.org","threadId":"10060","inReplyTo":"11912513203420-git-send-email-tom@u2i.com","subject":"Re: [PATCH] Adding rebase merge strategy","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-10-01T21:01:32Z","receivedAt":"2007-10-01T21:01:32Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Tom Clarke <tom@u2i.com> writes:\n\n> diff --git a/Documentation/merge-strategies.txt b/Documentation/merge-strategies.txt\n> index 7df0266..dff1909 100644\n> --- a/Documentation/merge-strategies.txt\n> +++ b/Documentation/merge-strategies.txt\n> @@ -33,3 +33,9 @@ ours::\n>  \tmerge is always the current branch head.  It is meant to\n>  \tbe used to supersede old development history of side\n>  \tbranches.\n> +\n> +rebase::\n> +\tThis rebases the current branch based on a single head.\n> +\tCommits are rewritten as with git-rebase. This doesn't\n> +\tproduce a merge. The procedure for dealing with conflicts \n> +\tis the same as with git-rebase.\n\nThis would give a handier shortcut iff the rebase goes well, but\nthe workflow after stopping would be entirely different from the\nnormal \"merge\".  I am a bit worried about it giving confusion to\nthe end users.\n\n> diff --git a/git-merge-rebase.sh b/git-merge-rebase.sh\n> new file mode 100755\n> index 0000000..b75be3f\n> --- /dev/null\n> +++ b/git-merge-rebase.sh\n> @@ -0,0 +1,17 @@\n> +#!/bin/sh\n> +#\n> +# Copyright (c) 2007 Tom Clarke\n> +#\n> +# Resolve two trees with rebase\n> +\n> +# The first parameters up to -- are merge bases ignore them\n> +while test $1 != \"--\"; do shift; done\n> +shift\n> +\n> +# ignore the first head, it's not needed in a rebase merge\n> +shift\n> +\n> +# Give up if we are given two or more remotes -- not handling octopus.\n> +test $# = 1 || exit 2\n> +\n> +git rebase $1 || exit 2\n\nThis code makes rebase strategy to signal the caller that rebase\nit punted by exit status 2 when it spots conflicting changes.\n\nAt that point, what is the state of the branch tip, the index\nand the work tree?\n\nWhen a merge strategy exits with 1 (\"I cannot handle this fully\nbut here is a partial attempt\"), it is expected to leave\nsomething that can be resolved in the working tree to be\ncommitted (iow, do some edit, update-index and the a single\n\"commit\" will conclude the whole \"git merge\" business).\n\nWhen the strategy exits with 2 (\"I cannot deal with this at\nall\"), git-merge will rewind the branch, index and the work tree\nby calling restorestate to the pristine state (in order to clear\nwhatever mess the strategy may have created), say \"Merge with\nstrategy rebase failed.\", and exits with 2.\n\nAnd at that point, what can the user do?\n\nThe user then can initiate the rebase process again from the\ncommand line (perhaps even with \"-i\"):\n\n\t$ git rebase FETCH_HEAD\n\nand deal manually with the incremental conflict resolution.\nThis needs to be documented a bit more clearly, I think, than\nyour change in the Documentation/merge-strategies.txt.\n\nBut more importantly, the above recovery is possible only if you\nabort that failed rebase you did in your strategy module, isn't\nit?\n\nAlthough I haven't tried, I suspect that you need to change the\nfinal \"git rebase $1 || exit 2\" in your script with something\nlike:\n\n\tgit rebase \"$1\" || {\n        \tgit rebase --abort\n                exit 2\n\t}\n\nHave you tested conflicting cases to see how well it works and\nwhat the user experience would look like?\n\n> diff --git a/git-merge.sh b/git-merge.sh\n> index 6c513dc..b58bee2 100755\n> --- a/git-merge.sh\n> +++ b/git-merge.sh\n> ...\n> @@ -81,11 +82,18 @@ finish () {\n>  \t\t\techo \"No merge message -- not updating HEAD\"\n>  \t\t\t;;\n>  \t\t*)\n> -\t\t\tgit update-ref -m \"$rlogm\" HEAD \"$1\" \"$head\" || exit 1\n> +\t\t\tcase \" $wt_strategy \" in\n> +\t\t\t*\" $no_update_ref \"*)\n> +\t\t\t\t;;\n> +\t\t\t*)\n> +\t\t\t\tgit update-ref -m \"$rlogm\" HEAD \"$1\" \"$head\" || exit 1\n> +\t\t\t\t;;\n> +\t\t\tesac\n\nIs this because a successful rebase strategy already updated the\nref?  I would not object from the end user experience point of\nview to allow \"git merge -s rebase\" command, but I suspect the\nchanges to the merge frontend could to be restructured a bit to\nhandle this easier to read.\n\n>  \t\t\t;;\n>  \t\tesac\n>  \t\t;;\n>  \tesac\n> +\n>  \tcase \"$1\" in\n>  \t'')\n>  \t\t;;\n\nProbably this is a good readability improvement.\n\n> @@ -418,6 +426,16 @@ do\n>  \t;;\n>      esac\n>  \n> +    # Check to see if there's a message in a merge type that won't produce a commit \n> +    if test $have_message = \"t\"\n> +    then\n\nThat quoting is backwards, isn't it?\n\nLiteral \"t\" is not empty and you know you do not need to quote;\nyou instead need to quote $have_message, because that could be\nempty and will not even be given as a separate token to \"test\"\ncommand without quoting when empty.\n\n> +\tcase \" $strategy \" in\n> +\t    *\" $no_update_ref \"*)\n\nYou have an unnecessary extra indentation here.\n\n> +\t    echo >&2 \"warning: Message is not used for $strategy merge strategy\"\n> +\t    ;;\n> +\tesac\n\nI had to spend 3 minutes thinking about this; if you had a\ncomment like \"A strategy that updates the ref by itself (iow,\nbypassing git-merge) does not give git-merge to record the merge\ncommit using the given message.\"  here, I did not have to.\n"},{"id":"54504","messageId":"550f9510710011441t1eb50352ofc8db77f79d794d5@mail.gmail.com","threadId":"10060","inReplyTo":"7vr6ker1lf.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH] Adding rebase merge strategy","fromName":"Tom Clarke","fromEmail":"tom@u2i.com","sentAt":"2007-10-01T21:41:56Z","receivedAt":"2007-10-01T21:41:56Z","isPatch":true,"sender":{"key":"tom@u2i.com","avatar":null},"body":"On 10/1/07, Junio C Hamano <gitster@pobox.com> wrote:\n> This would give a handier shortcut iff the rebase goes well, but\n> the workflow after stopping would be entirely different from the\n> normal \"merge\".  I am a bit worried about it giving confusion to\n> the end users.\n\nThanks for the ample feedback, you raise a number of interesting\nissues. I am wondering now if making rebase a merge strategy is really\na good idea. Rebasing is not merging, a difference that could perhaps\nbe overlooked in the no-conflict scenario, but as you point out, is\nglaringly obvious as soon as you have conflicts.\n\nI'm happy to try to address the issues you raised, but I wonder if we\nwould do better to look back at my original proposal which was to add\na --rebase option to git-pull. git-pull is the main place there I see\nneed for using a rebase instead of a merge, as anywhere where you\nmight use git-merge directly, if what you really want is a rebase, you\ncan just run git-rebase.\n\n-Tom\n"},{"id":"54508","messageId":"87ejgescnb.wl%cworth@cworth.org","threadId":"10060","inReplyTo":"550f9510710011441t1eb50352ofc8db77f79d794d5@mail.gmail.com","subject":"Re: [PATCH] Adding rebase merge strategy","fromName":"Carl Worth","fromEmail":"cworth@cworth.org","sentAt":"2007-10-01T22:17:28Z","receivedAt":"2007-10-01T22:17:28Z","isPatch":true,"sender":{"key":"cworth@cworth.org","avatar":"https://gravatar.com/avatar/3746dc28cde609bdbd7f939058356e7e2bbd16d21e32274df0725eb3d998bc5b?d=mp&s=160"},"body":"On Mon, 1 Oct 2007 23:41:56 +0200, \"Tom Clarke\" wrote:\n> Thanks for the ample feedback, you raise a number of interesting\n> issues. I am wondering now if making rebase a merge strategy is really\n> a good idea. Rebasing is not merging, a difference that could perhaps\n> be overlooked in the no-conflict scenario, but as you point out, is\n> glaringly obvious as soon as you have conflicts.\n\nWhat I think I've always wanted is something like the following\nbehavior for \"git pull\":\n\n  * Fast forward if possible\n\n  * Otherwise, rebase, but only if there are no conflicts at all\n\n  * Otherwise, do the merge as normal, (leave conflict markers in\n    place allowing the user to fix them up and then commit).\n\nWould it be straightforward to turn your rebase merge strategy into\nsomething like the above? And if so, would that address the primary\nconcerns that Junio raised?\n\n-Carl\n"},{"id":"54509","messageId":"550f9510710011521s126ca747v956a6f80182444bb@mail.gmail.com","threadId":"10060","inReplyTo":"87ejgescnb.wl%cworth@cworth.org","subject":"Re: [PATCH] Adding rebase merge strategy","fromName":"Tom Clarke","fromEmail":"tom@u2i.com","sentAt":"2007-10-01T22:21:21Z","receivedAt":"2007-10-01T22:21:21Z","isPatch":true,"sender":{"key":"tom@u2i.com","avatar":null},"body":"On 10/2/07, Carl Worth <cworth@cworth.org> wrote:\n> What I think I've always wanted is something like the following\n> behavior for \"git pull\":\n>\n>   * Fast forward if possible\n>\n>   * Otherwise, rebase, but only if there are no conflicts at all\n>\n>   * Otherwise, do the merge as normal, (leave conflict markers in\n>     place allowing the user to fix them up and then commit).\n>\n> Would it be straightforward to turn your rebase merge strategy into\n> something like the above? And if so, would that address the primary\n> concerns that Junio raised?\n\nMaybe we need a 'pull' strategy' - merge, rebase or <insert name for\nstrategy you describe above>.\n\n-Tom\n"},{"id":"54510","messageId":"7vir5qqxl6.fsf@gitster.siamese.dyndns.org","threadId":"10060","inReplyTo":"550f9510710011441t1eb50352ofc8db77f79d794d5@mail.gmail.com","subject":"Re: [PATCH] Adding rebase merge strategy","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-10-01T22:28:05Z","receivedAt":"2007-10-01T22:28:05Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Tom Clarke\" <tom@u2i.com> writes:\n\n> I'm happy to try to address the issues you raised, but I wonder if we\n> would do better to look back at my original proposal which was to add\n> a --rebase option to git-pull. git-pull is the main place there I see\n> need for using a rebase instead of a merge, as anywhere where you\n> might use git-merge directly, if what you really want is a rebase, you\n> can just run git-rebase.\n\nYeah, we have taught \"git-pull == git-fetch + git-merge\" to our\nusers, and \"-s strategy\" has been a way to specify _how_ the\nmerge is done, and not about doing something that is not a\nmerge.\n\nAs you say, rebase is not doing a merge.  But neither is \"squash\".\n\n\"git-pull --rebase == git-fetch + git-rebase\" might be simpler\nfor end users to understand.  I dunno.\n"},{"id":"54511","messageId":"20071001223050.GE2137@spearce.org","threadId":"10060","inReplyTo":"550f9510710011521s126ca747v956a6f80182444bb@mail.gmail.com","subject":"Re: [PATCH] Adding rebase merge strategy","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2007-10-01T22:30:50Z","receivedAt":"2007-10-01T22:30:50Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Tom Clarke <tom@u2i.com> wrote:\n> On 10/2/07, Carl Worth <cworth@cworth.org> wrote:\n> > What I think I've always wanted is something like the following\n> > behavior for \"git pull\":\n> >\n> >   * Fast forward if possible\n> >\n> >   * Otherwise, rebase, but only if there are no conflicts at all\n> >\n> >   * Otherwise, do the merge as normal, (leave conflict markers in\n> >     place allowing the user to fix them up and then commit).\n> >\n> > Would it be straightforward to turn your rebase merge strategy into\n> > something like the above? And if so, would that address the primary\n> > concerns that Junio raised?\n> \n> Maybe we need a 'pull' strategy' - merge, rebase or <insert name for\n> strategy you describe above>.\n\n`git pull -s <name>` takes any merge strategy that git-merge will\naccept for its -s option.  There is also the config option of\npull.twohead that indicates what the default merge/pull strategy\nshould be for a two head merge.  Most people don't set this,\nletting the code default to 'recursive'.\n\nBut I have to agree with (was it Junio who said this?) doing a rebase\nin a merge strategy doesn't make sense when conflicts come into play.\nIt gets confusing fast for the end-user as the conflict resolution\nprocess is different than for a merge.  A long time ago I wrote a\ngit-merge-rebase strategy and gave up on it for basically the same\nreason.  I posted it to the mailing list and I think Linus said\n\"Why?!\".  That was the end of that thread as I wound up agreeing\nwith him.\n\nMultiple merge strategies can be given (and attempted).  A rebase\nstrategy could be attempted before recursive, and if the rebase\nfails but the recursive succeeds then you get (roughly) what is\nbeing described above by Carl.  But that still requires a rebase\nmerge strategy.  :-\\\n\n-- \nShawn.\n"},{"id":"54513","messageId":"87d4vysayq.wl%cworth@cworth.org","threadId":"10060","inReplyTo":"20071001223050.GE2137@spearce.org","subject":"Re: [PATCH] Adding rebase merge strategy","fromName":"Carl Worth","fromEmail":"cworth@cworth.org","sentAt":"2007-10-01T22:53:49Z","receivedAt":"2007-10-01T22:53:49Z","isPatch":true,"sender":{"key":"cworth@cworth.org","avatar":"https://gravatar.com/avatar/3746dc28cde609bdbd7f939058356e7e2bbd16d21e32274df0725eb3d998bc5b?d=mp&s=160"},"body":"On Mon, 1 Oct 2007 18:30:50 -0400, \"Shawn O. Pearce\" wrote:\n> `git pull -s <name>` takes any merge strategy that git-merge will\n> accept for its -s option.  There is also the config option of\n> pull.twohead that indicates what the default merge/pull strategy\n> should be for a two head merge.  Most people don't set this,\n> letting the code default to 'recursive'.\n\nAh, \"pull.twohead\". I don't think I ever would have guessed that. (And\nI was just about to ask if there was a nice place to find all these\noptions, but then found it myself on my first guess with \"man\ngit-config\". Thanks everyone for writing that!).\n\n> But I have to agree with (was it Junio who said this?) doing a rebase\n> in a merge strategy doesn't make sense when conflicts come into play.\n\nSure. Rebase alone isn't useful as a complete merge strategy. But a\nrebase strategy that simply fails in the face of a conflict,\n(deferring to a subsequent merge strategy), could be very useful.\n\n> It gets confusing fast for the end-user as the conflict resolution\n> process is different than for a merge.  A long time ago I wrote a\n> git-merge-rebase strategy and gave up on it for basically the same\n> reason.  I posted it to the mailing list and I think Linus said\n> \"Why?!\".  That was the end of that thread as I wound up agreeing\n> with him.\n\nYes, I thought I recalled seeing a rebase strategy go by in the past,\nbut I had never gotten around to trying it out. I'll try to do better\non this try.\n\n> Multiple merge strategies can be given (and attempted).  A rebase\n> strategy could be attempted before recursive, and if the rebase\n> fails but the recursive succeeds then you get (roughly) what is\n> being described above by Carl.  But that still requires a rebase\n> merge strategy.  :-\\\n\nYes, this sounds exactly like what I want. So, I put \"rebase\nrecursive\" in place as the value for the pull.twohead configuration?\nAn then make sure that the rebase strategy aborts as \"failed\" instead\nof \"conflicted and left for user to resolve\"? I saw Junio talking\nabout return values up above in the thread but didn't pay attention to\ndetails, (2 vs. 1 or something)?\n\nHas anyone tried this rebase then recursive strategy yet? I'm\ndefinitely interested in trying it out, as I think I'd\nfind it quite nice as a default for pull in my usage.\n\nThough actually I'd like it even more if there was some way to mark a\ncommit as having been \"published\" and the rebase strategy would refuse\nto rebase published commits. Maybe that's a per-branch\n\"last-published\" reference? I think I'd even like git-push to update\nthe last-published reference for each pushed branch by default, but\nthen perhaps have an option to mark a particular remote so that\npushing to that remote doesn't count as publishing.\n\n-Carl\n"},{"id":"54515","messageId":"20071001230936.GA5556@fieldses.org","threadId":"10060","inReplyTo":"87ejgescnb.wl%cworth@cworth.org","subject":"Re: [PATCH] Adding rebase merge strategy","fromName":"J. Bruce Fields","fromEmail":"bfields@fieldses.org","sentAt":"2007-10-01T23:09:36Z","receivedAt":"2007-10-01T23:09:36Z","isPatch":true,"sender":{"key":"bfields@citi.umich.edu","avatar":null},"body":"On Mon, Oct 01, 2007 at 03:17:28PM -0700, Carl Worth wrote:\n> What I think I've always wanted is something like the following\n> behavior for \"git pull\":\n> \n>   * Fast forward if possible\n> \n>   * Otherwise, rebase, but only if there are no conflicts at all\n> \n>   * Otherwise, do the merge as normal, (leave conflict markers in\n>     place allowing the user to fix them up and then commit).\n> \n> Would it be straightforward to turn your rebase merge strategy into\n> something like the above? And if so, would that address the primary\n> concerns that Junio raised?\n\nSurely the job of a merge strategy is to take two heads and produce a\nsingle merge commit?\n\nIf it's worth automating the steps you describe above, I think it'd be\nbetter to choose an entirely different name for the command.\n\n--b.\n"},{"id":"54516","messageId":"7vabr2qvk5.fsf@gitster.siamese.dyndns.org","threadId":"10060","inReplyTo":"87d4vysayq.wl%cworth@cworth.org","subject":"Re: [PATCH] Adding rebase merge strategy","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-10-01T23:11:54Z","receivedAt":"2007-10-01T23:11:54Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Carl Worth <cworth@cworth.org> writes:\n\n> Though actually I'd like it even more if there was some way to mark a\n> commit as having been \"published\" and the rebase strategy would refuse\n> to rebase published commits.\n\nThat is not \"though actually\", but an independent topic.\n\nThe need is indeed so real that there is a hook git-rebase pays\nattention to in order to help you with that.  I use it to\nprevent myself from accidentally rebasing the topic branches\nthat I already merged to 'next'.\n\nUnsurprisingly, it is called pre-rebase hook.\n"},{"id":"54549","messageId":"Pine.LNX.4.64.0710021056280.28395@racer.site","threadId":"10060","inReplyTo":"20071001223050.GE2137@spearce.org","subject":"Re: [PATCH] Adding rebase merge strategy","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-10-02T10:00:40Z","receivedAt":"2007-10-02T10:00:40Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Mon, 1 Oct 2007, Shawn O. Pearce wrote:\n\n> But I have to agree with (was it Junio who said this?) doing a rebase\n> in a merge strategy doesn't make sense when conflicts come into play.\n\nIn contrast, I think that it makes sense, absolutely.  If you asked for \n\"rebase\", you _have_ to know what is coming.\n\nIt's all about convenience: in many repos, I just to \"git pull\", because \nthere is really only one upstream.\n\nBut in one repo, the upstream is svn, and I mistakenly checked in a merge.  \nNot wanting to know svn deeply, I have no nice way (as I would have with \ngit) to cover up my mistake.  So in this repo, I would have liked to set \nbranch.master.mergeOptions to '-s rebase'.\n\nCiao,\nDscho\n"},{"id":"54550","messageId":"550f9510710020329m7917dc9m2bb6cfc4055fea84@mail.gmail.com","threadId":"10060","inReplyTo":"Pine.LNX.4.64.0710021056280.28395@racer.site","subject":"Re: [PATCH] Adding rebase merge strategy","fromName":"Tom Clarke","fromEmail":"tom@u2i.com","sentAt":"2007-10-02T10:29:42Z","receivedAt":"2007-10-02T10:29:42Z","isPatch":true,"sender":{"key":"tom@u2i.com","avatar":null},"body":"On 10/2/07, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:\n> It's all about convenience: in many repos, I just to \"git pull\", because\n> there is really only one upstream.\n>\n> But in one repo, the upstream is svn, and I mistakenly checked in a merge.\n> Not wanting to know svn deeply, I have no nice way (as I would have with\n> git) to cover up my mistake.  So in this repo, I would have liked to set\n> branch.master.mergeOptions to '-s rebase'.\n\nThat's a good point, in addition to being able to do a git pull that\nuses rebase, it would be useful make this configurable so you can\nalways safely do 'git pull'.\n\nSo it's perhaps the question is whether rebasing should be treated as\na kind of merging, or as an alternative to merging when pulling.\nIncidentally, are there any other cases other than pulling where using\nrebase as an alternative merge strategy is useful?\n\n-Tom\n"},{"id":"54578","messageId":"7vr6kdl5rj.fsf@gitster.siamese.dyndns.org","threadId":"10060","inReplyTo":"550f9510710020329m7917dc9m2bb6cfc4055fea84@mail.gmail.com","subject":"Re: [PATCH] Adding rebase merge strategy","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-10-02T18:40:16Z","receivedAt":"2007-10-02T18:40:16Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Tom Clarke\" <tom@u2i.com> writes:\n\n> So it's perhaps the question is whether rebasing should be treated as\n> a kind of merging, or as an alternative to merging when pulling.\n> Incidentally, are there any other cases other than pulling where using\n> rebase as an alternative merge strategy is useful?\n\nVery well put; I like concise summary of the point in a\ndiscussion thread like this.\n\nAnd the question in your last sentence is not merely incidental,\nbut I think is the most crucial one to decide which way we\nshould proceed.\n\nI do not offhand think of a place other than \"git pull\" that\nwould make sense to sometimes be able to rebase when you\nnormally use merge, so I am inclined to say it would be easier\nto teach that \"'git pull' is usually a 'git fetch' followed by\n'git merge', but in certain workflow it is handier to 'git\nfetch' and then 'git rebase', and here are the ways to get the\nrebasing behaviour...\".\n"},{"id":"54711","messageId":"550f9510710030711p195378c5t2739292d31a12de@mail.gmail.com","threadId":"10060","inReplyTo":"7vr6kdl5rj.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH] Adding rebase merge strategy","fromName":"Tom Clarke","fromEmail":"tom@u2i.com","sentAt":"2007-10-03T14:11:14Z","receivedAt":"2007-10-03T14:11:14Z","isPatch":true,"sender":{"key":"tom@u2i.com","avatar":null},"body":"On 10/2/07, Junio C Hamano <gitster@pobox.com> wrote:\n> I do not offhand think of a place other than \"git pull\" that\n> would make sense to sometimes be able to rebase when you\n> normally use merge, so I am inclined to say it would be easier\n> to teach that \"'git pull' is usually a 'git fetch' followed by\n> 'git merge', but in certain workflow it is handier to 'git\n> fetch' and then 'git rebase', and here are the ways to get the\n> rebasing behaviour...\".\n\nI agree. I'll revisit teaching pull to be able to use rebase.\n\nThanks,\n\n-Tom\n"},{"id":"54717","messageId":"Pine.LNX.4.64.0710031653480.28395@racer.site","threadId":"10060","inReplyTo":"550f9510710030711p195378c5t2739292d31a12de@mail.gmail.com","subject":"Re: [PATCH] Adding rebase merge strategy","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-10-03T15:54:47Z","receivedAt":"2007-10-03T15:54:47Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Wed, 3 Oct 2007, Tom Clarke wrote:\n\n> On 10/2/07, Junio C Hamano <gitster@pobox.com> wrote:\n> > I do not offhand think of a place other than \"git pull\" that\n> > would make sense to sometimes be able to rebase when you\n> > normally use merge, so I am inclined to say it would be easier\n> > to teach that \"'git pull' is usually a 'git fetch' followed by\n> > 'git merge', but in certain workflow it is handier to 'git\n> > fetch' and then 'git rebase', and here are the ways to get the\n> > rebasing behaviour...\".\n> \n> I agree. I'll revisit teaching pull to be able to use rebase.\n\nIn that case, may I request a config variable to set this behaviour \nautomatically when calling \"git pull <nick>\"?\n\nHad we stayed with the merge strategy approach, that would have come for \nfree with the --no-ff patch series.\n\nCiao,\nDscho\n"}]}