Git development
 help / color / mirror / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: Bruno Haible <bruno@clisp.org>
Cc: git@vger.kernel.org
Subject: Re: request for documentation about branch surgery
Date: Mon, 06 Jul 2009 19:50:06 -0700	[thread overview]
Message-ID: <7vab3hb40x.fsf@alter.siamese.dyndns.org> (raw)
In-Reply-To: <200907070105.12821.bruno@clisp.org> (Bruno Haible's message of "Tue\, 7 Jul 2009 01\:05\:12 +0200")

Bruno Haible <bruno@clisp.org> writes:

> 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.

You learn new things every day, and today is such a day ;-)

>   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 master~25 ;# detach HEAD at A
        $ edit edit edit
        $ git commit ;# creates B

which makes

               B              HEAD (detached)
              /
             A---C---...---Z    master

and then

        $ git rebase HEAD master

which reshapes the history into


               B---C'--...---Z' master
              /
             A---C---...---Z    master@{1}

and you are done.

> 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.

If you think "git merge" _copies_, you will never understand what "merge"
does.

If you have master and origin branch, merging them together

                X---Y---Z  origin
               /
              /
             O----A----B master

        $ git checkout master
        $ git merge origin

will give you this:


                X---Y---Z  origin
               /         \
              /           \
             O----A----B---M master
                       ^
                       master@{1}

There is no copying involved anywhere .  It only creates a new commit, M,
and that commit allows 'master' (that used to point at B) to reach both
the history leading to B and the history leading to Z.

On the other hand, rebase _copies_.  It _does_ make new commits A' and B',
whose _effect_ to the tree mimics those of A and B.

        $ git rebase origin master


                X---Y---Z---A'---B' master
               /        ^origin
              /
             O----A----B master@{1}

> 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

And it is not even cutting.  It merely makes this:

                      F---G---H---.........---Y---Z master@{1}
                     /
                D---E
                    ^master

so that a new history can grow at E that is parallel to the
history that leads to Z.

I think your confusion is primarily coming from not understanding what a
branch in git is.  A branch in git does not have its own identity per-se,
and a commit does _not_ belong to a branch, in the sense that a commit
object does not record anywhere on which branch it was created on.  A
branch is just a pointer into a dag and the pointer can be moved.

  parent reply	other threads:[~2009-07-07  2:50 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-07-06 23:05 request for documentation about branch surgery Bruno Haible
2009-07-07  2:30 ` Elijah Newren
2009-07-07  3:45   ` Elijah Newren
2009-07-07  9:51   ` Bruno Haible
2009-07-07 10:06     ` Andreas Ericsson
2009-07-07  2:50 ` Junio C Hamano [this message]
2009-07-07 10:13   ` Bruno Haible
2009-07-07 11:03     ` Andreas Ericsson
2009-07-07 15:52     ` Junio C Hamano
2009-07-07 18:28 ` Daniel Barkalow

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7vab3hb40x.fsf@alter.siamese.dyndns.org \
    --to=gitster@pobox.com \
    --cc=bruno@clisp.org \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox