git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] Add howto about separating topics.

From
Kkent@lysator.liu.se <kent@lysator.liu.se>
Date
Feb 12, 2006, 12:00 UTC
Message-ID
<m3accwrdl7.fsf_-_@ceres.unit.liu.se>
In-Reply-To
<7vmzgxn1dz.fsf@assigned-by-dhcp.cox.net>

This howto consists of a footnote from an email by JC to the git mailing list (<7vfyms0x4p.fsf@assigned-by-dhcp.cox.net>).

Signed-off-by: Kent Engstrom <kent@lysator.liu.se>
---
 Documentation/howto/separating-topic-branches.txt |   91 +++++++++++++++++++++
 1 files changed, 91 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/howto/separating-topic-branches.txt
39f152ae224f45a3d977aa8966a477dbc1df676d
diff --git a/Documentation/howto/separating-topic-branches.txt b/Documentation/howto/separating-topic-branches.txt
new file mode 100644
index 0000000..090e2c9
--- /dev/null
+++ b/Documentation/howto/separating-topic-branches.txt
@@ -0,0 +1,91 @@
+From: Junio C Hamano <junkio@cox.net>
+Subject: Separating topic branches
+Abstract: In this article, JC describes how to separate topic branches.
+
+This text was originally a footnote to a discussion about the
+behaviour of the git diff commands.
+
+Often I find myself doing that [running diff against something other
+than HEAD] while rewriting messy development history.  For example, I
+start doing some work without knowing exactly where it leads, and end
+up with a history like this:
+
+            "master"
+        o---o
+             \                    "topic" 
+              o---o---o---o---o---o
+
+At this point, "topic" contains something I know I want, but it
+contains two concepts that turned out to be completely independent.
+And often, one topic component is larger than the other.  It may
+contain more than two topics.
+
+In order to rewrite this mess to be more manageable, I would first do
+"diff master..topic", to extract the changes into a single patch, start
+picking pieces from it to get logically self-contained units, and
+start building on top of "master":
+
+        $ git diff master..topic >P.diff
+        $ git checkout -b topicA master
+        ... pick and apply pieces from P.diff to build
+        ... commits on topicA branch.
+                      
+              o---o---o
+             /        "topicA"
+        o---o"master"
+             \                    "topic" 
+              o---o---o---o---o---o
+
+Before doing each commit on "topicA" HEAD, I run "diff HEAD"
+before update-index the affected paths, or "diff --cached HEAD"
+after.  Also I would run "diff --cached master" to make sure
+that the changes are only the ones related to "topicA".  Usually
+I do this for smaller topics first.
+
+After that, I'd do the remainder of the original "topic", but
+for that, I do not start from the patchfile I extracted by
+comparing "master" and "topic" I used initially.  Still on
+"topicA", I extract "diff topic", and use it to rebuild the
+other topic:
+
+        $ git diff -R topic >P.diff ;# --cached also would work fine
+        $ git checkout -b topicB master
+        ... pick and apply pieces from P.diff to build
+        ... commits on topicB branch.
+
+                                "topicB"
+               o---o---o---o---o
+              /
+             /o---o---o
+            |/        "topicA"
+        o---o"master"
+             \                    "topic" 
+              o---o---o---o---o---o
+
+After I am done, I'd try a pretend-merge between "topicA" and
+"topicB" in order to make sure I have not missed anything:
+
+        $ git pull . topicA ;# merge it into current "topicB"
+        $ git diff topic
+                                "topicB"
+               o---o---o---o---o---* (pretend merge)
+              /                   /
+             /o---o---o----------'
+            |/        "topicA"
+        o---o"master"
+             \                    "topic" 
+              o---o---o---o---o---o
+
+The last diff better not to show anything other than cleanups
+for crufts.  Then I can finally clean things up:
+
+        $ git branch -D topic
+        $ git reset --hard HEAD^ ;# nuke pretend merge
+
+                                "topicB"
+               o---o---o---o---o
+              / 
+             /o---o---o
+            |/        "topicA"
+        o---o"master"
+
-- 
1.1.6.g29e5
Previous: Junio C HamanoNext: J. Bruce Fields
Message 27 of 30 in “Two crazy proposals for changing git's diff commands”
  1. Carl WorthFeb 9, 2006
  2. Linus TorvaldsFeb 9, 2006
  3. Linus TorvaldsFeb 9, 2006
  4. Carl WorthFeb 9, 2006
  5. Junio C HamanoFeb 9, 2006
  6. Junio C HamanoFeb 9, 2006
  7. Junio C HamanoFeb 9, 2006
  8. Linus TorvaldsFeb 9, 2006
  9. Junio C HamanoFeb 9, 2006
  10. Junio C HamanoFeb 10, 2006
  11. Comments on "status -v" (was: Two crazy proposals for changing git's diff commands)Carl Worth, Feb 10, 2006
  12. Junio C HamanoFeb 10, 2006
  13. Linus TorvaldsFeb 10, 2006
  14. Junio C HamanoFeb 10, 2006
  15. Petr BaudisFeb 10, 2006
  16. Junio C HamanoFeb 10, 2006
  17. Carl WorthFeb 9, 2006
  18. Junio C HamanoFeb 10, 2006
  19. Carl WorthFeb 10, 2006
  20. Junio C HamanoFeb 10, 2006
  21. Carl WorthFeb 10, 2006
  22. Mark WoodingFeb 10, 2006
  23. Catalin MarinasFeb 13, 2006
  24. Prune-safe StGIT (was Re: Two crazy proposals for changing git's diff commands)Catalin Marinas, Feb 13, 2006
  25. Kent EngstromFeb 10, 2006
  26. Junio C HamanoFeb 11, 2006
  27. Add howto about separating topics.kent@lysator.liu.se, Feb 12, 2006
  28. J. Bruce FieldsFeb 12, 2006
  29. Junio C HamanoFeb 12, 2006
  30. Tim LarsonFeb 9, 2006

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.