{"thread":{"id":"54591","subject":"Re: git rebase/git rebase --abort cause inconsistent state","startedAt":"2020-11-06T18:34:39Z","lastAt":"2020-11-11T07:10:59Z","messageCount":9,"participants":["Eugen Konkov","Elijah Newren","Johannes Sixt","Junio C Hamano","Johannes Schindelin"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"409285","messageId":"992859192.20201106203433@yandex.ru","threadId":"54591","inReplyTo":"1526558917.20201106203213@yandex.ru","subject":"Re: git rebase/git rebase --abort cause inconsistent state","fromName":"Eugen Konkov","fromEmail":"kes-kes@yandex.ru","sentAt":"2020-11-06T18:34:33Z","receivedAt":"2020-11-06T18:34:39Z","isPatch":false,"sender":{"key":"kes-kes@yandex.ru","avatar":null},"body":"Hello Eugen,\n\nFriday, November 6, 2020, 8:32:13 PM, you wrote:\n\n> Hi\n\n> I try to rebase, get conflicts. So I decide to --abort\n\n> After --abort I expect state before rebasing, but I get conflicts.\n\n> I  supposet  this  is  because `git rebase` switches to not branch and\n> --abort can not return to branch I was on before rebasing\n\n> Is this a bug?\n\n\n\n\n> kes@work ~/t/lib/MaitreD $ git rebase dev local/dev\n> Created autostash: 566876c8\n> warning: Cannot merge binary files: share/ChangeAgreement.docx\n> (HEAD vs. f2442d9a... Update Docs.pm)\n> Auto-merging share/ChangeAgreement.docx\n> CONFLICT (content): Merge conflict in share/ChangeAgreement.docx\n> error: could not apply f2442d9a... Update Docs.pm\n> Resolve all conflicts manually, mark them as resolved with\n> \"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n> You can instead skip this commit: run \"git rebase --skip\".\n> To abort and get back to the state before \"git rebase\", run \"git rebase --abort\".\n> Could not apply f2442d9a... Update Docs.pm\n> kes@work ~/t/lib/MaitreD $ git rebase --abort \n> Applying autostash resulted in conflicts.\n> Your changes are safe in the stash.\n> You can run \"git stash pop\" or \"git stash drop\" at any time.\n\n> Here is a tree before rebasing:\n>> a9597aaa (HEAD -> dev) Use DateTime with correct timezone\n>> 822ff801 Add link to Podio into mail\n>> 65575afe Update Docs.pm\n> | < e0003861 (local/dev) Update podio.t - test person contacts\n> | < 28ab8630 Create docdate if agreement is new and update test for that\n> | < 208ead68 Specified checking of person\n> | < f2442d9a Update Docs.pm\n> |/  \n> o 6d9c2159 (xtucha/test, xtucha/dev) Leave only one example in month\n\n> Here is conflicts:\n> HEAD detached from 142c1b15\n> Changes to be committed:\n>   (use \"git restore --staged <file>...\" to unstage)\n> 1       modified:   ../../Makefile\n> 2       modified:   ../../etc/maitre_d.development.conf\n> 3       modified:   Command/bank_statement.pm\n> 4       modified:   Command/invoicing.pm\n> 5       modified:   Command/reminding.pm\n> 6       modified:   Controller/Cart.pm\n> 7       modified:   Controller/Saldo.pm\n\n> Unmerged paths:\n>   (use \"git restore --staged <file>...\" to unstage)\n>   (use \"git add <file>...\" to mark resolution)\n> 8       both modified:   Controller/Podio.pm\n\n> $ git --version\n> git version 2.28.0\n\n\nhistory after --abort:\n* e0003861 (HEAD, local/dev) Update podio.t - test person contacts\n* 28ab8630 Create docdate if agreement is new and update test for that\n* 208ead68 Specified checking of person\n* f2442d9a Update Docs.pm\n* 6d9c2159 (xtucha/test, xtucha/dev) Leave only one example in month\n\n\nhistory before rebase:\na9597aaa (HEAD -> dev) Use DateTime with correct timezone\n\n\n\n-- \nBest regards,\nEugen Konkov\n\n"},{"id":"409286","messageId":"1526558917.20201106203213@yandex.ru","threadId":"54591","inReplyTo":null,"subject":"git rebase/git rebase --abort cause inconsistent state","fromName":"Eugen Konkov","fromEmail":"kes-kes@yandex.ru","sentAt":"2020-11-06T18:32:13Z","receivedAt":"2020-11-06T18:39:14Z","isPatch":false,"sender":{"key":"kes-kes@yandex.ru","avatar":null},"body":"Hi\n\nI try to rebase, get conflicts. So I decide to --abort\n\nAfter --abort I expect state before rebasing, but I get conflicts.\n\nI  supposet  this  is  because `git rebase` switches to not branch and\n--abort can not return to branch I was on before rebasing\n\nIs this a bug?\n\n\n\n\nkes@work ~/t/lib/MaitreD $ git rebase dev local/dev\nCreated autostash: 566876c8\nwarning: Cannot merge binary files: share/ChangeAgreement.docx (HEAD vs. f2442d9a... Update Docs.pm)\nAuto-merging share/ChangeAgreement.docx\nCONFLICT (content): Merge conflict in share/ChangeAgreement.docx\nerror: could not apply f2442d9a... Update Docs.pm\nResolve all conflicts manually, mark them as resolved with\n\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\nYou can instead skip this commit: run \"git rebase --skip\".\nTo abort and get back to the state before \"git rebase\", run \"git rebase --abort\".\nCould not apply f2442d9a... Update Docs.pm\nkes@work ~/t/lib/MaitreD $ git rebase --abort \nApplying autostash resulted in conflicts.\nYour changes are safe in the stash.\nYou can run \"git stash pop\" or \"git stash drop\" at any time.\n\nHere is a tree before rebasing:\n> a9597aaa (HEAD -> dev) Use DateTime with correct timezone\n> 822ff801 Add link to Podio into mail\n> 65575afe Update Docs.pm\n| < e0003861 (local/dev) Update podio.t - test person contacts\n| < 28ab8630 Create docdate if agreement is new and update test for that\n| < 208ead68 Specified checking of person\n| < f2442d9a Update Docs.pm\n|/  \no 6d9c2159 (xtucha/test, xtucha/dev) Leave only one example in month\n\nHere is conflicts:\nHEAD detached from 142c1b15\nChanges to be committed:\n  (use \"git restore --staged <file>...\" to unstage)\n1       modified:   ../../Makefile\n2       modified:   ../../etc/maitre_d.development.conf\n3       modified:   Command/bank_statement.pm\n4       modified:   Command/invoicing.pm\n5       modified:   Command/reminding.pm\n6       modified:   Controller/Cart.pm\n7       modified:   Controller/Saldo.pm\n\nUnmerged paths:\n  (use \"git restore --staged <file>...\" to unstage)\n  (use \"git add <file>...\" to mark resolution)\n8       both modified:   Controller/Podio.pm\n\n$ git --version\ngit version 2.28.0\n\n\n-- \nBest regards,\nEugen Konkov\n\n"},{"id":"409296","messageId":"CABPp-BGAJiaU5aeC3sGvp3znQw1esrn9c19gyOZQBymYvNFCaw@mail.gmail.com","threadId":"54591","inReplyTo":"1526558917.20201106203213@yandex.ru","subject":"Re: git rebase/git rebase --abort cause inconsistent state","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2020-11-06T20:27:08Z","receivedAt":"2020-11-06T20:27:21Z","isPatch":false,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Fri, Nov 6, 2020 at 10:41 AM Eugen Konkov <kes-kes@yandex.ru> wrote:\n>\n> Hi\n>\n> I try to rebase, get conflicts. So I decide to --abort\n>\n> After --abort I expect state before rebasing, but I get conflicts.\n>\n> I  suppose this  is  because `git rebase` switches to not branch and\n> --abort can not return to branch I was on before rebasing\n>\n> Is this a bug?\n>\n>\n>\n>\n> kes@work ~/t/lib/MaitreD $ git rebase dev local/dev\n> Created autostash: 566876c8\n> warning: Cannot merge binary files: share/ChangeAgreement.docx (HEAD vs. f2442d9a... Update Docs.pm)\n> Auto-merging share/ChangeAgreement.docx\n> CONFLICT (content): Merge conflict in share/ChangeAgreement.docx\n> error: could not apply f2442d9a... Update Docs.pm\n> Resolve all conflicts manually, mark them as resolved with\n> \"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n> You can instead skip this commit: run \"git rebase --skip\".\n> To abort and get back to the state before \"git rebase\", run \"git rebase --abort\".\n> Could not apply f2442d9a... Update Docs.pm\n> kes@work ~/t/lib/MaitreD $ git rebase --abort\n> Applying autostash resulted in conflicts.\n^^^^^^\n\nLooks like you have rebase.autostash set to true and have some\nuncommitted changes before your rebase started; it looks like it was\nthe reapplying of that stash at the time you abort is the thing that\nfailed.\n\nAccording to the rebase docs for the --abort flag:\n\"If <branch> was provided when the rebase operation was started, then\nHEAD will be reset to <branch>\"\nwhich suggests that the abort should switch you back to the original\nbranch, where the application of your local changes should be safe.\nI'll cc the two most prolific committers to builtin/stash.c to get\ntheir comments.\n\nSome questions they may be interested in, though:  Is this bug\nrepeatable?  Can you find steps to reproduce and/or share your\nrepository?  Can you verify that you don't get this bug when\nrebase.autostash is off?  What do your local changes before the rebase\nlook like and what are the nature of the conflicts afterwards (how\ndoes a \"git diff\" before the rebase compare to a \"git diff\" after)?\n\n\n> Your changes are safe in the stash.\n> You can run \"git stash pop\" or \"git stash drop\" at any time.\n>\n> Here is a tree before rebasing:\n> > a9597aaa (HEAD -> dev) Use DateTime with correct timezone\n> > 822ff801 Add link to Podio into mail\n> > 65575afe Update Docs.pm\n> | < e0003861 (local/dev) Update podio.t - test person contacts\n> | < 28ab8630 Create docdate if agreement is new and update test for that\n> | < 208ead68 Specified checking of person\n> | < f2442d9a Update Docs.pm\n> |/\n> o 6d9c2159 (xtucha/test, xtucha/dev) Leave only one example in month\n>\n> Here is conflicts:\n> HEAD detached from 142c1b15\n> Changes to be committed:\n>   (use \"git restore --staged <file>...\" to unstage)\n> 1       modified:   ../../Makefile\n> 2       modified:   ../../etc/maitre_d.development.conf\n> 3       modified:   Command/bank_statement.pm\n> 4       modified:   Command/invoicing.pm\n> 5       modified:   Command/reminding.pm\n> 6       modified:   Controller/Cart.pm\n> 7       modified:   Controller/Saldo.pm\n>\n> Unmerged paths:\n>   (use \"git restore --staged <file>...\" to unstage)\n>   (use \"git add <file>...\" to mark resolution)\n> 8       both modified:   Controller/Podio.pm\n>\n> $ git --version\n> git version 2.28.0\n>\n>\n> --\n> Best regards,\n> Eugen Konkov\n>\n"},{"id":"409309","messageId":"43de6950-a33c-f3da-2a76-72719fef5af3@kdbg.org","threadId":"54591","inReplyTo":"CABPp-BGAJiaU5aeC3sGvp3znQw1esrn9c19gyOZQBymYvNFCaw@mail.gmail.com","subject":"Re: git rebase/git rebase --abort cause inconsistent state","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2020-11-06T23:13:04Z","receivedAt":"2020-11-06T23:13:13Z","isPatch":false,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 06.11.20 um 21:27 schrieb Elijah Newren:\n> On Fri, Nov 6, 2020 at 10:41 AM Eugen Konkov <kes-kes@yandex.ru> wrote:\n>> I try to rebase, get conflicts. So I decide to --abort\n>>\n>> After --abort I expect state before rebasing, but I get conflicts.\n>>\n>> I  suppose this  is  because `git rebase` switches to not branch and\n>> --abort can not return to branch I was on before rebasing\n>>\n>> Is this a bug?\n>>\n>>\n>>\n>>\n>> kes@work ~/t/lib/MaitreD $ git rebase dev local/dev\n>> Created autostash: 566876c8\n>> warning: Cannot merge binary files: share/ChangeAgreement.docx (HEAD vs. f2442d9a... Update Docs.pm)\n>> Auto-merging share/ChangeAgreement.docx\n>> CONFLICT (content): Merge conflict in share/ChangeAgreement.docx\n>> error: could not apply f2442d9a... Update Docs.pm\n>> Resolve all conflicts manually, mark them as resolved with\n>> \"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n>> You can instead skip this commit: run \"git rebase --skip\".\n>> To abort and get back to the state before \"git rebase\", run \"git rebase --abort\".\n>> Could not apply f2442d9a... Update Docs.pm\n>> kes@work ~/t/lib/MaitreD $ git rebase --abort\n>> Applying autostash resulted in conflicts.\n> ^^^^^^\n> \n> Looks like you have rebase.autostash set to true and have some\n> uncommitted changes before your rebase started; it looks like it was\n> the reapplying of that stash at the time you abort is the thing that\n> failed.\n> \n> According to the rebase docs for the --abort flag:\n> \"If <branch> was provided when the rebase operation was started, then\n> HEAD will be reset to <branch>\"\n> which suggests that the abort should switch you back to the original\n> branch, where the application of your local changes should be safe.\n\nUnfortunately, that is not always the case, for example, in this one.\n\n>> Your changes are safe in the stash.\n>> You can run \"git stash pop\" or \"git stash drop\" at any time.\n>>\n>> Here is a tree before rebasing:\n>>> a9597aaa (HEAD -> dev) Use DateTime with correct timezone >>> 822ff801 Add link to Podio into mail\n>>> 65575afe Update Docs.pm\n>> | < e0003861 (local/dev) Update podio.t - test person contacts\n>> | < 28ab8630 Create docdate if agreement is new and update test for that\n>> | < 208ead68 Specified checking of person\n>> | < f2442d9a Update Docs.pm\n>> |/\n>> o 6d9c2159 (xtucha/test, xtucha/dev) Leave only one example in month\n\nYou start at branch dev. Then you use the two argument form\n\n     git rebase dev local/dev\n\nand when you later\n\n     git rebase --abort\n\nthen you are not warped back to dev, but to local/dev:\n\n> history after --abort:\n> * e0003861 (HEAD, local/dev) Update podio.t - test person contacts\n> * 28ab8630 Create docdate if agreement is new and update test for that\n> * 208ead68 Specified checking of person\n> * f2442d9a Update Docs.pm\n> * 6d9c2159 (xtucha/test, xtucha/dev) Leave only one example in month\n\nand at this point, your stashed changes, which were snapshot when you \nwere on branch dev, are obvously in conflict with branch local/dev.\n\nI'm not saying that that the behavior should be like this, I'm just \nexplaining what was going on. I hate this behavior, BTW.\n\n-- Hannes\n"},{"id":"409390","messageId":"16910030549.20201109134640@yandex.ru","threadId":"54591","inReplyTo":"43de6950-a33c-f3da-2a76-72719fef5af3@kdbg.org","subject":"Re: git rebase/git rebase --abort cause inconsistent state","fromName":"Eugen Konkov","fromEmail":"kes-kes@yandex.ru","sentAt":"2020-11-09T11:46:40Z","receivedAt":"2020-11-09T11:53:14Z","isPatch":false,"sender":{"key":"kes-kes@yandex.ru","avatar":null},"body":"Hello Johannes,\n\nSaturday, November 7, 2020, 1:13:04 AM, you wrote:\n\n> Am 06.11.20 um 21:27 schrieb Elijah Newren:\n>> On Fri, Nov 6, 2020 at 10:41 AM Eugen Konkov <kes-kes@yandex.ru> wrote:\n>>> I try to rebase, get conflicts. So I decide to --abort\n>>>\n>>> After --abort I expect state before rebasing, but I get conflicts.\n>>>\n>>> I  suppose this  is  because `git rebase` switches to not branch and\n>>> --abort can not return to branch I was on before rebasing\n>>>\n>>> Is this a bug?\n>>>\n>>>\n>>>\n>>>\n>>> kes@work ~/t/lib/MaitreD $ git rebase dev local/dev\n>>> Created autostash: 566876c8\n>>> warning: Cannot merge binary files: share/ChangeAgreement.docx (HEAD vs. f2442d9a... Update Docs.pm)\n>>> Auto-merging share/ChangeAgreement.docx\n>>> CONFLICT (content): Merge conflict in share/ChangeAgreement.docx\n>>> error: could not apply f2442d9a... Update Docs.pm\n>>> Resolve all conflicts manually, mark them as resolved with\n>>> \"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n>>> You can instead skip this commit: run \"git rebase --skip\".\n>>> To abort and get back to the state before \"git rebase\", run \"git rebase --abort\".\n>>> Could not apply f2442d9a... Update Docs.pm\n>>> kes@work ~/t/lib/MaitreD $ git rebase --abort\n>>> Applying autostash resulted in conflicts.\n>> ^^^^^^\n>> \n>> Looks like you have rebase.autostash set to true and have some\n>> uncommitted changes before your rebase started; it looks like it was\n>> the reapplying of that stash at the time you abort is the thing that\n>> failed.\n>> \n>> According to the rebase docs for the --abort flag:\n>> \"If <branch> was provided when the rebase operation was started, then\n>> HEAD will be reset to <branch>\"\n>> which suggests that the abort should switch you back to the original\n>> branch, where the application of your local changes should be safe.\n\n> Unfortunately, that is not always the case, for example, in this one.\n\n>>> Your changes are safe in the stash.\n>>> You can run \"git stash pop\" or \"git stash drop\" at any time.\n>>>\n>>> Here is a tree before rebasing:\n>>>> a9597aaa (HEAD -> dev) Use DateTime with correct timezone >>> 822ff801 Add link to Podio into mail\n>>>> 65575afe Update Docs.pm\n>>> | < e0003861 (local/dev) Update podio.t - test person contacts\n>>> | < 28ab8630 Create docdate if agreement is new and update test for that\n>>> | < 208ead68 Specified checking of person\n>>> | < f2442d9a Update Docs.pm\n>>> |/\n>>> o 6d9c2159 (xtucha/test, xtucha/dev) Leave only one example in month\n\n> You start at branch dev. Then you use the two argument form\n\n>      git rebase dev local/dev\n\n> and when you later\n\n>      git rebase --abort\n\n> then you are not warped back to dev, but to local/dev:\n\nI suppose `git rebase --abort` should return me back to `dev`, because\nthis is the state I was before the command. hmm... suppose it will not\nreturn to original branch when [branch] parameter is specified for git\nrebase\n\n\n>> history after --abort:\n>> * e0003861 (HEAD, local/dev) Update podio.t - test person contacts\n>> * 28ab8630 Create docdate if agreement is new and update test for that\n>> * 208ead68 Specified checking of person\n>> * f2442d9a Update Docs.pm\n>> * 6d9c2159 (xtucha/test, xtucha/dev) Leave only one example in month\n\n> and at this point, your stashed changes, which were snapshot when you \n> were on branch dev, are obvously in conflict with branch local/dev.\n\n> I'm not saying that that the behavior should be like this, I'm just \n> explaining what was going on. I hate this behavior, BTW.\nI also get inconsisten results https://stackoverflow.com/q/64592489/4632019\nThis depends on the remote history:\n1)  when  there is changes to branch on remote server (sorry, it is named local\non pictures) and local changes to this branch\n2)  when there is changes only to branch on remote server and no local\nchanges, so fast forward is possible\n\n\n> Is this bug repeatable?\nYes\n\n>Can you find steps to reproduce and/or share your repository?\ndo for commits.\npush them to remote server\non  second  machine  fetch  this  branch  and  change the history. For\nexample the first made commit\npush force back to server\nfetch changes history from remote server on first machine\nThen try to rebase remote history locally: git rebase dev local/dev\n***local is name for local server, but this is remote history\n\nThis occur:\n> and at this point, your stashed changes, which were snapshot when you\n> were on branch dev, are obvously in conflict with branch local/dev.\n\nActually  here  I  this  of  `git  rebase  dev  local/dev`  as synonym\n(probably incorrect) for `git pull --rebase`\nProbably  here I am requred an option to drop those local commits that\nwere pushed to remote and which was changed on remote,\nlike this is done when `git pull --rebase`\n\nI  prefer do `git fetch/git rebase` manually to keep thins in control.\n`git pull` to my mind makes too many magic =(\n\n\n>Can you verify that you don't get this bug when rebase.autostash is off?\nThis has no matter\n\n\n>What do your local changes before the rebase\n>look like and what are the nature of the conflicts afterwards (how\n>does a \"git diff\" before the rebase compare to a \"git diff\" after)?\nchanges  was  at  binary  .docx  files.  Hope  I repeat upper those steps to\nreproduce problem.\n\n\n> -- Hannes\n\n\n\n-- \nBest regards,\nEugen Konkov\n\n"},{"id":"409402","messageId":"xmqqft5icsd9.fsf@gitster.c.googlers.com","threadId":"54591","inReplyTo":"16910030549.20201109134640@yandex.ru","subject":"Re: git rebase/git rebase --abort cause inconsistent state","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-11-09T18:11:46Z","receivedAt":"2020-11-09T18:11:52Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Eugen Konkov <kes-kes@yandex.ru> writes:\n\n>> You start at branch dev. Then you use the two argument form\n>\n>>      git rebase dev local/dev\n>\n>> and when you later\n>\n>>      git rebase --abort\n>\n>> then you are not warped back to dev, but to local/dev:\n>\n> I suppose `git rebase --abort` should return me back to `dev`, because\n> this is the state I was before the command. hmm... suppose it will not\n> return to original branch when [branch] parameter is specified for git\n> rebase\n\nYes, \"git rebase [--onto C] A B\" has always been a short-hand for\n\n\tgit checkout B\n\tgit rebase [--onto C] A\n\nwhich means that if the second rebase step aborts, rebase wants to\ngo back to the state before the rebase started, i.e. immediately\nafter \"checkout B\" was done.\n\nI think the root cause of the problem is that addition of the\n\"--autostash\" feature (which came much later than the two-arg form)\nwas designed poorly.  If it wanted to keep the \"two-arg form is a\nmere short-hand for checkout followed by rebase\" semantics to avoid\nconfusing existing users (which is probably a good thing and that\nseems to be what the code does), then the auto-stash should have\nbeen added _after_ we switch to the branch we rebase, i.e. B.  That\nway, the stash would be applicable if the rebase gets aborted and\ngoes back to the original B, where the stash was taken from.\n\nOf course, that would also mean that the original modification in\nthe working tree and the index may not allow you to move to branch B\n(i.e. starting from your original branch O, and editing files in the\nworking tree, \"git checkout B\" may notice that you edited files that\nare different between O and B and refuse to check out branch B to\nprevent you from losing your local modifications), but that probably\nis a good thing, if \"two-arg form is a mere short-hand\" paradigm is\nto be kept.  So, \"use autostash and you can always rebase in a clean\nstate\" would no longer hold.\n\nAnother thing we could have done when adding \"--autostash\", was to\nredefine the meaning of the two-arg form.  Then it starts to make\nsense to take a stash _before_ switching to the branch to be rebased\n(i.e.  B), to go back to the original branch before switching to B,\nand then to unstash on the working tree of the original branch that\nis checked out after aborting.\n\nNote that such an alternative design would have had its own issues.\nWith such a different semantics of two-arg form, if a rebase cleanly\nfinishes, instead of staying on the rebased branch B, we MUST go\nback to the original branch to unstash what was autostashed.\nUsually people expect after a rebase to play with the rebased state\n(e.g. test build), so staying on branch B that was just rebased\nwould be far more usable than going back to unrelated original\nbranch (and possibly unstashing).\n\nIn any case, the ship has long sailed, so ...\n"},{"id":"409504","messageId":"1564505431.20201110195952@yandex.ru","threadId":"54591","inReplyTo":"xmqqft5icsd9.fsf@gitster.c.googlers.com","subject":"Re: git rebase/git rebase --abort cause inconsistent state","fromName":"Eugen Konkov","fromEmail":"kes-kes@yandex.ru","sentAt":"2020-11-10T17:59:52Z","receivedAt":"2020-11-10T18:00:28Z","isPatch":false,"sender":{"key":"kes-kes@yandex.ru","avatar":null},"body":"Hello Junio,\n\nMonday, November 9, 2020, 8:11:46 PM, you wrote:\n\n> Eugen Konkov <kes-kes@yandex.ru> writes:\n\n>>> You start at branch dev. Then you use the two argument form\n>>\n>>>      git rebase dev local/dev\n>>\n>>> and when you later\n>>\n>>>      git rebase --abort\n>>\n>>> then you are not warped back to dev, but to local/dev:\n>>\n>> I suppose `git rebase --abort` should return me back to `dev`, because\n>> this is the state I was before the command. hmm... suppose it will not\n>> return to original branch when [branch] parameter is specified for git\n>> rebase\n\n> Yes, \"git rebase [--onto C] A B\" has always been a short-hand for\n\n>         git checkout B\n>         git rebase [--onto C] A\n\n> which means that if the second rebase step aborts, rebase wants to\n> go back to the state before the rebase started, i.e. immediately\n> after \"checkout B\" was done.\n\n> I think the root cause of the problem is that addition of the\n> \"--autostash\" feature (which came much later than the two-arg form)\n> was designed poorly.  If it wanted to keep the \"two-arg form is a\n> mere short-hand for checkout followed by rebase\" semantics to avoid\n> confusing existing users (which is probably a good thing and that\n> seems to be what the code does), then the auto-stash should have\n> been added _after_ we switch to the branch we rebase, i.e. B.  That\n> way, the stash would be applicable if the rebase gets aborted and\n> goes back to the original B, where the stash was taken from.\n\n> Of course, that would also mean that the original modification in\n> the working tree and the index may not allow you to move to branch B\n> (i.e. starting from your original branch O, and editing files in the\n> working tree, \"git checkout B\" may notice that you edited files that\n> are different between O and B and refuse to check out branch B to\n> prevent you from losing your local modifications), but that probably\n> is a good thing, if \"two-arg form is a mere short-hand\" paradigm is\n> to be kept.  So, \"use autostash and you can always rebase in a clean\n> state\" would no longer hold.\n\n> Another thing we could have done when adding \"--autostash\", was to\n> redefine the meaning of the two-arg form.  Then it starts to make\n> sense to take a stash _before_ switching to the branch to be rebased\n> (i.e.  B), to go back to the original branch before switching to B,\n> and then to unstash on the working tree of the original branch that\n> is checked out after aborting.\n\n> Note that such an alternative design would have had its own issues.\n> With such a different semantics of two-arg form, if a rebase cleanly\n> finishes, instead of staying on the rebased branch B, we MUST go\n> back to the original branch to unstash what was autostashed.\n> Usually people expect after a rebase to play with the rebased state\n> (e.g. test build), so staying on branch B that was just rebased\n> would be far more usable than going back to unrelated original\n> branch (and possibly unstashing).\n\n> In any case, the ship has long sailed, so ...\n\nI should try that usecases to have an opinion on that.\n\nCurrently I just add picture when `dev` is moved while rebasing.\nThis does not occur when `local/dev` does not point to `dev`\n(when `local/dev/` and `dev` point different commits)\n\nAlso I will try --onto and how it suits to my work flow.\n\n\n\n\n\n-- \nBest regards,\nEugen Konkov"},{"id":"409559","messageId":"nycvar.QRO.7.76.6.2011102312020.18437@tvgsbejvaqbjf.bet","threadId":"54591","inReplyTo":"xmqqft5icsd9.fsf@gitster.c.googlers.com","subject":"Re: git rebase/git rebase --abort cause inconsistent state","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2020-11-10T22:28:49Z","receivedAt":"2020-11-10T22:28:59Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Junio,\n\nOn Mon, 9 Nov 2020, Junio C Hamano wrote:\n\n> Eugen Konkov <kes-kes@yandex.ru> writes:\n>\n> >> You start at branch dev. Then you use the two argument form\n> >\n> >>      git rebase dev local/dev\n> >\n> >> and when you later\n> >\n> >>      git rebase --abort\n> >\n> >> then you are not warped back to dev, but to local/dev:\n> >\n> > I suppose `git rebase --abort` should return me back to `dev`, because\n> > this is the state I was before the command. hmm... suppose it will not\n> > return to original branch when [branch] parameter is specified for git\n> > rebase\n>\n> Yes, \"git rebase [--onto C] A B\" has always been a short-hand for\n>\n> \tgit checkout B\n> \tgit rebase [--onto C] A\n>\n> which means that if the second rebase step aborts, rebase wants to\n> go back to the state before the rebase started, i.e. immediately\n> after \"checkout B\" was done.\n>\n> I think the root cause of the problem is that addition of the\n> \"--autostash\" feature (which came much later than the two-arg form)\n> was designed poorly.  If it wanted to keep the \"two-arg form is a\n> mere short-hand for checkout followed by rebase\" semantics to avoid\n> confusing existing users (which is probably a good thing and that\n> seems to be what the code does), then the auto-stash should have\n> been added _after_ we switch to the branch we rebase, i.e. B.  That\n> way, the stash would be applicable if the rebase gets aborted and\n> goes back to the original B, where the stash was taken from.\n\nThat makes a ton of sense to me.\n\n> Of course, that would also mean that the original modification in\n> the working tree and the index may not allow you to move to branch B\n> (i.e. starting from your original branch O, and editing files in the\n> working tree, \"git checkout B\" may notice that you edited files that\n> are different between O and B and refuse to check out branch B to\n> prevent you from losing your local modifications), but that probably\n> is a good thing, if \"two-arg form is a mere short-hand\" paradigm is\n> to be kept.  So, \"use autostash and you can always rebase in a clean\n> state\" would no longer hold.\n\nI agree with that, too.\n\n> Another thing we could have done when adding \"--autostash\", was to\n> redefine the meaning of the two-arg form.  Then it starts to make\n> sense to take a stash _before_ switching to the branch to be rebased\n> (i.e.  B), to go back to the original branch before switching to B,\n> and then to unstash on the working tree of the original branch that\n> is checked out after aborting.\n>\n> Note that such an alternative design would have had its own issues.\n> With such a different semantics of two-arg form, if a rebase cleanly\n> finishes, instead of staying on the rebased branch B, we MUST go\n> back to the original branch to unstash what was autostashed.\n> Usually people expect after a rebase to play with the rebased state\n> (e.g. test build), so staying on branch B that was just rebased\n> would be far more usable than going back to unrelated original\n> branch (and possibly unstashing).\n>\n> In any case, the ship has long sailed, so ...\n\nRight. I think by now, the sanest way out of this fix is to do as you say,\nstash only _after_ switching to the branch (if that was asked for).\n\nUnfortunately, it is not that trivial to change `git rebase` to autostash\n_after_ switching branches: we actually do skip the actual _checkout_\npart, for performance reasons, as of 767a9c417eb (rebase -i: stop checking\nout the tip of the branch to rebase, 2020-01-24).\n\nMy wishful thinking part wants Elijah's merge-ort work to be complete\nalready so that we can implement a purely in-memory, throw-away\ncherry-pick of the autostashed changes on top of the branch to switch to,\nand add that as a mandatory check _right after_ autostashing in `git\nrebase`. I guess at some stage that will happen.\n\nIn the meantime, we might need to disallow `--autostash` with implicit\nbranch switching.\n\nCiao,\nDscho\n"},{"id":"409587","messageId":"ea62f9b7-483b-9187-25ee-b6116a25b757@kdbg.org","threadId":"54591","inReplyTo":"nycvar.QRO.7.76.6.2011102312020.18437@tvgsbejvaqbjf.bet","subject":"Re: git rebase/git rebase --abort cause inconsistent state","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2020-11-11T07:10:53Z","receivedAt":"2020-11-11T07:10:59Z","isPatch":false,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 10.11.20 um 23:28 schrieb Johannes Schindelin:\n> On Mon, 9 Nov 2020, Junio C Hamano wrote:\n>> Eugen Konkov <kes-kes@yandex.ru> writes:\n>>\n>>>> You start at branch dev. Then you use the two argument form\n>>>\n>>>>       git rebase dev local/dev\n>>>\n>>>> and when you later\n>>>\n>>>>       git rebase --abort\n>>>\n>>>> then you are not warped back to dev, but to local/dev:\n>>>\n>>> I suppose `git rebase --abort` should return me back to `dev`, because\n>>> this is the state I was before the command. hmm... suppose it will not\n>>> return to original branch when [branch] parameter is specified for git\n>>> rebase\n>>\n>> Yes, \"git rebase [--onto C] A B\" has always been a short-hand for\n>>\n>> \tgit checkout B\n>> \tgit rebase [--onto C] A\n>>\n>> which means that if the second rebase step aborts, rebase wants to\n>> go back to the state before the rebase started, i.e. immediately\n>> after \"checkout B\" was done.\n>>\n>> I think the root cause of the problem is that addition of the\n>> \"--autostash\" feature (which came much later than the two-arg form)\n>> was designed poorly.  If it wanted to keep the \"two-arg form is a\n>> mere short-hand for checkout followed by rebase\" semantics to avoid\n>> confusing existing users (which is probably a good thing and that\n>> seems to be what the code does), then the auto-stash should have\n>> been added _after_ we switch to the branch we rebase, i.e. B.  That\n>> way, the stash would be applicable if the rebase gets aborted and\n>> goes back to the original B, where the stash was taken from.\n> \n> That makes a ton of sense to me.\n\nNot to me. In particular, I would prefer to move away from the mental \nmodel \"two-arg form is shorthand for checkout followed by rebase\".\n\nFirst of all, it does not match the mental model of inexperienced users. \nYou have to have been deep in Git operations long enough to know that \nthe two-arg form is implemented by an initial checkout so that the \nrebase can proceed as if it were the usual one-arg form.\n\nSecond, this initial checkout in two-arg form is not necessary at all to \nbegin the rebase. As a first step, the commits to be rebased must be \ndetermined. For this, the traditional way is to ask for the range \nBASE..HEAD (and in order not to change this query for two-arg form, the \ncheckout was added). But the commits can be determined with \nBASE..${second_arg:-HEAD} without requiring a checkout. Then the first \nunavoidable checkout is the one that goes to ONTO (with some further \nshortcuts in an interactive rebase).\n\nI really don't give a dime for the initial checkout. After a botched \ntwo-arg rebase, I usually prefer that --abort brings me back to the \nbranch were I was when I started, and not to the branch that was the \nsecond arg of the rebase.\n\n>> In any case, the ship has long sailed, so ...\n\nWell, then order it back. rebase is porcelain, not plumbing.\n\n-- Hannes\n"}]}