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