{"thread":{"id":"42093","subject":"[PATCH] git-rebase--merge: don't include absent parent as a base","startedAt":"2016-04-20T18:20:56Z","lastAt":"2016-04-20T21:19:04Z","messageCount":3,"participants":["Ben Woosley","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"283974","messageId":"0102015434e7556a-2d9848cb-93c3-4883-96ec-c0c70098796b-000000@eu-west-1.amazonses.com","threadId":"42093","inReplyTo":null,"subject":"[PATCH] git-rebase--merge: don't include absent parent as a base","fromName":"Ben Woosley","fromEmail":"ben.woosley@gmail.com","sentAt":"2016-04-20T18:20:56Z","receivedAt":"2016-04-20T18:20:56Z","isPatch":true,"sender":{"key":"ben.woosley@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5470?v=4"},"body":"From: Ben Woosley <ben.woosley@gmail.com>\n\nAbsent this fix, attempts to rebase an orphan branch with --strategy recursive\nwill fail with:\n\n    $ git rebase ORPHAN_TARGET_BASE -s recursive\n    First, rewinding head to replay your work on top of it...\n    fatal: Could not parse object 'ORPHAN_ROOT_SHA^'\n    Unknown exit code (128) from command: git-merge-recursive ORPHAN_ROOT_SHA^ -- HEAD ORPHAN_ROOT_SHA\n\nTo fix, this will only include the rebase root's parent as a base if it exists,\nso that in cases of rebasing an orphan branch, it is a simple two-way merge.\n\nNote the default rebase behavior does not fail:\n\n    $ git rebase ORPHAN_TARGET_BASE\n    First, rewinding head to replay your work on top of it...\n    Applying: ORPHAN_ROOT_COMMIT_MSG\n    Using index info to reconstruct a base tree...\n\nSigned-off-by: Ben Woosley <ben.woosley@gmail.com>\n---\n git-rebase--merge.sh    | 4 +++-\n t/t3402-rebase-merge.sh | 9 +++++++++\n 2 files changed, 12 insertions(+), 1 deletion(-)\n\ndiff --git a/git-rebase--merge.sh b/git-rebase--merge.sh\nindex 2cc2a6d..8d43db9 100644\n--- a/git-rebase--merge.sh\n+++ b/git-rebase--merge.sh\n@@ -67,7 +67,9 @@ call_merge () {\n \t\tGIT_MERGE_VERBOSITY=1 && export GIT_MERGE_VERBOSITY\n \tfi\n \ttest -z \"$strategy\" && strategy=recursive\n-\teval 'git-merge-$strategy' $strategy_opts '\"$cmt^\" -- \"$hd\" \"$cmt\"'\n+\t# If cmt doesn't have a parent, don't include it as a base\n+\tbase=$(git rev-parse --verify --quiet $cmt^)\n+\teval 'git-merge-$strategy' $strategy_opts $base ' -- \"$hd\" \"$cmt\"'\n \trv=$?\n \tcase \"$rv\" in\n \t0)\ndiff --git a/t/t3402-rebase-merge.sh b/t/t3402-rebase-merge.sh\nindex 8f64505..488945e 100755\n--- a/t/t3402-rebase-merge.sh\n+++ b/t/t3402-rebase-merge.sh\n@@ -85,6 +85,15 @@ test_expect_success 'rebase -Xtheirs' '\n \t! grep 11 original\n '\n \n+test_expect_success 'rebase -Xtheirs from orphan' '\n+\tgit checkout --orphan orphan-conflicting master~2 &&\n+\techo \"AB $T\" >> original &&\n+\tgit commit -morphan-conflicting original &&\n+\tgit rebase -Xtheirs master &&\n+\tgrep AB original &&\n+\t! grep 11 original\n+'\n+\n test_expect_success 'merge and rebase should match' '\n \tgit diff-tree -r test-rebase test-merge >difference &&\n \tif test -s difference\n\n--\nhttps://github.com/git/git/pull/228\n"},{"id":"284003","messageId":"xmqq1t60ugoi.fsf@gitster.mtv.corp.google.com","threadId":"42093","inReplyTo":"0102015434e7556a-2d9848cb-93c3-4883-96ec-c0c70098796b-000000@eu-west-1.amazonses.com","subject":"Re: [PATCH] git-rebase--merge: don't include absent parent as a base","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-04-20T21:13:49Z","receivedAt":"2016-04-20T21:13:49Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ben Woosley <Ben.Woosley@gmail.com> writes:\n\n> From: Ben Woosley <ben.woosley@gmail.com>\n>\n> Absent this fix, attempts to rebase an orphan branch with --strategy recursive\n> will fail with:\n>\n>     $ git rebase ORPHAN_TARGET_BASE -s recursive\n>     First, rewinding head to replay your work on top of it...\n>     fatal: Could not parse object 'ORPHAN_ROOT_SHA^'\n>     Unknown exit code (128) from command: git-merge-recursive ORPHAN_ROOT_SHA^ -- HEAD ORPHAN_ROOT_SHA\n>\n> To fix, this will only include the rebase root's parent as a base if it exists,\n> so that in cases of rebasing an orphan branch, it is a simple two-way merge.\n>\n> Note the default rebase behavior does not fail:\n>\n>     $ git rebase ORPHAN_TARGET_BASE\n>     First, rewinding head to replay your work on top of it...\n>     Applying: ORPHAN_ROOT_COMMIT_MSG\n>     Using index info to reconstruct a base tree...\n>\n> Signed-off-by: Ben Woosley <ben.woosley@gmail.com>\n> ---\n>  git-rebase--merge.sh    | 4 +++-\n>  t/t3402-rebase-merge.sh | 9 +++++++++\n>  2 files changed, 12 insertions(+), 1 deletion(-)\n>\n> diff --git a/git-rebase--merge.sh b/git-rebase--merge.sh\n> index 2cc2a6d..8d43db9 100644\n> --- a/git-rebase--merge.sh\n> +++ b/git-rebase--merge.sh\n> @@ -67,7 +67,9 @@ call_merge () {\n>  \t\tGIT_MERGE_VERBOSITY=1 && export GIT_MERGE_VERBOSITY\n>  \tfi\n>  \ttest -z \"$strategy\" && strategy=recursive\n> -\teval 'git-merge-$strategy' $strategy_opts '\"$cmt^\" -- \"$hd\" \"$cmt\"'\n> +\t# If cmt doesn't have a parent, don't include it as a base\n> +\tbase=$(git rev-parse --verify --quiet $cmt^)\n> +\teval 'git-merge-$strategy' $strategy_opts $base ' -- \"$hd\" \"$cmt\"'\n\nMakes sense to me.  It is not clear if such a merge without common\nancestor is all that useful, but as it is mechanically possible,\nI do not see a reason to forbid it.\n\n>  \trv=$?\n>  \tcase \"$rv\" in\n>  \t0)\n> diff --git a/t/t3402-rebase-merge.sh b/t/t3402-rebase-merge.sh\n> index 8f64505..488945e 100755\n> --- a/t/t3402-rebase-merge.sh\n> +++ b/t/t3402-rebase-merge.sh\n> @@ -85,6 +85,15 @@ test_expect_success 'rebase -Xtheirs' '\n>  \t! grep 11 original\n>  '\n>  \n> +test_expect_success 'rebase -Xtheirs from orphan' '\n> +\tgit checkout --orphan orphan-conflicting master~2 &&\n> +\techo \"AB $T\" >> original &&\n> +\tgit commit -morphan-conflicting original &&\n> +\tgit rebase -Xtheirs master &&\n> +\tgrep AB original &&\n> +\t! grep 11 original\n> +'\n> +\n>  test_expect_success 'merge and rebase should match' '\n>  \tgit diff-tree -r test-rebase test-merge >difference &&\n>  \tif test -s difference\n>\n> --\n> https://github.com/git/git/pull/228\n"},{"id":"284006","messageId":"CAC5gnOxFVT=Y-YURxQxnT3Qng162=jogoZMEYJdN1jz8SmJtCg@mail.gmail.com","threadId":"42093","inReplyTo":"xmqq1t60ugoi.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH] git-rebase--merge: don't include absent parent as a base","fromName":"Ben Woosley","fromEmail":"ben.woosley@gmail.com","sentAt":"2016-04-20T21:19:04Z","receivedAt":"2016-04-20T21:19:04Z","isPatch":true,"sender":{"key":"ben.woosley@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5470?v=4"},"body":"It's helpful in the case where a bit of code has been detached from\nits history by way of copying the files and starting a new repo, where\ndevelopment continues. If you want to reunite the new history with the\nprior history, while preferring the new history, you need to `rebase\n-Xtheirs` the new branch onto the old.\n\nBest,\nBen\n\nOn Wed, Apr 20, 2016 at 2:13 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Ben Woosley <Ben.Woosley@gmail.com> writes:\n>\n>> From: Ben Woosley <ben.woosley@gmail.com>\n>>\n>> Absent this fix, attempts to rebase an orphan branch with --strategy recursive\n>> will fail with:\n>>\n>>     $ git rebase ORPHAN_TARGET_BASE -s recursive\n>>     First, rewinding head to replay your work on top of it...\n>>     fatal: Could not parse object 'ORPHAN_ROOT_SHA^'\n>>     Unknown exit code (128) from command: git-merge-recursive ORPHAN_ROOT_SHA^ -- HEAD ORPHAN_ROOT_SHA\n>>\n>> To fix, this will only include the rebase root's parent as a base if it exists,\n>> so that in cases of rebasing an orphan branch, it is a simple two-way merge.\n>>\n>> Note the default rebase behavior does not fail:\n>>\n>>     $ git rebase ORPHAN_TARGET_BASE\n>>     First, rewinding head to replay your work on top of it...\n>>     Applying: ORPHAN_ROOT_COMMIT_MSG\n>>     Using index info to reconstruct a base tree...\n>>\n>> Signed-off-by: Ben Woosley <ben.woosley@gmail.com>\n>> ---\n>>  git-rebase--merge.sh    | 4 +++-\n>>  t/t3402-rebase-merge.sh | 9 +++++++++\n>>  2 files changed, 12 insertions(+), 1 deletion(-)\n>>\n>> diff --git a/git-rebase--merge.sh b/git-rebase--merge.sh\n>> index 2cc2a6d..8d43db9 100644\n>> --- a/git-rebase--merge.sh\n>> +++ b/git-rebase--merge.sh\n>> @@ -67,7 +67,9 @@ call_merge () {\n>>               GIT_MERGE_VERBOSITY=1 && export GIT_MERGE_VERBOSITY\n>>       fi\n>>       test -z \"$strategy\" && strategy=recursive\n>> -     eval 'git-merge-$strategy' $strategy_opts '\"$cmt^\" -- \"$hd\" \"$cmt\"'\n>> +     # If cmt doesn't have a parent, don't include it as a base\n>> +     base=$(git rev-parse --verify --quiet $cmt^)\n>> +     eval 'git-merge-$strategy' $strategy_opts $base ' -- \"$hd\" \"$cmt\"'\n>\n> Makes sense to me.  It is not clear if such a merge without common\n> ancestor is all that useful, but as it is mechanically possible,\n> I do not see a reason to forbid it.\n>\n>>       rv=$?\n>>       case \"$rv\" in\n>>       0)\n>> diff --git a/t/t3402-rebase-merge.sh b/t/t3402-rebase-merge.sh\n>> index 8f64505..488945e 100755\n>> --- a/t/t3402-rebase-merge.sh\n>> +++ b/t/t3402-rebase-merge.sh\n>> @@ -85,6 +85,15 @@ test_expect_success 'rebase -Xtheirs' '\n>>       ! grep 11 original\n>>  '\n>>\n>> +test_expect_success 'rebase -Xtheirs from orphan' '\n>> +     git checkout --orphan orphan-conflicting master~2 &&\n>> +     echo \"AB $T\" >> original &&\n>> +     git commit -morphan-conflicting original &&\n>> +     git rebase -Xtheirs master &&\n>> +     grep AB original &&\n>> +     ! grep 11 original\n>> +'\n>> +\n>>  test_expect_success 'merge and rebase should match' '\n>>       git diff-tree -r test-rebase test-merge >difference &&\n>>       if test -s difference\n>>\n>> --\n>> https://github.com/git/git/pull/228\n"}]}