1 From: Junio C Hamano <gitster@pobox.com>
 
   2 Subject: Separating topic branches
 
   3 Abstract: In this article, JC describes how to separate topic branches.
 
   4 Content-type: text/asciidoc
 
   6 How to separate topic branches
 
   7 ==============================
 
   9 This text was originally a footnote to a discussion about the
 
  10 behaviour of the git diff commands.
 
  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:
 
  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.
 
  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":
 
  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.
 
  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.
 
  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
 
  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.
 
  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:
 
  72         $ git pull . topicA ;# merge it into current "topicB"
 
  75                o---o---o---o---o---* (pretend merge)
 
  83 The last diff better not to show anything other than cleanups
 
  84 for crufts.  Then I can finally clean things up:
 
  87         $ git reset --hard HEAD^ ;# nuke pretend merge