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