{"thread":{"id":"37196","subject":"rebase flattens history when it shouldn't?","startedAt":"2014-07-23T13:34:25Z","lastAt":"2014-08-06T15:34:55Z","messageCount":6,"participants":["Sergei Organov","Jonathan Nieder","Sergey Organov","Holger Hellmuth"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"246558","messageId":"87k374xkpq.fsf@osv.gnss.ru","threadId":"37196","inReplyTo":null,"subject":"rebase flattens history when it shouldn't?","fromName":"Sergei Organov","fromEmail":"osv@javad.com","sentAt":"2014-07-23T13:34:25Z","receivedAt":"2014-07-23T13:34:25Z","isPatch":false,"sender":{"key":"osv@javad.com","avatar":null},"body":"Hello,\n\n$ git --version\ngit version 1.9.3\n\nPlease consider the following history:\n\n     --C--\n    /     \\\n   /   ----M topic,HEAD\n  /   /\n A---B master\n\nshouldn't\n\n$ git rebase master\n\nbe a no-op here? According to my reading of the rebase manual page, it\nshould be a no-op, as 'topic' is a descendant of the 'master'. Instead,\n\"git rebase master\" flattens the history to:\n\n       ----C topic,HEAD\n      /\n A---B master\n\nI'd expect --force-rebase to be required for this to happen:\n\n-f, --force-rebase\n    Force the rebase even if the current branch is a descendant of the\n    commit you are rebasing onto. Normally non-interactive rebase will\n    exit with the message \"Current branch is up to date\" in such a\n    situation. Incompatible with the --interactive option.\n\nAlso notice that:\n\n$ git rebase --preserve-merges --verbose master\n\ndoes perform the rebasing work, even though it does not change the\nhistory in the end.\n\nHere is use-case where it came from and where it gave me real surprise:\n\nI have pull.rebase=true in configuration. Being on a remote tracking\nbranch, I've successfully pulled from the origin and had no any local\nchanges on this branch. Then I've successfully merged another branch to\nthe current one but didn't push the changes back upstream. A few hours\nlater I returned to the work and issued \"git pull\" that instead of doing\nnothing (as it would be should pull.rebase be either \"false\" or\n\"preserve\") created a surprising mess.\n\nDo you think it's worth fixing?\n\nHere are reproduction commands for the example history:\n\ngit init t\ncd t\necho A > a\necho B > b\ngit add a b\ngit commit -m A -a\ngit checkout -b x\necho A >> a\ngit commit -m C -a\ngit checkout master\necho B >> b\ngit commit -m B -a\ngit checkout -b topic\ngit merge -m M x\ngit branch -d x\ngit rebase master\n\n-- \nSergey.\n"},{"id":"246580","messageId":"20140723175218.GB12427@google.com","threadId":"37196","inReplyTo":"87k374xkpq.fsf@osv.gnss.ru","subject":"Re: rebase flattens history when it shouldn't?","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2014-07-23T17:52:18Z","receivedAt":"2014-07-23T17:52:18Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Hi Sergei,\n\nSergei Organov wrote:\n\n>      --C--\n>     /     \\\n>    /   ----M topic,HEAD\n>   /   /\n>  A---B master\n>\n> shouldn't\n>\n> $ git rebase master\n>\n> be a no-op here?\n[...]\n> I'd expect --force-rebase to be required for this to happen:\n>\n> -f, --force-rebase\n>     Force the rebase even if the current branch is a descendant of the\n>     commit you are rebasing onto. Normally non-interactive rebase will\n>     exit with the message \"Current branch is up to date\" in such a\n>     situation.\n[...]\n> Do you think it's worth fixing?\n\nThanks for a clear report.\n\nAfter a successful 'git rebase master', the current branch is always a\nlinear string of patches on top of 'master'.  The \"already up to date\"\nbehavior when -f is not passed is in a certain sense an optimization\n--- it is about git noticing that 'git rebase' wouldn't have anything\nto do (except for touching timestamps) and therefore doing nothing.\n\nSo I don't think requiring -f for this case would be an improvement.\n\nI do agree that the documentation is misleading.  Any ideas for\nwording that could make it clearer?\n\nHope that helps,\nJonathan\n"},{"id":"246595","messageId":"8738drj2fc.fsf@osv.gnss.ru","threadId":"37196","inReplyTo":"20140723175218.GB12427@google.com","subject":"Re: rebase flattens history when it shouldn't?","fromName":"Sergei Organov","fromEmail":"osv@javad.com","sentAt":"2014-07-23T19:33:11Z","receivedAt":"2014-07-23T19:33:11Z","isPatch":false,"sender":{"key":"osv@javad.com","avatar":null},"body":"Jonathan Nieder <jrnieder@gmail.com> writes:\n> Hi Sergei,\n>\n> Sergei Organov wrote:\n>\n>>      --C--\n>>     /     \\\n>>    /   ----M topic,HEAD\n>>   /   /\n>>  A---B master\n>>\n>> shouldn't\n>>\n>> $ git rebase master\n>>\n>> be a no-op here?\n> [...]\n>> I'd expect --force-rebase to be required for this to happen:\n>>\n>> -f, --force-rebase\n>>     Force the rebase even if the current branch is a descendant of the\n>>     commit you are rebasing onto. Normally non-interactive rebase will\n>>     exit with the message \"Current branch is up to date\" in such a\n>>     situation.\n> [...]\n>> Do you think it's worth fixing?\n>\n> Thanks for a clear report.\n>\n> After a successful 'git rebase master', the current branch is always a\n> linear string of patches on top of 'master'.  The \"already up to date\"\n> behavior when -f is not passed is in a certain sense an optimization\n> --- it is about git noticing that 'git rebase' wouldn't have anything\n> to do (except for touching timestamps) and therefore doing nothing.\n>\n> So I don't think requiring -f for this case would be an improvement.\n\nWhat actually bothers me is the unfortunate consequence that \"git pull\"\nis not always a no-op when nothing was changed at the origin since the\nlast \"git pull\". THIS is really surprising and probably should better be\nfixed. Requiring -f is just one (obvious) way to fix this.\n\n> I do agree that the documentation is misleading.  Any ideas for\n> wording that could make it clearer?\n\nI can't suggest anything as I don't see why -f is there in the first\nplace. What are use cases?\n\n-- \nSergey.\n"},{"id":"247317","messageId":"87ppgdu9xo.fsf@osv.gnss.ru","threadId":"37196","inReplyTo":"20140723175218.GB12427@google.com","subject":"Re: rebase flattens history when it shouldn't?","fromName":"Sergey Organov","fromEmail":"sorganov@gmail.com","sentAt":"2014-08-06T11:36:19Z","receivedAt":"2014-08-06T11:36:19Z","isPatch":false,"sender":{"key":"sorganov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8501568?v=4"},"body":"Jonathan Nieder <jrnieder@gmail.com> writes:\n\n> Hi Sergei,\n>\n> Sergei Organov wrote:\n>\n>>      --C--\n>>     /     \\\n>>    /   ----M topic,HEAD\n>>   /   /\n>>  A---B master\n>>\n>> shouldn't\n>>\n>> $ git rebase master\n>>\n>> be a no-op here?\n> [...]\n>> I'd expect --force-rebase to be required for this to happen:\n>>\n>> -f, --force-rebase\n>>     Force the rebase even if the current branch is a descendant of the\n>>     commit you are rebasing onto. Normally non-interactive rebase will\n>>     exit with the message \"Current branch is up to date\" in such a\n>>     situation.\n> [...]\n>> Do you think it's worth fixing?\n>\n> Thanks for a clear report.\n>\n> After a successful 'git rebase master', the current branch is always a\n> linear string of patches on top of 'master'.\n\nIs this documented? Except implicitly by the: \n\n-p, --preserve-merges\n           Instead of ignoring merges, try to recreate them.\n\n??\n\nAnyway, why such a requirement, and is it actually enforced by tests?\n\n> The \"already up to date\" behavior when -f is not passed is in a\n> certain sense an optimization --- it is about git noticing that 'git\n> rebase' wouldn't have anything to do (except for touching timestamps)\n> and therefore doing nothing.\n\nMaybe, but I'd argue it's rather sane behavior to do no rebase when new\nrebase point is the same as original in general. I.e., when \"current\nbranch is a descendant of the commit you are rebasing onto\", as\ndocumentation says.\n\n> So I don't think requiring -f for this case would be an improvement.\n\nI still do, as it will match documentation, that in turn looks\nreasonable.\n\n> I do agree that the documentation is misleading.\n\nIf the problem is in documentation, it's not only misleading, it's\nformally wrong.\n\n> Any ideas for wording that could make it clearer?\n\nWell, if it's indeed documentation, how about this:\n\ndiff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt\nindex 2a93c64..62dac31 100644\n--- a/Documentation/git-rebase.txt\n+++ b/Documentation/git-rebase.txt\n@@ -316,10 +316,9 @@ which makes little sense.\n \n -f::\n --force-rebase::\n-\tForce the rebase even if the current branch is a descendant\n-\tof the commit you are rebasing onto.  Normally non-interactive rebase will\n-\texit with the message \"Current branch is up to date\" in such a\n-\tsituation.\n+\tForce the rebase even if the result will only change commit\n+\ttimestamps. Normally non-interactive rebase will exit with the\n+\tmessage \"Current branch is up to date\" in such a situation.\n \tIncompatible with the --interactive option.\n +\n You may find this (or --no-ff with an interactive rebase) helpful after\n\nBTW, why \"Incompatible with the --interactive option.\"? Isn't \"force\"\nassumed by --interactive, functionally?\n\n-- \nSergey.\n"},{"id":"247329","messageId":"53E2452D.6000109@ira.uka.de","threadId":"37196","inReplyTo":"8738drj2fc.fsf@osv.gnss.ru","subject":"Re: rebase flattens history when it shouldn't?","fromName":"Holger Hellmuth","fromEmail":"hellmuth@ira.uka.de","sentAt":"2014-08-06T15:09:33Z","receivedAt":"2014-08-06T15:09:33Z","isPatch":false,"sender":{"key":"hellmuth@ira.uka.de","avatar":null},"body":"On 23.07.2014 21:33, Sergei Organov wrote:\n> What actually bothers me is the unfortunate consequence that \"git pull\"\n> is not always a no-op when nothing was changed at the origin since the\n> last \"git pull\". THIS is really surprising and probably should better be\n> fixed. Requiring -f is just one (obvious) way to fix this.\n\nThat would invalidate the simple rule that \"git pull\" is equivalent to \n\"git fetch\" + \"git rebase\".\n\ngit rebase depends on both branches it operates on, not just one. The \nsame goes for \"git merge\", I assume it is just a coincidence that git \nmerge does have this characteristic you now expect both to have.\n"},{"id":"247332","messageId":"8738d91vj4.fsf@osv.gnss.ru","threadId":"37196","inReplyTo":"53E2452D.6000109@ira.uka.de","subject":"Re: rebase flattens history when it shouldn't?","fromName":"Sergey Organov","fromEmail":"sorganov@gmail.com","sentAt":"2014-08-06T15:34:55Z","receivedAt":"2014-08-06T15:34:55Z","isPatch":false,"sender":{"key":"sorganov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8501568?v=4"},"body":"Holger Hellmuth <hellmuth@ira.uka.de> writes:\n\n> On 23.07.2014 21:33, Sergei Organov wrote:\n>> What actually bothers me is the unfortunate consequence that \"git pull\"\n>> is not always a no-op when nothing was changed at the origin since the\n>> last \"git pull\". THIS is really surprising and probably should better be\n>> fixed. Requiring -f is just one (obvious) way to fix this.\n>\n> That would invalidate the simple rule that \"git pull\" is equivalent to\n> \"git fetch\" + \"git rebase\".\n\nSorry, I don't see how it would invalidate this. My suggestion even\nwon't change git-pull source code at all, only git-rebase code.\n\n> git rebase depends on both branches it operates on, not just one. The\n> same goes for \"git merge\", I assume it is just a coincidence that git\n> merge does have this characteristic you now expect both to have.\n\ngit pull --reabse=false\ngit pull --rebase=preserve\n\nboth have this property.\n\ngit pull --rebase=true\n\nalmost always has this property, unless there are local merge commits to \nbe rebased.\n\nSo, I'd rather say it's likely behavior of \"git pull --rebase=true\" that\nis a coincidence.\n\n-- \nSergey.\n"}]}