]> git.ipfire.org Git - thirdparty/git.git/blame - Documentation/howto/separating-topic-branches.txt
Merge branch 'es/grep-require-name-when-needed'
[thirdparty/git.git] / Documentation / howto / separating-topic-branches.txt
CommitLineData
59eb68aa 1From: Junio C Hamano <gitster@pobox.com>
5b766ea9
KE
2Subject: Separating topic branches
3Abstract: In this article, JC describes how to separate topic branches.
1797e5c5
TA
4Content-type: text/asciidoc
5
6How to separate topic branches
7==============================
5b766ea9
KE
8
9This text was originally a footnote to a discussion about the
10behaviour of the git diff commands.
11
12Often I find myself doing that [running diff against something other
13than HEAD] while rewriting messy development history. For example, I
14start doing some work without knowing exactly where it leads, and end
15up with a history like this:
16
17 "master"
18 o---o
a6080a0a 19 \ "topic"
5b766ea9
KE
20 o---o---o---o---o---o
21
22At this point, "topic" contains something I know I want, but it
23contains two concepts that turned out to be completely independent.
24And often, one topic component is larger than the other. It may
25contain more than two topics.
26
27In 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
29picking pieces from it to get logically self-contained units, and
30start 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
43Before doing each commit on "topicA" HEAD, I run "diff HEAD"
44before update-index the affected paths, or "diff --cached HEAD"
45after. Also I would run "diff --cached master" to make sure
46that the changes are only the ones related to "topicA". Usually
47I do this for smaller topics first.
48
49After that, I'd do the remainder of the original "topic", but
50for that, I do not start from the patchfile I extracted by
51comparing "master" and "topic" I used initially. Still on
52"topicA", I extract "diff topic", and use it to rebuild the
53other 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
69After 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
83The last diff better not to show anything other than cleanups
84for crufts. Then I can finally clean things up:
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"