{"thread":{"id":"38695","subject":"Unexpected/unexplained difference between git pull --rebase and git rebase","startedAt":"2015-03-03T20:39:31Z","lastAt":"2015-03-04T09:35:54Z","messageCount":9,"participants":["Mike Botsko","John Keeping","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"256927","messageId":"CAPfvZp6oNnM=M-9BAVqAE052jQApH-O_t3gEoq6JWC2kQrR8gg@mail.gmail.com","threadId":"38695","inReplyTo":null,"subject":"Unexpected/unexplained difference between git pull --rebase and git rebase","fromName":"Mike Botsko","fromEmail":"botsko@gmail.com","sentAt":"2015-03-03T20:39:31Z","receivedAt":"2015-03-03T20:39:31Z","isPatch":false,"sender":{"key":"botsko@gmail.com","avatar":"https://gravatar.com/avatar/1207322b4640c5494f9b5cf3286295100c52de97f20e228b4b31305765f6808a?d=mp&s=160"},"body":"Hello,\n\nI'm seeing unexpected behavior between \"git pull --rebase\" and \"git\nrebase\" commands, which are supposed to be (and always described as)\nsynonymous:\n\ngit pull --rebase upstream our-branch-name\n\nand\n\ngit fetch upstream\ngit rebase upstream/our-branch-name\n\nWe have a situation where the upstream/our-branch-name was rebased, to\nincorporate changes from master. Somehow, the person who did the\nrebase discarded a merge commit:\n\n634b622 Sue Merge pull request #254 from bob/B-07290\nbc76e5b Bob [B-07290] Order Parts Ship To/Comments\n\nbecame:\n\nc1452be Sue [B-07290] Order Parts Ship To/Comments\n\n\nA developer who had a local branch tried to rebase their work (a\nsingle commit on top of that feature branch).\n\nAt the moment, his now-out-of-date branch looks like this:\n\n92b2194 Rick B-07241\n634b622 Sue Merge pull request #254 from dboyle/B-07290\nbc76e5b Bob [B-07290] Order Parts Ship To/Comments\n\nI've done some debugging, and the above \"git pull\" command generates\nthe following and sends it to eval():\n\ngit-rebase --onto c1452be62cf271a25d3d74cc63cd67eca51a127d\n634b622870a1016e717067281c7739b1fe08e08d\n\nThis process works perfectly. The old commits are discarded and his\nbranch now correctly reflects upstream/our-branch-name, with his\nsingle new commit at the top.\n\n\nHowever, if he runs the \"git rebase\" command above, several of the\ncommits that have changed hashes (they've also changed patch id\nslightly, because during the rebase someone fixed a merge conflict)\nare treated as new work, and git tries to re-apply them and we get\ntons of merge conflicts.\n\nThe git rebase command above is trying to rebase onto:\n\nrevisions = c1452be62cf271a25d3d74cc63cd67eca51a127d..92b2194e3adc29eb3fadd93ddded0ed34513d587\n\n\nThese two features should work the same, yet one is choosing a\ndifferent commit hash than the other.\n\nIf this is not a bug, I can't find anyone who can explain what's\nhappening. I'm using git 2.2.1 on mac, but other people on our team\nhave a variety of older versions and we're all seeing the same result.\n\nThanks!\n\n-- \nMike Botsko\nLead Dev @ Helion3\nPh: 1-(503)-897-0155\n"},{"id":"256931","messageId":"20150303210900.GP890@serenity.lan","threadId":"38695","inReplyTo":"CAPfvZp6oNnM=M-9BAVqAE052jQApH-O_t3gEoq6JWC2kQrR8gg@mail.gmail.com","subject":"Re: Unexpected/unexplained difference between git pull --rebase and git rebase","fromName":"John Keeping","fromEmail":"john@keeping.me.uk","sentAt":"2015-03-03T21:09:00Z","receivedAt":"2015-03-03T21:09:00Z","isPatch":false,"sender":{"key":"john@keeping.me.uk","avatar":"https://avatars.githubusercontent.com/u/1702081?v=4"},"body":"On Tue, Mar 03, 2015 at 12:39:31PM -0800, Mike Botsko wrote:\n> I'm seeing unexpected behavior between \"git pull --rebase\" and \"git\n> rebase\" commands, which are supposed to be (and always described as)\n> synonymous:\n> \n> git pull --rebase upstream our-branch-name\n> \n> and\n> \n> git fetch upstream\n> git rebase upstream/our-branch-name\n> \n> We have a situation where the upstream/our-branch-name was rebased, to\n> incorporate changes from master. Somehow, the person who did the\n> rebase discarded a merge commit:\n> \n> 634b622 Sue Merge pull request #254 from bob/B-07290\n> bc76e5b Bob [B-07290] Order Parts Ship To/Comments\n> \n> became:\n> \n> c1452be Sue [B-07290] Order Parts Ship To/Comments\n> \n> \n> A developer who had a local branch tried to rebase their work (a\n> single commit on top of that feature branch).\n> \n> At the moment, his now-out-of-date branch looks like this:\n> \n> 92b2194 Rick B-07241\n> 634b622 Sue Merge pull request #254 from dboyle/B-07290\n> bc76e5b Bob [B-07290] Order Parts Ship To/Comments\n> \n> I've done some debugging, and the above \"git pull\" command generates\n> the following and sends it to eval():\n> \n> git-rebase --onto c1452be62cf271a25d3d74cc63cd67eca51a127d\n> 634b622870a1016e717067281c7739b1fe08e08d\n> \n> This process works perfectly. The old commits are discarded and his\n> branch now correctly reflects upstream/our-branch-name, with his\n> single new commit at the top.\n> \n> \n> However, if he runs the \"git rebase\" command above, several of the\n> commits that have changed hashes (they've also changed patch id\n> slightly, because during the rebase someone fixed a merge conflict)\n> are treated as new work, and git tries to re-apply them and we get\n> tons of merge conflicts.\n> \n> The git rebase command above is trying to rebase onto:\n> \n> revisions = c1452be62cf271a25d3d74cc63cd67eca51a127d..92b2194e3adc29eb3fadd93ddded0ed34513d587\n> \n> \n> These two features should work the same, yet one is choosing a\n> different commit hash than the other.\n> \n> If this is not a bug, I can't find anyone who can explain what's\n> happening. I'm using git 2.2.1 on mac, but other people on our team\n> have a variety of older versions and we're all seeing the same result.\n\nWhat version of Git are you using?\n\nDoes it work if you add the `--fork-point` argument to git-rebase?  If\nso, does it do the same if you just do \"git rebase\" with no arguments\n(see the documentation of `--fork-point` in git-rebase(1) for details of\nthis)?\n"},{"id":"256934","messageId":"CAPfvZp5KmEwY_903aUJE0p7qKMUbABYpC3Y8JvPSc_Dmd0ppGA@mail.gmail.com","threadId":"38695","inReplyTo":"20150303210900.GP890@serenity.lan","subject":"Re: Unexpected/unexplained difference between git pull --rebase and git rebase","fromName":"Mike Botsko","fromEmail":"botsko@gmail.com","sentAt":"2015-03-03T21:31:39Z","receivedAt":"2015-03-03T21:31:39Z","isPatch":false,"sender":{"key":"botsko@gmail.com","avatar":"https://gravatar.com/avatar/1207322b4640c5494f9b5cf3286295100c52de97f20e228b4b31305765f6808a?d=mp&s=160"},"body":"I'm using git 2.2.1 on Mac OS X Yosemite.\n\nI just tried the git rebase with \"--fork-point\" added, and it works properly:\n\n$ git rebase upstream/our-branch-name --fork-point\nFirst, rewinding head to replay your work on top of it...\nApplying: B-07241\n\nWhile discussing with someone else, he mentioned \"poking about a bit\nmore, git rebase began defaulting to --fork-point in git 1.9, so one\nmight expect it to be there in that version\" - but we figured it might\nbe related to https://github.com/git/git/commit/1e0dacdbdb751caa5936b6d1510f5e8db4d1ed5f.\nI upgraded my version of git, but it wasn't fixed.\n\nI assume he was incorrect in that git rebase uses --fork-point by default?\n\nOn Tue, Mar 3, 2015 at 1:09 PM, John Keeping <john@keeping.me.uk> wrote:\n> On Tue, Mar 03, 2015 at 12:39:31PM -0800, Mike Botsko wrote:\n>> I'm seeing unexpected behavior between \"git pull --rebase\" and \"git\n>> rebase\" commands, which are supposed to be (and always described as)\n>> synonymous:\n>>\n>> git pull --rebase upstream our-branch-name\n>>\n>> and\n>>\n>> git fetch upstream\n>> git rebase upstream/our-branch-name\n>>\n>> We have a situation where the upstream/our-branch-name was rebased, to\n>> incorporate changes from master. Somehow, the person who did the\n>> rebase discarded a merge commit:\n>>\n>> 634b622 Sue Merge pull request #254 from bob/B-07290\n>> bc76e5b Bob [B-07290] Order Parts Ship To/Comments\n>>\n>> became:\n>>\n>> c1452be Sue [B-07290] Order Parts Ship To/Comments\n>>\n>>\n>> A developer who had a local branch tried to rebase their work (a\n>> single commit on top of that feature branch).\n>>\n>> At the moment, his now-out-of-date branch looks like this:\n>>\n>> 92b2194 Rick B-07241\n>> 634b622 Sue Merge pull request #254 from dboyle/B-07290\n>> bc76e5b Bob [B-07290] Order Parts Ship To/Comments\n>>\n>> I've done some debugging, and the above \"git pull\" command generates\n>> the following and sends it to eval():\n>>\n>> git-rebase --onto c1452be62cf271a25d3d74cc63cd67eca51a127d\n>> 634b622870a1016e717067281c7739b1fe08e08d\n>>\n>> This process works perfectly. The old commits are discarded and his\n>> branch now correctly reflects upstream/our-branch-name, with his\n>> single new commit at the top.\n>>\n>>\n>> However, if he runs the \"git rebase\" command above, several of the\n>> commits that have changed hashes (they've also changed patch id\n>> slightly, because during the rebase someone fixed a merge conflict)\n>> are treated as new work, and git tries to re-apply them and we get\n>> tons of merge conflicts.\n>>\n>> The git rebase command above is trying to rebase onto:\n>>\n>> revisions = c1452be62cf271a25d3d74cc63cd67eca51a127d..92b2194e3adc29eb3fadd93ddded0ed34513d587\n>>\n>>\n>> These two features should work the same, yet one is choosing a\n>> different commit hash than the other.\n>>\n>> If this is not a bug, I can't find anyone who can explain what's\n>> happening. I'm using git 2.2.1 on mac, but other people on our team\n>> have a variety of older versions and we're all seeing the same result.\n>\n> What version of Git are you using?\n>\n> Does it work if you add the `--fork-point` argument to git-rebase?  If\n> so, does it do the same if you just do \"git rebase\" with no arguments\n> (see the documentation of `--fork-point` in git-rebase(1) for details of\n> this)?\n\n\n\n-- \nMike Botsko\nLead Dev @ Helion3\nPh: 1-(503)-897-0155\n"},{"id":"256935","messageId":"20150303214653.GQ890@serenity.lan","threadId":"38695","inReplyTo":"CAPfvZp5KmEwY_903aUJE0p7qKMUbABYpC3Y8JvPSc_Dmd0ppGA@mail.gmail.com","subject":"Re: Unexpected/unexplained difference between git pull --rebase and git rebase","fromName":"John Keeping","fromEmail":"john@keeping.me.uk","sentAt":"2015-03-03T21:46:53Z","receivedAt":"2015-03-03T21:46:53Z","isPatch":false,"sender":{"key":"john@keeping.me.uk","avatar":"https://avatars.githubusercontent.com/u/1702081?v=4"},"body":"On Tue, Mar 03, 2015 at 01:31:39PM -0800, Mike Botsko wrote:\n> I'm using git 2.2.1 on Mac OS X Yosemite.\n> \n> I just tried the git rebase with \"--fork-point\" added, and it works properly:\n> \n> $ git rebase upstream/our-branch-name --fork-point\n> First, rewinding head to replay your work on top of it...\n> Applying: B-07241\n> \n> While discussing with someone else, he mentioned \"poking about a bit\n> more, git rebase began defaulting to --fork-point in git 1.9, so one\n> might expect it to be there in that version\" - but we figured it might\n> be related to https://github.com/git/git/commit/1e0dacdbdb751caa5936b6d1510f5e8db4d1ed5f.\n> I upgraded my version of git, but it wasn't fixed.\n> \n> I assume he was incorrect in that git rebase uses --fork-point by default?\n\ngit-rebase assumes that if you give an explicit upstream then you want\nprecisely what you asked for.  From git-rebase(1):\n\n\tIf either <upstream> or --root is given on the command line,\n\tthen the default is `--no-fork-point`, otherwise the default is\n\t`--fork-point`.\n\n> On Tue, Mar 3, 2015 at 1:09 PM, John Keeping <john@keeping.me.uk> wrote:\n> > On Tue, Mar 03, 2015 at 12:39:31PM -0800, Mike Botsko wrote:\n> >> I'm seeing unexpected behavior between \"git pull --rebase\" and \"git\n> >> rebase\" commands, which are supposed to be (and always described as)\n> >> synonymous:\n> >>\n> >> git pull --rebase upstream our-branch-name\n> >>\n> >> and\n> >>\n> >> git fetch upstream\n> >> git rebase upstream/our-branch-name\n> >>\n> >> We have a situation where the upstream/our-branch-name was rebased, to\n> >> incorporate changes from master. Somehow, the person who did the\n> >> rebase discarded a merge commit:\n> >>\n> >> 634b622 Sue Merge pull request #254 from bob/B-07290\n> >> bc76e5b Bob [B-07290] Order Parts Ship To/Comments\n> >>\n> >> became:\n> >>\n> >> c1452be Sue [B-07290] Order Parts Ship To/Comments\n> >>\n> >>\n> >> A developer who had a local branch tried to rebase their work (a\n> >> single commit on top of that feature branch).\n> >>\n> >> At the moment, his now-out-of-date branch looks like this:\n> >>\n> >> 92b2194 Rick B-07241\n> >> 634b622 Sue Merge pull request #254 from dboyle/B-07290\n> >> bc76e5b Bob [B-07290] Order Parts Ship To/Comments\n> >>\n> >> I've done some debugging, and the above \"git pull\" command generates\n> >> the following and sends it to eval():\n> >>\n> >> git-rebase --onto c1452be62cf271a25d3d74cc63cd67eca51a127d\n> >> 634b622870a1016e717067281c7739b1fe08e08d\n> >>\n> >> This process works perfectly. The old commits are discarded and his\n> >> branch now correctly reflects upstream/our-branch-name, with his\n> >> single new commit at the top.\n> >>\n> >>\n> >> However, if he runs the \"git rebase\" command above, several of the\n> >> commits that have changed hashes (they've also changed patch id\n> >> slightly, because during the rebase someone fixed a merge conflict)\n> >> are treated as new work, and git tries to re-apply them and we get\n> >> tons of merge conflicts.\n> >>\n> >> The git rebase command above is trying to rebase onto:\n> >>\n> >> revisions = c1452be62cf271a25d3d74cc63cd67eca51a127d..92b2194e3adc29eb3fadd93ddded0ed34513d587\n> >>\n> >>\n> >> These two features should work the same, yet one is choosing a\n> >> different commit hash than the other.\n> >>\n> >> If this is not a bug, I can't find anyone who can explain what's\n> >> happening. I'm using git 2.2.1 on mac, but other people on our team\n> >> have a variety of older versions and we're all seeing the same result.\n> >\n> > What version of Git are you using?\n> >\n> > Does it work if you add the `--fork-point` argument to git-rebase?  If\n> > so, does it do the same if you just do \"git rebase\" with no arguments\n> > (see the documentation of `--fork-point` in git-rebase(1) for details of\n> > this)?\n> \n> \n> \n> -- \n> Mike Botsko\n> Lead Dev @ Helion3\n> Ph: 1-(503)-897-0155\n> --\n> To unsubscribe from this list: send the line \"unsubscribe git\" in\n> the body of a message to majordomo@vger.kernel.org\n> More majordomo info at  http://vger.kernel.org/majordomo-info.html\n"},{"id":"256947","messageId":"xmqq61ahad18.fsf@gitster.dls.corp.google.com","threadId":"38695","inReplyTo":"20150303214653.GQ890@serenity.lan","subject":"Re: Unexpected/unexplained difference between git pull --rebase and git rebase","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-03-03T23:15:15Z","receivedAt":"2015-03-03T23:15:15Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"John Keeping <john@keeping.me.uk> writes:\n\n> git-rebase assumes that if you give an explicit upstream then you want\n> precisely what you asked for.  From git-rebase(1):\n>\n> \tIf either <upstream> or --root is given on the command line,\n> \tthen the default is `--no-fork-point`, otherwise the default is\n> \t`--fork-point`.\n\nCorrect.\n\nYou ask it to rebase the history without guessing by being explicit;\nthe command guesses when you are not explicit and being lazy ;-).\n"},{"id":"256949","messageId":"CAPfvZp5jTTbWVL0QuZTP83=SWvsvyZWX0BG_q7jPLK5wNNvCgg@mail.gmail.com","threadId":"38695","inReplyTo":"xmqq61ahad18.fsf@gitster.dls.corp.google.com","subject":"Re: Unexpected/unexplained difference between git pull --rebase and git rebase","fromName":"Mike Botsko","fromEmail":"botsko@gmail.com","sentAt":"2015-03-03T23:20:48Z","receivedAt":"2015-03-03T23:20:48Z","isPatch":false,"sender":{"key":"botsko@gmail.com","avatar":"https://gravatar.com/avatar/1207322b4640c5494f9b5cf3286295100c52de97f20e228b4b31305765f6808a?d=mp&s=160"},"body":"Maybe I'm lacking the distinction regarding what I'm being specific about.\n\nIn both examples, I'm asking it specifically to rebase in changes from\nthe remote \"upstream\" and a named branch at that location. I'm giving\ngit the same information, it's just interpreting it differently - and\nI'm not understanding why.\n\nMy local branch would have been created from the\nupstream/feature-branch, and will eventually be merged back into it.\nUntil I'm ready for that, I regularly rebase the work done on\nupstream/feature-branch so that my local work is always clean and\nabove anything else.\n\n\n\nOn Tue, Mar 3, 2015 at 3:15 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> John Keeping <john@keeping.me.uk> writes:\n>\n>> git-rebase assumes that if you give an explicit upstream then you want\n>> precisely what you asked for.  From git-rebase(1):\n>>\n>>       If either <upstream> or --root is given on the command line,\n>>       then the default is `--no-fork-point`, otherwise the default is\n>>       `--fork-point`.\n>\n> Correct.\n>\n> You ask it to rebase the history without guessing by being explicit;\n> the command guesses when you are not explicit and being lazy ;-).\n>\n\n\n\n-- \nMike Botsko\nLead Dev @ Helion3\nPh: 1-(503)-897-0155\n"},{"id":"256951","messageId":"20150303234057.GR890@serenity.lan","threadId":"38695","inReplyTo":"CAPfvZp5jTTbWVL0QuZTP83=SWvsvyZWX0BG_q7jPLK5wNNvCgg@mail.gmail.com","subject":"Re: Unexpected/unexplained difference between git pull --rebase and git rebase","fromName":"John Keeping","fromEmail":"john@keeping.me.uk","sentAt":"2015-03-03T23:40:57Z","receivedAt":"2015-03-03T23:40:57Z","isPatch":false,"sender":{"key":"john@keeping.me.uk","avatar":"https://avatars.githubusercontent.com/u/1702081?v=4"},"body":"On Tue, Mar 03, 2015 at 03:20:48PM -0800, Mike Botsko wrote:\n> Maybe I'm lacking the distinction regarding what I'm being specific about.\n> \n> In both examples, I'm asking it specifically to rebase in changes from\n> the remote \"upstream\" and a named branch at that location. I'm giving\n> git the same information, it's just interpreting it differently - and\n> I'm not understanding why.\n\nNot quite.  If you say:\n\n\tgit rebase $sha1\n\nthen you're telling git-rebase to apply the commits $sha1..HEAD onto\n$sha1.\n\nIf you say:\n\n\tgit rebase\n\nthen it will be re-written as:\n\n\tgit rebase --fork-point @{upstream}\n\nin which case Git will apply more complicated logic so that you can\nrecover from the case where @{upstream} has been re-written.\n\nConsider the following scenario:\n\n                      F\t\t\tbranch\n                     /\n               C -- D\t\t\tmaster@{1}\n              /\n\tA -- B -- C' -- D' -- E\t\tmaster\n\nwhere C' and D' are rewritten versions of C and D.\n\nIn this case, imagine you are at F on \"branch\", \"git rebase master\" will\nreplace C, D and F onto E because you have explicitly selected to replay\nmaster..branch onto master.\n\n\"git rebase\" will apply the fork-point logic and realise that D is a\nprevious version of master, so it will only replay F onto E.\n\nIn general if you just want to rebase onto your upstream it is simpler\nto just call \"git rebase\" which will do the right thing; it's also\nshorter to type ;-)\n\n> My local branch would have been created from the\n> upstream/feature-branch, and will eventually be merged back into it.\n> Until I'm ready for that, I regularly rebase the work done on\n> upstream/feature-branch so that my local work is always clean and\n> above anything else.\n\nIn this case the problem stems from the fact that\nupstream/feature-branch has been rewritten.  Building on top of branches\nthat will be rewritten is not advisable unless you have a really good\nreason to do so.\n\n> On Tue, Mar 3, 2015 at 3:15 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> > John Keeping <john@keeping.me.uk> writes:\n> >\n> >> git-rebase assumes that if you give an explicit upstream then you want\n> >> precisely what you asked for.  From git-rebase(1):\n> >>\n> >>       If either <upstream> or --root is given on the command line,\n> >>       then the default is `--no-fork-point`, otherwise the default is\n> >>       `--fork-point`.\n> >\n> > Correct.\n> >\n> > You ask it to rebase the history without guessing by being explicit;\n> > the command guesses when you are not explicit and being lazy ;-).\n"},{"id":"256952","messageId":"CAPfvZp5VCd+Q2LHczqTQ08ZR+yvkGHhubRHgBSCznGQJgekadg@mail.gmail.com","threadId":"38695","inReplyTo":"20150303234057.GR890@serenity.lan","subject":"Re: Unexpected/unexplained difference between git pull --rebase and git rebase","fromName":"Mike Botsko","fromEmail":"botsko@gmail.com","sentAt":"2015-03-03T23:54:05Z","receivedAt":"2015-03-03T23:54:05Z","isPatch":false,"sender":{"key":"botsko@gmail.com","avatar":"https://gravatar.com/avatar/1207322b4640c5494f9b5cf3286295100c52de97f20e228b4b31305765f6808a?d=mp&s=160"},"body":"Thanks, that clarifies a lot.\n\nI only have two follow-up questions:\n\nIn your branch example, how does git determine that C/D have been\nrewritten and need to be \"replaced\" with their current versions\nexisting upstream? In this scenario I've encountered, the commit hash\nand the patch ID of those commits changed because the contents of the\npatches had to be modified slightly due to merge conflicts which\noccurred when the upstream branch was rebased.\n\nAlso, you mentioned \"not building off of upstream branches which might\nbe rewritten\". We generally try to avoid this but I don't see any\nalternative with the way we do things.\n\nupstream/master <- An always-clean copy of what's fully approved and live\nupstreamfeature-A\nupstreamfeature-B, etc <- Feature branches designed to organized\nlong-term new feature work\n\nIndividual developers will then create local development branches\nbased on those feature branches. If three people are responsible for\ntasks for feature-A, they'll create development branches for each\ntask, do their work, and(via github enterprise) submit a pull request\nso we can properly review their work, test it, etc.\n\nThe problem I have today stems from situations where a feature branch\nhas been merged with master. If feature-B is merged with master, and\nsomeone rebases feature-A, there may be merge conflicts. If they fix\nthe conflicts, that may alter the commit history of the feature\nbranch, which then impacts all branches developers have based on it.\n\nPart of me feels like we should be able to never rebase feature\nbranches, they should exist outside of new work merged to master.\nHowever, it's much easier to resolve merge conflicts in small doses,\nand we're in a much better position to know that we're fully updated\nand can catch other problems early.\n\nIs there a better way to do this, so that we never risk rewriting the\n\"middle tier\"?\n\n\n\nOn Tue, Mar 3, 2015 at 3:40 PM, John Keeping <john@keeping.me.uk> wrote:\n> On Tue, Mar 03, 2015 at 03:20:48PM -0800, Mike Botsko wrote:\n>> Maybe I'm lacking the distinction regarding what I'm being specific about.\n>>\n>> In both examples, I'm asking it specifically to rebase in changes from\n>> the remote \"upstream\" and a named branch at that location. I'm giving\n>> git the same information, it's just interpreting it differently - and\n>> I'm not understanding why.\n>\n> Not quite.  If you say:\n>\n>         git rebase $sha1\n>\n> then you're telling git-rebase to apply the commits $sha1..HEAD onto\n> $sha1.\n>\n> If you say:\n>\n>         git rebase\n>\n> then it will be re-written as:\n>\n>         git rebase --fork-point @{upstream}\n>\n> in which case Git will apply more complicated logic so that you can\n> recover from the case where @{upstream} has been re-written.\n>\n> Consider the following scenario:\n>\n>                       F                 branch\n>                      /\n>                C -- D                   master@{1}\n>               /\n>         A -- B -- C' -- D' -- E         master\n>\n> where C' and D' are rewritten versions of C and D.\n>\n> In this case, imagine you are at F on \"branch\", \"git rebase master\" will\n> replace C, D and F onto E because you have explicitly selected to replay\n> master..branch onto master.\n>\n> \"git rebase\" will apply the fork-point logic and realise that D is a\n> previous version of master, so it will only replay F onto E.\n>\n> In general if you just want to rebase onto your upstream it is simpler\n> to just call \"git rebase\" which will do the right thing; it's also\n> shorter to type ;-)\n>\n>> My local branch would have been created from the\n>> upstream/feature-branch, and will eventually be merged back into it.\n>> Until I'm ready for that, I regularly rebase the work done on\n>> upstream/feature-branch so that my local work is always clean and\n>> above anything else.\n>\n> In this case the problem stems from the fact that\n> upstream/feature-branch has been rewritten.  Building on top of branches\n> that will be rewritten is not advisable unless you have a really good\n> reason to do so.\n>\n>> On Tue, Mar 3, 2015 at 3:15 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>> > John Keeping <john@keeping.me.uk> writes:\n>> >\n>> >> git-rebase assumes that if you give an explicit upstream then you want\n>> >> precisely what you asked for.  From git-rebase(1):\n>> >>\n>> >>       If either <upstream> or --root is given on the command line,\n>> >>       then the default is `--no-fork-point`, otherwise the default is\n>> >>       `--fork-point`.\n>> >\n>> > Correct.\n>> >\n>> > You ask it to rebase the history without guessing by being explicit;\n>> > the command guesses when you are not explicit and being lazy ;-).\n\n\n\n-- \nMike Botsko\nLead Dev @ Helion3\nPh: 1-(503)-897-0155\n"},{"id":"256978","messageId":"20150304093554.GT890@serenity.lan","threadId":"38695","inReplyTo":"CAPfvZp5VCd+Q2LHczqTQ08ZR+yvkGHhubRHgBSCznGQJgekadg@mail.gmail.com","subject":"Re: Unexpected/unexplained difference between git pull --rebase and git rebase","fromName":"John Keeping","fromEmail":"john@keeping.me.uk","sentAt":"2015-03-04T09:35:54Z","receivedAt":"2015-03-04T09:35:54Z","isPatch":false,"sender":{"key":"john@keeping.me.uk","avatar":"https://avatars.githubusercontent.com/u/1702081?v=4"},"body":"On Tue, Mar 03, 2015 at 03:54:05PM -0800, Mike Botsko wrote:\n> Thanks, that clarifies a lot.\n> \n> I only have two follow-up questions:\n> \n> In your branch example, how does git determine that C/D have been\n> rewritten and need to be \"replaced\" with their current versions\n> existing upstream? In this scenario I've encountered, the commit hash\n> and the patch ID of those commits changed because the contents of the\n> patches had to be modified slightly due to merge conflicts which\n> occurred when the upstream branch was rebased.\n\nIt uses the reflog.  There's some discussion in git-merge-base(1) [0],\nalthough IIRC it steers away from being too explicit in case anyone\ncomes up with a way to make it more intelligent in the future.\n\nNote that this means it will only work if you are performing the rebase\nin the same repository as you originally created the branch, since in\nother repositories the original branch point may not appear in the\nreflog of the upstream.\n\n[0] http://git-scm.com/docs/git-merge-base#_discussion_on_fork_point_mode\n\n> Also, you mentioned \"not building off of upstream branches which might\n> be rewritten\". We generally try to avoid this but I don't see any\n> alternative with the way we do things.\n> \n> upstream/master <- An always-clean copy of what's fully approved and live\n> upstreamfeature-A\n> upstreamfeature-B, etc <- Feature branches designed to organized\n> long-term new feature work\n> \n> Individual developers will then create local development branches\n> based on those feature branches. If three people are responsible for\n> tasks for feature-A, they'll create development branches for each\n> task, do their work, and(via github enterprise) submit a pull request\n> so we can properly review their work, test it, etc.\n> \n> The problem I have today stems from situations where a feature branch\n> has been merged with master. If feature-B is merged with master, and\n> someone rebases feature-A, there may be merge conflicts. If they fix\n> the conflicts, that may alter the commit history of the feature\n> branch, which then impacts all branches developers have based on it.\n> \n> Part of me feels like we should be able to never rebase feature\n> branches, they should exist outside of new work merged to master.\n> However, it's much easier to resolve merge conflicts in small doses,\n> and we're in a much better position to know that we're fully updated\n> and can catch other problems early.\n> \n> Is there a better way to do this, so that we never risk rewriting the\n> \"middle tier\"?\n\nHaving two tiers of feature branches seems a bit weird to me (although I\ndo know of another group that does something similar).\n\nPerhaps a throwaway integration branch would help, which will allow you\nto let git-rerere(1) remember resolutions to merge conflicts.  The idea\nis that you periodically (say once a day or every few days) do something\nlike this:\n\n\t$ git checkout integration\n\t$ git reset --keep master\n\t$ git merge feature-A\n\t$ git merge feature-B\n\t...\n\nThen you can test the features together and get an early view of any\nconflicts that might hit when you merge them to master.\n\n<shameless-plug>\nI wrote a tool to help manage integration branches [1].\n\n[1] http://johnkeeping.github.io/git-integration/\n</shameless-plug>\n\nThere's quite a lot of discussion on branch management in\ngit-workflows(7).\n\n> On Tue, Mar 3, 2015 at 3:40 PM, John Keeping <john@keeping.me.uk> wrote:\n> > On Tue, Mar 03, 2015 at 03:20:48PM -0800, Mike Botsko wrote:\n> >> Maybe I'm lacking the distinction regarding what I'm being specific about.\n> >>\n> >> In both examples, I'm asking it specifically to rebase in changes from\n> >> the remote \"upstream\" and a named branch at that location. I'm giving\n> >> git the same information, it's just interpreting it differently - and\n> >> I'm not understanding why.\n> >\n> > Not quite.  If you say:\n> >\n> >         git rebase $sha1\n> >\n> > then you're telling git-rebase to apply the commits $sha1..HEAD onto\n> > $sha1.\n> >\n> > If you say:\n> >\n> >         git rebase\n> >\n> > then it will be re-written as:\n> >\n> >         git rebase --fork-point @{upstream}\n> >\n> > in which case Git will apply more complicated logic so that you can\n> > recover from the case where @{upstream} has been re-written.\n> >\n> > Consider the following scenario:\n> >\n> >                       F                 branch\n> >                      /\n> >                C -- D                   master@{1}\n> >               /\n> >         A -- B -- C' -- D' -- E         master\n> >\n> > where C' and D' are rewritten versions of C and D.\n> >\n> > In this case, imagine you are at F on \"branch\", \"git rebase master\" will\n> > replace C, D and F onto E because you have explicitly selected to replay\n> > master..branch onto master.\n> >\n> > \"git rebase\" will apply the fork-point logic and realise that D is a\n> > previous version of master, so it will only replay F onto E.\n> >\n> > In general if you just want to rebase onto your upstream it is simpler\n> > to just call \"git rebase\" which will do the right thing; it's also\n> > shorter to type ;-)\n> >\n> >> My local branch would have been created from the\n> >> upstream/feature-branch, and will eventually be merged back into it.\n> >> Until I'm ready for that, I regularly rebase the work done on\n> >> upstream/feature-branch so that my local work is always clean and\n> >> above anything else.\n> >\n> > In this case the problem stems from the fact that\n> > upstream/feature-branch has been rewritten.  Building on top of branches\n> > that will be rewritten is not advisable unless you have a really good\n> > reason to do so.\n> >\n> >> On Tue, Mar 3, 2015 at 3:15 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> >> > John Keeping <john@keeping.me.uk> writes:\n> >> >\n> >> >> git-rebase assumes that if you give an explicit upstream then you want\n> >> >> precisely what you asked for.  From git-rebase(1):\n> >> >>\n> >> >>       If either <upstream> or --root is given on the command line,\n> >> >>       then the default is `--no-fork-point`, otherwise the default is\n> >> >>       `--fork-point`.\n> >> >\n> >> > Correct.\n> >> >\n> >> > You ask it to rebase the history without guessing by being explicit;\n> >> > the command guesses when you are not explicit and being lazy ;-).\n> \n> \n> \n> -- \n> Mike Botsko\n> Lead Dev @ Helion3\n> Ph: 1-(503)-897-0155\n> --\n> To unsubscribe from this list: send the line \"unsubscribe git\" in\n> the body of a message to majordomo@vger.kernel.org\n> More majordomo info at  http://vger.kernel.org/majordomo-info.html\n"}]}