Documentation / howto / rebase-and-edit.txton commit GIT 1.5.4-rc2 (bbff2dc)
   1Date:   Sat, 13 Aug 2005 22:16:02 -0700 (PDT)
   2From:   Linus Torvalds <torvalds@osdl.org>
   3To:     Steve French <smfrench@austin.rr.com>
   4cc:     git@vger.kernel.org
   5Subject: Re: sending changesets from the middle of a git tree
   6Abstract: In this article, Linus demonstrates how a broken commit
   7 in a sequence of commits can be removed by rewinding the head and
   8 reapplying selected changes.
   9
  10On Sat, 13 Aug 2005, Linus Torvalds wrote:
  11
  12> That's correct. Same things apply: you can move a patch over, and create a
  13> new one with a modified comment, but basically the _old_ commit will be
  14> immutable.
  15
  16Let me clarify.
  17
  18You can entirely _drop_ old branches, so commits may be immutable, but
  19nothing forces you to keep them. Of course, when you drop a commit, you'll
  20always end up dropping all the commits that depended on it, and if you
  21actually got somebody else to pull that commit you can't drop it from
  22_their_ repository, but undoing things is not impossible.
  23
  24For example, let's say that you've made a mess of things: you've committed
  25three commits "old->a->b->c", and you notice that "a" was broken, but you
  26want to save "b" and "c". What you can do is
  27
  28        # Create a branch "broken" that is the current code
  29        # for reference
  30        git branch broken
  31
  32        # Reset the main branch to three parents back: this
  33        # effectively undoes the three top commits
  34        git reset HEAD^^^
  35        git checkout -f
  36
  37        # Check the result visually to make sure you know what's
  38        # going on
  39        gitk --all
  40
  41        # Re-apply the two top ones from "broken"
  42        #
  43        # First "parent of broken" (aka b):
  44        git-diff-tree -p broken^ | git-apply --index
  45        git commit --reedit=broken^
  46
  47        # Then "top of broken" (aka c):
  48        git-diff-tree -p broken | git-apply --index
  49        git commit --reedit=broken
  50
  51and you've now re-applied (and possibly edited the comments) the two
  52commits b/c, and commit "a" is basically gone (it still exists in the
  53"broken" branch, of course).
  54
  55Finally, check out the end result again:
  56
  57        # Look at the new commit history
  58        gitk --all
  59
  60to see that everything looks sensible.
  61
  62And then, you can just remove the broken branch if you decide you really
  63don't want it:
  64
  65        # remove 'broken' branch
  66        git branch -d broken
  67
  68        # Prune old objects if you're really really sure
  69        git prune
  70
  71And yeah, I'm sure there are other ways of doing this. And as usual, the
  72above is totally untested, and I just wrote it down in this email, so if
  73I've done something wrong, you'll have to figure it out on your own ;)
  74
  75                        Linus
  76-
  77To unsubscribe from this list: send the line "unsubscribe git" in
  78the body of a message to majordomo@vger.kernel.org
  79More majordomo info at  http://vger.kernel.org/majordomo-info.html