{"thread":{"id":"37496","subject":"git rebase: yet another newbie quest.","startedAt":"2014-09-05T10:28:46Z","lastAt":"2014-09-08T19:49:25Z","messageCount":9,"participants":["Sergey Organov","Theodore Ts'o","John Keeping"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"248898","messageId":"87a96ecqe9.fsf@osv.gnss.ru","threadId":"37496","inReplyTo":null,"subject":"git rebase: yet another newbie quest.","fromName":"Sergey Organov","fromEmail":"sorganov@gmail.com","sentAt":"2014-09-05T10:28:46Z","receivedAt":"2014-09-05T10:28:46Z","isPatch":false,"sender":{"key":"sorganov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8501568?v=4"},"body":"Hello,\n\nCaveat: this is somewhat long, sorry.\n\nRecently I've run into yet another rather tricky trouble with\npull/rebase. No, neither of my troubles is in the usual \"rewriting\npublished history\" group.\n\n(The first trouble I ran earlier was caused by the fact that \"git pull\"\nbreaks local merges when \"pull.rebase\" configuration variable is set to\n\"true\".)\n\nBelow is shell script to create test repo that shows the steps I did\nthat lead me to the trouble, along with explanations why I did them.\nThen follows description of the actual quest I ran through to figure a\nwork-around.\n\nI must admit I still don't know what I should have done differently in\nthe script below to avoid this problem in the first place, nor do I\nentirely understood what git is doing.\n\n$ git --version\ngit version 1.9.3\n\n----- 8< -----  Test repo creation ----- 8< -----\n\n#!/bin/sh\n\n# Git output is prefixed with '#> \" below\n\n# Prepare some initial state for the show. Create 2 files to be changed\n# in 2 different branches to avoid content conflicts later.\n\ngit init t\ncd t\necho A > a\necho B > b\ngit add a b\ngit commit -m \"A\" -a\n\n# Pretend we have some origin/master. It was really the case in the\n# original scenario. Here I just set a tag instead, as it doesn't\n# change the outcome.\n\ngit tag origin_master\n\n# OK. Here we start. On the branch 'master' (that tracked origin/master in\n# original scenario) I do some small change:\n\necho B >> b\ngit commit -m B -a\n\n# Then I realize I need more changes and it gets complex enough to\n# warrant a topic branch. I create the 'topic' branch that will track\n# 'master' branch and reset 'master' back to its origin (remote\n# origin/master in original scenario).\n\ngit checkout -b topic\ngit branch --force master origin_master\ngit branch -u master\n\n# Now I do more work on the topic branch...\n\necho C >> b\ngit commit -m C -a\n\n# Meanwhile something non-conflicting (in another file) changed upstream...\n\ngit checkout master\necho A >> a\ngit commit -m D -a\ngit checkout topic\n\n----- >8 -----  Test repo creation end ----- >8 -----\n\nThe creation of the test setup complete, we end-up with the following\nsimple history:\n\n$ git log --all --oneline --graph --decorate\n* 335fc12 (master) D\n| * 2cefe9f (HEAD, topic) C\n| * aed3006 B\n|/\n* 951b15b (tag: origin_master) A\n$\n\nAnd my 'topic' branch is set to track 'master':\n\n$ git branch -vv --list topic\n* topic 2cefe9f [master: ahead 2, behind 1] C\n\nExactly what I wanted to achieve. Now we are ready to go to the essence\nof the quest.\n\nBeing on the 'topic' branch I pull from upstream, rebasing. Can you\nguess what I expectated? Yeah, something as simple as B and C being\nrebased on top of D, like this:\n\n> $ git pull --rebase\n> ...\n> $ git log --all --oneline --graph --decorate\n> * xxxxxxx (HEAD, topic) C\n> * xxxxxxx B\n> * 335fc12 (master) D\n> * 951b15b (tag: origin_master) A\n\nHere is what I got instead:\n\n$ git pull --rebase\nFrom .\n * branch            master     -> FETCH_HEAD\nFirst, rewinding head to replay your work on top of it...\nApplying: C\nUsing index info to reconstruct a base tree...\nM\tb\nFalling back to patching base and 3-way merge...\nAuto-merging b\nCONFLICT (content): Merge conflict in b\nRecorded preimage for 'b'\nFailed to merge in the changes.\nPatch failed at 0001 C\nThe copy of the patch that failed is found in:\n   /home/osv/f/t/t/.git/rebase-apply/patch\n\nWhen you have resolved this problem, run \"git rebase --continue\".\nIf you prefer to skip this patch, run \"git rebase --skip\" instead.\nTo check out the original branch and stop rebasing, run \"git rebase --abort\".\n\n$\n\nWait... Conflict?! That's unexpected. Let's first get back to a sane state:\n\n$ git rebase --abort\n$\n\nI suspect it's not easy to figure what happens here, even having this\nsimple imitation. It was even harder in real life as there were a lot of\nunrelated things happening simultaneously.\n\nWhat I did:\n\nLooking closer at the \"git rebase\" output, it applies C, but not (yet?)\nB. Why doesn't it apply B?\n\nLet's first exclude \"git pull\" from the equation:\n\n$ git rebase\n...\n$\n\nStill the same outcome as with 'git pull --rebase\" above -- at least git\nis consistent at kicking me into the stomach ;-) Good...\n\nLet's figure how to check which commits are to be rebased:\n\n$ git help rebase\n\n \"...\n  This is the same set of commits that would be shown by\n  git log <upstream>..HEAD\"\n\n$ git rebase --abort\n$ git log --oneline master..HEAD\n2cefe9f C\naed3006 B\n$\n\nSo it should apply B and C, but only applies C. The manual lies?\nUnlikely. Let's dig more into the manual... Ah, maybe here it is:\n\n \"Note that any commits in HEAD which introduce the same textual\n  changes as a commit in HEAD..<upstream> are omitted \"\n\nCheck...\n\n$ git log --oneline HEAD..master\n335fc12 D\n$\n\nNo, there is no way missed commit 'B' textually matches commit 'D'.\n\nWondering further... let's try to specify <upstream> explicitly:\n\n$ git --rebase master\nFirst, rewinding head to replay your work on top of it...\nApplying: B\nApplying: C\n$\n\nWow! This way it works! But the manual says:\n\n \"If <upstream> is not specified, the upstream configured in\n  branch.<name>.remote and branch.<name>.merge options will be\n  used; see git-config(1) for details.\"\n\nDid I mis-configured <upstream>? Check:\n\n$ git config --list | grep topic\nbranch.topic.remote=.\nbranch.topic.merge=refs/heads/master\n$\n\n# So it's 'refs/heads/master'. I always thought I can say just 'master',\n# but let's see if it suddenly matters in this case?:\n\n$ git reset --hard @{1} # First get to pre-rebase state\nHEAD is now at 2cefe9f C\n$ git --rebase refs/heads/master\nFirst, rewinding head to replay your work on top of it...\nApplying: B\nApplying: C\n$\n\nStill different from what vanilla \"git rebase\" does. So, what's next?\nHow do I figure what exactly it does? Searching for \"debug\", \"verbose\",\n\"dry-run\", or something like that in the manual page. Well, there is\n'-v', try it:\n\n$ git reset --hard @{1}\nHEAD is now at 2cefe9f C\n$ git rebase -v\nChanges from 951b15b8bfd6dee3d22ed1c48b0d2947aefac346 to 335fc12a2ddd175a22e086a08492ceda1280fd9f:\n a | 1 +\n 1 file changed, 1 insertion(+)\nFirst, rewinding head to replay your work on top of it...\nApplying: C\nUsing index info to reconstruct a base tree...\nM\tb\nFalling back to patching base and 3-way merge...\nAuto-merging b\nCONFLICT (content): Merge conflict in b\nRecorded preimage for 'b'\nFailed to merge in the changes.\nPatch failed at 0001 C\nThe copy of the patch that failed is found in:\n   /home/osv/f/t/t/.git/rebase-apply/patch\n\nWhen you have resolved this problem, run \"git rebase --continue\".\nIf you prefer to skip this patch, run \"git rebase --skip\" instead.\nTo check out the original branch and stop rebasing, run \"git rebase --abort\".\n\n$\n\nDoesn't help either, no luck.\n\nWell, how does it calculate the set of commits? Probably it has\nsomething to do with merge-base? (Yeah, I already knew about merge-base\nas I wrote script to convert our CVS repository to git and learned a few\nthings on the way, so I'm not entirely newbie.)\n\n$ git help merge-base\n...\n\nAnd there, right in SYNOPSIS, the --fork-point catches my attention.\nReading its description:\n\n--fork-point\n    Find the point at which a branch (or any history that leads to\n    <commit>) forked from another branch (or any reference) <ref>. This\n    does not just look for the common ancestor of the two commits, but\n    also takes into account the reflog of <ref> to see if the history\n    leading to <commit> forked from an earlier incarnation of the branch\n    <ref> (see discussion on this mode below). :\n\nIt definitely clicks! Let's look for --fork-point in the\n\n$ git help rebase\n\nYeah, it's there!\n\n--fork-point, --no-fork-point\n    Use git merge-base --fork-point to find a better common ancestor\n    between upstream and branch when calculating which commits have have\n    been introduced by branch (see git-merge-base(1)).\n\n    If no non-option arguments are given on the command line, then the\n    default is --fork-point @{u} otherwise the upstream argument is\n    interpreted literally unless the --fork-point option is specified.\n\n\nSo, this last paragraph, hidden deep in the middle of the lengthy git\nrebase manual page, brings us the answer:\n\n\"git rebase\"      ==  \"git rebase --fork-point @{u}\"\n\nwhile\n\n\"git rebase @{u}\" ==  \"git rebase --no-fork-point @{u}\"\n\nSurprise!\n\nAnd the set of commits vanilla \"git rebase\" will rebase could apparently\nbe rather different from those output by\n\n\"git log @{u}..HEAD\"\n\nthat the manual unconditionally claims in the DESCRIPTION.\n\n... And after I wrote the above, out of curiosity I tried the following\n(I've already re-created the test repo, so SHA1s won't match):\n\n$ git pull --no-rebase --no-edit\nFrom .\n * branch            master     -> FETCH_HEAD\nMerge made by the 'recursive' strategy.\n a | 1 +\n 1 file changed, 1 insertion(+)\n$ git pull --rebase\nFrom .\n * branch            master     -> FETCH_HEAD\nFirst, rewinding head to replay your work on top of it...\nApplying: B\nApplying: C\n$\n\nSo, if I first do pull/merge, then pull/rebase suddenly starts to do\nwhat I asked it to do in the first place! That throws me back right into\nthe middle of the quest!\n\n$ git reset --hard @{1}\nHEAD is now at ed1ff0f Merge branch 'master' into topic\n$ git log $(git merge-base --fork-point @{u} HEAD)..HEAD\n<no output>\n$ git merge-base --fork-point @{u} HEAD\n<no output>\n$ git log --one-line ${u}..HEAD\ned1ff0f Merge branch 'master' into topic\nff4d9fa C\ne326c16 B\n$\n\nSo, when there is no fork-point found, vanilla \"git rebase\" behaves as\nif it were \"git rebase @{u}\"? I still neither understand what exactly\nhappens here, nor what all this --fork-point business is all about in\nthe first place.\n\nHow comes fork point disappears because of merge, and is it OK that\n'merge-base --fork-point' produces no output at all when vanilla\n'merge-base' does?\n\nCould somebody please fix the manual page to explain what \"git rebase\"\nis actually doing? I mean somebody who, unlike me, actually knows,\n\nAlso, what should I have done differently in the script above to avoid\nthe problem in the first place? Is it git bug I stumbled over?\n\nP.S. On the positive side, it reminded me playing good old Larry game in\n     the early 90's :-)\n\n-- \nSergey.\n"},{"id":"248901","messageId":"20140905154159.GB1510@thunk.org","threadId":"37496","inReplyTo":"87a96ecqe9.fsf@osv.gnss.ru","subject":"Re: git rebase: yet another newbie quest.","fromName":"Theodore Ts'o","fromEmail":"tytso@mit.edu","sentAt":"2014-09-05T15:41:59Z","receivedAt":"2014-09-05T15:41:59Z","isPatch":false,"sender":{"key":"tytso@mit.edu","avatar":"https://avatars.githubusercontent.com/u/51416?v=4"},"body":"I'm not going to say what you *should* have done, since it's not clear\nwhether anything close to what you were doing is a supported workflow.\nBut I can tell you what I *do* myself.  Personally, I vastly distrust\ngit pull --rebase.\n\nSo in general, my pulls are all the equivalent of \"git pull\n--ff-only\", and if I want to rebase the topic branch (which in\ngeneral, is a bad idea to do regularly; I will generally not do it at\nall until I'm almost done).  So I'll branch the topic branch off of\norigin (which tracks origin/master, typically):\n\ngit checkout -b topic1 origin\n<hack hack hack>\ngit commit\n    .\n    .\n    .\n\n\nThen I might do something like this to do a build:\n\ngit fetch origin ; git branch -f origin origin/master    # this is optional\ngit checkout -B build origin\ngit merge topic1\ngit merge topic2\n    ...\n<make>\n\nIn general, I will only rebase a topic branch when it's needed to fix\na serious conflcit caused by significant changes upstream.  And in\nthat case, I might do something like this:\n\ngit checkout topic1\ngit rebase origin/master\n<make>\n<make check>\n\n\nThis basically goes to a philosophical question of whether it's\nsimpler to tell users to use a single command, such as \"git pull\n--rebase\", or whether to tell users to use a 2 or 3 commands that\nconceptually much more simple.  Personally, I type fast enough that I\ntend to use simple commands, and not try to use things like automated\nbranch tracking.  That way I don't have to strain my brain thinking\nabout things like \"fork points\".  :-)\n\nOTOH, some people feel that it's better to make things like \"git pull\n--rebase\" work and do the right thing automatically, because\n<competing DSCM> allows you to do it in a single command.  And indeed,\nif you use \"git pull --rebase\" without any topic branches, it works\nfine.  But then when you start wanting to do things that are more\ncomplicated, the automated command starts getting actually harder and\nmore confusing (at least in my opinion).  \n\nI don't know if a workflow involving topic branches was even expected\nto work with \"git pull --rebase\", and if so, how to set things up so\nthat they do work smoothly.  All I know is that the issue never arises\nwith me, because it's rare that I use git pull, let alone git pull\n--rebase.  That's because I usually like to take a quick look at what\nI've pulled (using gitk, or git log) before do the merge operation.\n\nIf I'm doing a pull from a repo that I control, and so I think I'm\nsure I know what's there, I might skip the \"git fetch\", and do a \"git\npull --ff-only\" instead.  But in general I prefer to do the merging\nseparate from the pull operation.\n\nCheers,\n\n\t\t\t\t\t\t- Ted\n\nP.S.  There is a separate, and completely valid discussion which is\nhow to prevent a newbie from falling into a same trap you did.  I'll\ndefer that discussion to others...\n"},{"id":"248937","messageId":"20140905221336.GB701@serenity.lan","threadId":"37496","inReplyTo":"87a96ecqe9.fsf@osv.gnss.ru","subject":"Re: git rebase: yet another newbie quest.","fromName":"John Keeping","fromEmail":"john@keeping.me.uk","sentAt":"2014-09-05T22:13:36Z","receivedAt":"2014-09-05T22:13:36Z","isPatch":false,"sender":{"key":"john@keeping.me.uk","avatar":"https://avatars.githubusercontent.com/u/1702081?v=4"},"body":"On Fri, Sep 05, 2014 at 02:28:46PM +0400, Sergey Organov wrote:\n...\n> # Then I realize I need more changes and it gets complex enough to\n> # warrant a topic branch. I create the 'topic' branch that will track\n> # 'master' branch and reset 'master' back to its origin (remote\n> # origin/master in original scenario).\n> \n> git checkout -b topic\n> git branch --force master origin_master\n\nThis line is the problem, because the purpose of the `--fork-point`\nargument to `git rebase` is designed to help people recover from\nupstream rebases, which is essentially what you create here.  So when\nrebase calculates the local changes it realises (from the reflog) that\nthe state of master before this command was before you created the\nbranch, so only commits after it should be picked.\n\nFor the case when the upstream of a branch is remote, this is normally\nwhat you want.\n"},{"id":"249034","messageId":"87tx4i8bk1.fsf@osv.gnss.ru","threadId":"37496","inReplyTo":"20140905221336.GB701@serenity.lan","subject":"Re: git rebase: yet another newbie quest.","fromName":"Sergey Organov","fromEmail":"sorganov@gmail.com","sentAt":"2014-09-08T13:51:58Z","receivedAt":"2014-09-08T13:51:58Z","isPatch":false,"sender":{"key":"sorganov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8501568?v=4"},"body":"John Keeping <john@keeping.me.uk> writes:\n\n> On Fri, Sep 05, 2014 at 02:28:46PM +0400, Sergey Organov wrote:\n> ...\n>> # Then I realize I need more changes and it gets complex enough to\n>> # warrant a topic branch. I create the 'topic' branch that will track\n>> # 'master' branch and reset 'master' back to its origin (remote\n>> # origin/master in original scenario).\n>> \n>> git checkout -b topic\n>> git branch --force master origin_master\n>\n> This line is the problem, because the purpose of the `--fork-point`\n> argument to `git rebase` is designed to help people recover from\n> upstream rebases, which is essentially what you create here.  So when\n> rebase calculates the local changes it realises (from the reflog) that\n> the state of master before this command was before you created the\n> branch, so only commits after it should be picked.\n\nThanks, but I did realize it myself (after I spent a few hours figuiring\nit out). The question is what should I have done instead?\n\n-- \nSergey.\n"},{"id":"249035","messageId":"87sik28bir.fsf@osv.gnss.ru","threadId":"37496","inReplyTo":"20140905154159.GB1510@thunk.org","subject":"Re: git rebase: yet another newbie quest.","fromName":"Sergey Organov","fromEmail":"sorganov@gmail.com","sentAt":"2014-09-08T13:52:44Z","receivedAt":"2014-09-08T13:52:44Z","isPatch":false,"sender":{"key":"sorganov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8501568?v=4"},"body":"Theodore Ts'o <tytso@mit.edu> writes:\n> I'm not going to say what you *should* have done, since it's not clear\n> whether anything close to what you were doing is a supported workflow.\n> But I can tell you what I *do* myself.  Personally, I vastly distrust\n> git pull --rebase.\n\nThank you for sharing your experience!\n\nIn the particular case at hand though, \"git rebase\" is the actual cause\nof the problem, not \"git pull --rebase\".\n\n> So in general, my pulls are all the equivalent of \"git pull\n> --ff-only\", and if I want to rebase the topic branch (which in\n> general, is a bad idea to do regularly; I will generally not do it at\n> all until I'm almost done).  So I'll branch the topic branch off of\n> origin (which tracks origin/master, typically):\n>\n> git checkout -b topic1 origin\n> <hack hack hack>\n> git commit\n>\n>   ...\n> <make>\n>\n> In general, I will only rebase a topic branch when it's needed to fix\n> a serious conflcit caused by significant changes upstream.  And in\n> that case, I might do something like this:\n>\n> git checkout topic1\n> git rebase origin/master\n> <make>\n> <make check>\n\nYeah, it's a good way to do things, but for most of quick fixes I'm lazy\nto create topic branch, and in this case it lead to a nasty unexpected\ntrouble.\n\nI didn't intend to make topic branch from the very beginning, and\nalready made a commit or two on the remote tracking branch bofore I\nrealized I'd better use topic branch. It'd create no problem as far as I\ncan see, provided vanilla \"git rebase\" has \"sane\" defaults. That said,\nI've already been once pointed to by Junio that my definition of \"sane\"\ndoesn't take into account workflows of others, so now I try to be\ncarefull calling vanilla \"git rebase\" names.\n\nPlease also notice that I didn't pull immediately after I've re-arranged\nmy branches, and this fact only made it more difficult to find and\nisolate the problem.\n\n[...]\n\n> P.S.  There is a separate, and completely valid discussion which is\n> how to prevent a newbie from falling into a same trap you did.  I'll\n> defer that discussion to others...\n\nYeah, it'd be fine if at least documentation is fixed.\n\n-- \nSergey.\n"},{"id":"249037","messageId":"20140908140758.GI1066@thunk.org","threadId":"37496","inReplyTo":"87sik28bir.fsf@osv.gnss.ru","subject":"Re: git rebase: yet another newbie quest.","fromName":"Theodore Ts'o","fromEmail":"tytso@mit.edu","sentAt":"2014-09-08T14:07:58Z","receivedAt":"2014-09-08T14:07:58Z","isPatch":false,"sender":{"key":"tytso@mit.edu","avatar":"https://avatars.githubusercontent.com/u/51416?v=4"},"body":"On Mon, Sep 08, 2014 at 05:52:44PM +0400, Sergey Organov wrote:\n> \n> I didn't intend to make topic branch from the very beginning, and\n> already made a commit or two on the remote tracking branch bofore I\n> realized I'd better use topic branch. It'd create no problem as far as I\n> can see, provided vanilla \"git rebase\" has \"sane\" defaults. That said,\n> I've already been once pointed to by Junio that my definition of \"sane\"\n> doesn't take into account workflows of others, so now I try to be\n> carefull calling vanilla \"git rebase\" names.\n\nRight, so what I typically in that situation is the following:\n\n<on the master branch>\n<hack hack hack>\ngit commit\n<hack hack hack>\ngit commit\n<oops, I should have created a topic branch>\ngit checkout -b topic-branch\ngit branch -f master origin/msater\n\nThis resets the master branch to only have what is in the upstream\ncommit.\n\n> Please also notice that I didn't pull immediately after I've re-arranged\n> my branches, and this fact only made it more difficult to find and\n> isolate the problem.\n\nIt's also the case that I rarely will do a \"git rebase\" without taking\na look at the branches to make sure it will do what I expect.  I'll do\nthat using either \"gitk\" or \"git lgt\", where git lgt is defined in my\n.gitconfig as:\n\n[alias]\n\tlgt = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%Creset' --abbrev-commit\n\nAnd typically what I will do is something like this:\n\ngitk -20 master origin/master topic\n\n-or-\n\ngit lgt -20 master origin/master topic\n\nThe \"git lgt\" command is very handy when I want to see how the\nbranches are arranged, and I'm logged remotely over ssh/tmux or some\nsuch, so gitk isn't really available to me.\n\nCheers,\n\n\t\t\t\t\t\t- Ted\n"},{"id":"249041","messageId":"87fvg23yhx.fsf@osv.gnss.ru","threadId":"37496","inReplyTo":"20140908140758.GI1066@thunk.org","subject":"Re: git rebase: yet another newbie quest.","fromName":"Sergey Organov","fromEmail":"sorganov@gmail.com","sentAt":"2014-09-08T15:47:38Z","receivedAt":"2014-09-08T15:47:38Z","isPatch":false,"sender":{"key":"sorganov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8501568?v=4"},"body":"Theodore Ts'o <tytso@mit.edu> writes:\n\n> On Mon, Sep 08, 2014 at 05:52:44PM +0400, Sergey Organov wrote:\n>> \n>> I didn't intend to make topic branch from the very beginning, and\n>> already made a commit or two on the remote tracking branch bofore I\n>> realized I'd better use topic branch. It'd create no problem as far as I\n>> can see, provided vanilla \"git rebase\" has \"sane\" defaults. That said,\n>> I've already been once pointed to by Junio that my definition of \"sane\"\n>> doesn't take into account workflows of others, so now I try to be\n>> carefull calling vanilla \"git rebase\" names.\n>\n> Right, so what I typically in that situation is the following:\n>\n> <on the master branch>\n> <hack hack hack>\n> git commit\n> <hack hack hack>\n> git commit\n> <oops, I should have created a topic branch>\n> git checkout -b topic-branch\n> git branch -f master origin/msater\n>\n> This resets the master branch to only have what is in the upstream\n> commit.\n\nBut that's *exactly* what lead me to the problem! Here is relevant part\nof my script:\n\ngit checkout -b topic\ngit branch --force master origin_master\ngit branch -u master\n\nexcept that I wanted to configure upstream as well for the topic-branch,\nthat looks like pretty legit desire. If I didn't, I'd need to specify\nupstream explicitly in the \"git rebase\", and I'd not notice the problem\nat all, as the actual problem is that \"git rebase\" and \"git rebase\n<upstream>\" work differently!\n\n-- Sergey.\n\nP.S. Nice 'lgt' alias, BTW. I simply use:\n\n$ git help hist\ngit hist' is aliased to `log --oneline --graph --decorate'\n\nstolen somewhere.\n"},{"id":"249046","messageId":"20140908173251.GA24855@thunk.org","threadId":"37496","inReplyTo":"87fvg23yhx.fsf@osv.gnss.ru","subject":"Re: git rebase: yet another newbie quest.","fromName":"Theodore Ts'o","fromEmail":"tytso@mit.edu","sentAt":"2014-09-08T17:32:51Z","receivedAt":"2014-09-08T17:32:51Z","isPatch":false,"sender":{"key":"tytso@mit.edu","avatar":"https://avatars.githubusercontent.com/u/51416?v=4"},"body":"On Mon, Sep 08, 2014 at 07:47:38PM +0400, Sergey Organov wrote:\n> \n> except that I wanted to configure upstream as well for the topic-branch,\n> that looks like pretty legit desire. If I didn't, I'd need to specify\n> upstream explicitly in the \"git rebase\", and I'd not notice the problem\n> at all, as the actual problem is that \"git rebase\" and \"git rebase\n> <upstream>\" work differently!\n\nRight, so I never do that.  I have master track origin/master, where\nit automagically does the right thing, but I'm not even sure I can\narticulate what it *means* to have topic also track origin/master.  I\njust don't have a mental model for it, and so it falls in the category\nof \"it's too complicated for my simple brain to figure out\".\n\nSo I just do \"git rebase master\", and I would never even *consider*\ndoing a \"git pull --rebase\".  I'll do a \"git fetch\", and then look at\nwhat just landed, and and then checkout master, update it to\norigin/master, and then run the regression tests to make sure what\njust came in from outside actually was *sane*, and only then would I\ndo a \"git checkout topic; git rebase master\", and then re-run the\nregression tests a third time.\n\nOtherwise, how would I know whether the regression came in from\norigin/master, or from my topic branch, or from the result of rebasing\nthe topic branch on top of origin/master?\n\nAnd of course, this goes back to my observation that I don't rebase my\ntopic branchs all that often anyway, just because the moment you do\nthe rebase, you've invalidated all of the testing that you've done to\ndate.  In fact, some upstreams will tell explicitly tell you to never\nrebase a topic branch before you ask them to pull it in, unless you\nneed to handle some non-trivial merge conflict.\n\nCheers,\n\n\t\t\t\t\t\t- Ted\n"},{"id":"249059","messageId":"87egvlzyd6.fsf@osv.gnss.ru","threadId":"37496","inReplyTo":"20140908173251.GA24855@thunk.org","subject":"Re: git rebase: yet another newbie quest.","fromName":"Sergey Organov","fromEmail":"sorganov@gmail.com","sentAt":"2014-09-08T19:49:25Z","receivedAt":"2014-09-08T19:49:25Z","isPatch":false,"sender":{"key":"sorganov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8501568?v=4"},"body":"Theodore Ts'o <tytso@mit.edu> writes:\n\n> On Mon, Sep 08, 2014 at 07:47:38PM +0400, Sergey Organov wrote:\n>> \n>> except that I wanted to configure upstream as well for the topic-branch,\n>> that looks like pretty legit desire. If I didn't, I'd need to specify\n>> upstream explicitly in the \"git rebase\", and I'd not notice the problem\n>> at all, as the actual problem is that \"git rebase\" and \"git rebase\n>> <upstream>\" work differently!\n>\n> Right, so I never do that.  I have master track origin/master, where\n> it automagically does the right thing, but I'm not even sure I can\n> articulate what it *means* to have topic also track origin/master.\n\nYou got it somewhat wrong. I intended 'topic' to track 'master', not\n'origin/master'.\n\n> I just don't have a mental model for it, and so it falls in the category\n> of \"it's too complicated for my simple brain to figure out\".\n\nI thought it's rather common for one local branch to track another in\nthe git world. At least all machinery is there, and I don't see how\ntracking local branch is different from tracking remote branch,\nfundamentally.\n\n> So I just do \"git rebase master\", and I would never even *consider*\n> doing a \"git pull --rebase\".  I'll do a \"git fetch\", and then look at\n> what just landed, and and then checkout master, update it to\n> origin/master, and then run the regression tests to make sure what\n> just came in from outside actually was *sane*, and only then would I\n> do a \"git checkout topic; git rebase master\", and then re-run the\n> regression tests a third time.\n\nYeah, and I simply wanted to shorten it to \"git checkout topic; git\nrebase\", by making git remember I want to rebase w.r.t. 'master' by\ndefault. \n\n> Otherwise, how would I know whether the regression came in from\n> origin/master, or from my topic branch, or from the result of rebasing\n> the topic branch on top of origin/master?\n\nAs far as I can see, what I did is almost exactly what you do, except I\ndidn't want to tell \"master\" every time I want to rebase 'topic' branch.\nConfiguring tracking branch and saying just \"git rebase\" when you are on\nthe branch seems to be logical, and there doesn't seem to be anything\nwrong with it (except strange git default behavior), or does it?\n\n> And of course, this goes back to my observation that I don't rebase my\n> topic branchs all that often anyway, just because the moment you do\n> the rebase, you've invalidated all of the testing that you've done to\n> date.  In fact, some upstreams will tell explicitly tell you to never\n> rebase a topic branch before you ask them to pull it in, unless you\n> need to handle some non-trivial merge conflict.\n\nThat's good advice indeed, but it's unrelated to the issue at hand, as you\nstill rebase, sooner or later.\n\n-- \nSergey.\n"}]}