Subject: request for documentation about branch surgery

From: Bruno Haible <[email-masked]>
Date: Tue, 7 Jul 2009 01:05:12 +0200

Hi,

Here are a few things that I would have expected to find in the Git user's
manual, chapter "Rewriting history and maintaining patch series"
  <http://www.kernel.org/pub/software/scm/git/docs/user-manual.html#cleaning-up-history>

It is meant for a user who does not yet know about "git rebase", "git merge",
"git reset" and the like. Organized by the goal that a user has ("how do I?").

1) After the section "Rewriting a single commit", it may be useful to
have a section "Inserting one or more new commits". This is something that
cannot be done with the "detached head" technique. I found this sequence
of commands useful:

  If you want to add a commit in the middle of a branch:

            A---C---...---Z    master

  =>

            A---B---C---...---Z    master

  it is achieved by

    $ git checkout A
    $ git branch temp
    $ git checkout temp
    [make changes for B]
    $ git commit -a

  now:

            A---C---...---Z    master
             \
              --B              temp

    $ git checkout master
    $ git rebase temp
    $ git branch -d temp

2) About the section "Reordering or selecting from a patch series".
   The "git rebase" documentation contains a good example:

   Reordering, possibly merging, the last 5 commits:
   $ git rebase -i HEAD~5
   See "man git-rebase" under "INTERACTIVE MODE".

   I find this technique very useful, because it guarantees that no
   commit gets lost (unlike "git cherry-pick"). Maybe the section could
   be split into two sections
      "Reordering a patch series"
   and
      "Selecting from a patch series"?

3) When do I need "git merge", and when do I need "git rebase", in the
   context of branch surgery?

   The simple answer, that I would find worth mentioning, is:
     - "git merge" copies commits from one branch to another.
     - "git rebase" only moves commits around to make history more linear.

4) It would be good to have a section "Cutting branches"

   How do I remove the N most recent commits from a branch?

               D---E---F---G---H---.........---Y---Z master

  =>
               D---E master

   It goes like this:

     $ git checkout master
     $ git reset --hard E

5) Then, it would be good to have a section "Replacing branches"

   How do I copy the contents of a branch over to another branch, replacing
   the recent development on that branch?

  If you want to copy a branch into another, while throwing away commits:

                     F1---F2---F3                         released
                    /
               D---E---F---G---H---.........---Y---Z master

  =>
                     F1---F2---F3   released
                    /
               D---E---F1---F2---F3 master

  This is achieved by

    $ git checkout master
    $ git reset --hard E      # Cut the branch "master"
    $ git merge released      # Copy commits from branch "released" to "master"

6) Also, it would be good to have a section "Reconnecting branches after rebase".
   If you want to reconnect a branch to a rebased master, here's how to do it:

                   /--C'--...---P'--Q'--...---Z'  new rebased master
              A---B---C---...---P---Q---...---Z   old master
                                 \
                                  --BA---...---BZ  release-branch

  =>
              A---B---C'--...---P'--Q'--...---Z'  new rebased master
                                 \
                                  --BA---...---BZ  release-branch

  This is achieved by

    $ git checkout release-branch
    $ git rebase --onto P' P

This might seem exotic, but these use cases all came up while rewriting the
history after a "git cvsimport".

Bruno