]>
Commit | Line | Data |
---|---|---|
59eb68aa | 1 | From: Junio C Hamano <gitster@pobox.com> |
5b766ea9 KE |
2 | Subject: Separating topic branches |
3 | Abstract: In this article, JC describes how to separate topic branches. | |
1797e5c5 TA |
4 | Content-type: text/asciidoc |
5 | ||
6 | How to separate topic branches | |
7 | ============================== | |
5b766ea9 KE |
8 | |
9 | This text was originally a footnote to a discussion about the | |
10 | behaviour of the git diff commands. | |
11 | ||
12 | Often I find myself doing that [running diff against something other | |
13 | than HEAD] while rewriting messy development history. For example, I | |
14 | start doing some work without knowing exactly where it leads, and end | |
15 | up with a history like this: | |
16 | ||
17 | "master" | |
18 | o---o | |
a6080a0a | 19 | \ "topic" |
5b766ea9 KE |
20 | o---o---o---o---o---o |
21 | ||
22 | At this point, "topic" contains something I know I want, but it | |
23 | contains two concepts that turned out to be completely independent. | |
24 | And often, one topic component is larger than the other. It may | |
25 | contain more than two topics. | |
26 | ||
27 | In order to rewrite this mess to be more manageable, I would first do | |
28 | "diff master..topic", to extract the changes into a single patch, start | |
29 | picking pieces from it to get logically self-contained units, and | |
30 | start building on top of "master": | |
31 | ||
32 | $ git diff master..topic >P.diff | |
33 | $ git checkout -b topicA master | |
34 | ... pick and apply pieces from P.diff to build | |
35 | ... commits on topicA branch. | |
a6080a0a | 36 | |
5b766ea9 KE |
37 | o---o---o |
38 | / "topicA" | |
39 | o---o"master" | |
a6080a0a | 40 | \ "topic" |
5b766ea9 KE |
41 | o---o---o---o---o---o |
42 | ||
43 | Before doing each commit on "topicA" HEAD, I run "diff HEAD" | |
44 | before update-index the affected paths, or "diff --cached HEAD" | |
45 | after. Also I would run "diff --cached master" to make sure | |
46 | that the changes are only the ones related to "topicA". Usually | |
47 | I do this for smaller topics first. | |
48 | ||
49 | After that, I'd do the remainder of the original "topic", but | |
50 | for that, I do not start from the patchfile I extracted by | |
51 | comparing "master" and "topic" I used initially. Still on | |
52 | "topicA", I extract "diff topic", and use it to rebuild the | |
53 | other topic: | |
54 | ||
55 | $ git diff -R topic >P.diff ;# --cached also would work fine | |
56 | $ git checkout -b topicB master | |
57 | ... pick and apply pieces from P.diff to build | |
58 | ... commits on topicB branch. | |
59 | ||
60 | "topicB" | |
61 | o---o---o---o---o | |
62 | / | |
63 | /o---o---o | |
64 | |/ "topicA" | |
65 | o---o"master" | |
a6080a0a | 66 | \ "topic" |
5b766ea9 KE |
67 | o---o---o---o---o---o |
68 | ||
69 | After I am done, I'd try a pretend-merge between "topicA" and | |
70 | "topicB" in order to make sure I have not missed anything: | |
71 | ||
72 | $ git pull . topicA ;# merge it into current "topicB" | |
73 | $ git diff topic | |
74 | "topicB" | |
75 | o---o---o---o---o---* (pretend merge) | |
76 | / / | |
77 | /o---o---o----------' | |
78 | |/ "topicA" | |
79 | o---o"master" | |
a6080a0a | 80 | \ "topic" |
5b766ea9 KE |
81 | o---o---o---o---o---o |
82 | ||
83 | The last diff better not to show anything other than cleanups | |
031fd4b9 | 84 | for cruft. Then I can finally clean things up: |
5b766ea9 KE |
85 | |
86 | $ git branch -D topic | |
87 | $ git reset --hard HEAD^ ;# nuke pretend merge | |
88 | ||
89 | "topicB" | |
90 | o---o---o---o---o | |
a6080a0a | 91 | / |
5b766ea9 KE |
92 | /o---o---o |
93 | |/ "topicA" | |
94 | o---o"master" |