1From: Junio C Hamano <junkio@cox.net> 2To: git@vger.kernel.org 3Cc: Petr Baudis <pasky@suse.cz>, Linus Torvalds <torvalds@osdl.org> 4Subject: Re: sending changesets from the middle of a git tree 5Date: Sun, 14 Aug 2005 18:37:39 -0700 6Abstract: In this article, JC talks about how he rebases the 7 public "pu" branch using the core GIT tools when he updates 8 the "master" branch, and how "rebase" works. Also discussed 9 is how this applies to individual developers who sends patches 10 upstream. 11 12Petr Baudis <pasky@suse.cz> writes: 13 14> Dear diary, on Sun, Aug 14, 2005 at 09:57:13AM CEST, I got a letter 15> where Junio C Hamano <junkio@cox.net> told me that... 16>> Linus Torvalds <torvalds@osdl.org> writes: 17>> 18>> > Junio, maybe you want to talk about how you move patches from your "pu" 19>> > branch to the real branches. 20>> 21> Actually, wouldn't this be also precisely for what StGIT is intended to? 22 23Exactly my feeling. I was sort of waiting for Catalin to speak 24up. With its basing philosophical ancestry on quilt, this is 25the kind of task StGIT is designed to do. 26 27I just have done a simpler one, this time using only the core 28GIT tools. 29 30I had a handful commits that were ahead of master in pu, and I 31wanted to add some documentation bypassing my usual habit of 32placing new things in pu first. At the beginning, the commit 33ancestry graph looked like this: 34 35 *"pu" head 36 master --> #1 --> #2 --> #3 37 38So I started from master, made a bunch of edits, and committed: 39 40 $ git checkout master 41 $ cd Documentation; ed git.txt ... 42 $ cd ..; git add Documentation/*.txt 43 $ git commit -s 44 45After the commit, the ancestry graph would look like this: 46 47 *"pu" head 48 master^ --> #1 --> #2 --> #3 49 \ 50 \---> master 51 52The old master is now master^ (the first parent of the master). 53The new master commit holds my documentation updates. 54 55Now I have to deal with "pu" branch. 56 57This is the kind of situation I used to have all the time when 58Linus was the maintainer and I was a contributor, when you look 59at "master" branch being the "maintainer" branch, and "pu" 60branch being the "contributor" branch. Your work started at the 61tip of the "maintainer" branch some time ago, you made a lot of 62progress in the meantime, and now the maintainer branch has some 63other commits you do not have yet. And "git rebase" was written 64with the explicit purpose of helping to maintain branches like 65"pu". You _could_ merge master to pu and keep going, but if you 66eventually want to cherrypick and merge some but not necessarily 67all changes back to the master branch, it often makes later 68operations for _you_ easier if you rebase (i.e. carry forward 69your changes) "pu" rather than merge. So I ran "git rebase": 70 71 $ git checkout pu 72 $ git rebase master pu 73 74What this does is to pick all the commits since the current 75branch (note that I now am on "pu" branch) forked from the 76master branch, and forward port these changes. 77 78 master^ --> #1 --> #2 --> #3 79 \ *"pu" head 80 \---> master --> #1' --> #2' --> #3' 81 82The diff between master^ and #1 is applied to master and 83committed to create #1' commit with the commit information (log, 84author and date) taken from commit #1. On top of that #2' and #3' 85commits are made similarly out of #2 and #3 commits. 86 87Old #3 is not recorded in any of the .git/refs/heads/ file 88anymore, so after doing this you will have dangling commit if 89you ran fsck-cache, which is normal. After testing "pu", you 90can run "git prune" to get rid of those original three commits. 91 92While I am talking about "git rebase", I should talk about how 93to do cherrypicking using only the core GIT tools. 94 95Let's go back to the earlier picture, with different labels. 96 97You, as an individual developer, cloned upstream repository and 98made a couple of commits on top of it. 99 100 *your "master" head 101 upstream --> #1 --> #2 --> #3 102 103You would want changes #2 and #3 incorporated in the upstream, 104while you feel that #1 may need further improvements. So you 105prepare #2 and #3 for e-mail submission. 106 107 $ git format-patch master^^ master 108 109This creates two files, 0001-XXXX.patch and 0002-XXXX.patch. Send 110them out "To: " your project maintainer and "Cc: " your mailing 111list. You could use contributed script git-send-email if 112your host has necessary perl modules for this, but your usual 113MUA would do as long as it does not corrupt whitespaces in the 114patch. 115 116Then you would wait, and you find out that the upstream picked 117up your changes, along with other changes. 118 119 where *your "master" head 120 upstream --> #1 --> #2 --> #3 121 used \ 122 to be \--> #A --> #2' --> #3' --> #B --> #C 123 *upstream head 124 125The two commits #2' and #3' in the above picture record the same 126changes your e-mail submission for #2 and #3 contained, but 127probably with the new sign-off line added by the upstream 128maintainer and definitely with different committer and ancestry 129information, they are different objects from #2 and #3 commits. 130 131You fetch from upstream, but not merge. 132 133 $ git fetch upstream 134 135This leaves the updated upstream head in .git/FETCH_HEAD but 136does not touch your .git/HEAD nor .git/refs/heads/master. 137You run "git rebase" now. 138 139 $ git rebase FETCH_HEAD master 140 141Earlier, I said that rebase applies all the commits from your 142branch on top of the upstream head. Well, I lied. "git rebase" 143is a bit smarter than that and notices that #2 and #3 need not 144be applied, so it only applies #1. The commit ancestry graph 145becomes something like this: 146 147 where *your old "master" head 148 upstream --> #1 --> #2 --> #3 149 used \ your new "master" head* 150 to be \--> #A --> #2' --> #3' --> #B --> #C --> #1' 151 *upstream 152 head 153 154Again, "git prune" would discard the disused commits #1-#3 and 155you continue on starting from the new "master" head, which is 156the #1' commit. 157 158-jc 159 160- 161To unsubscribe from this list: send the line "unsubscribe git" in 162the body of a message to majordomo@vger.kernel.org 163More majordomo info at http://vger.kernel.org/majordomo-info.html