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