From: Jay Soffian <jaysoffian@gmail.com>
To: Junio C Hamano <gitster@pobox.com>, Ron Garret <ron1@flownet.com>
Cc: git@vger.kernel.org
Subject: Re: master^ is not a local branch -- huh?!?
Date: Fri, 29 Jan 2010 23:52:18 -0500 [thread overview]
Message-ID: <76718491001292052x7f46d479lfeff7b66121502c3@mail.gmail.com> (raw)
In-Reply-To: <7vbpgc8fhb.fsf@alter.siamese.dyndns.org>
On Fri, Jan 29, 2010 at 9:59 PM, Junio C Hamano <gitster@pobox.com> wrote:
> Ron Garret <ron1@flownet.com> writes:
>
>> 1. The term "detached HEAD" is inherently misleading. A detached HEAD
>> isn't detached from anything, it's just pointing to the middle of a
>> branch, which is to say, to a commit that happens to already have
>> descendants. For that matter, the name HEAD is itself misleading, since
>> HEAD need not be the head of a branch (though normally it is). A better
>> name for HEAD would have been CURRENT or ACTIVE. I recognize it's
>> probably too late to change it now.
>
> This description, especially the phrase "middle of a branch" shows that
> you don't understand git yet. A git branch is _not_ a line (nor multiple
> lines) of development. It is merely a _point_ in the history.
>
> "A commit that is in the middle of an ancestry chain with existing
> descendants" can be at the tip of a branch and does not have anything to
> do with detached HEAD state.
>
> When HEAD points at a branch, making a commit advances _that_ branch. And
> we say you are "on that branch". When HEAD is detached, because it is not
> attached to anything, it advances no branch. "detached HEAD" is detached
> in the very real sense. It is not attached to _any_ branch.
Let me try wording this slightly different, because I think I can see
Ron's confusion.
HEAD normally refers to a named branch. For example "master"
(technically, HEAD would contain "ref: refs/heads/master"), but we'll
just say "master" for now.
Meanwhile, the branch named "master" refers to a specific commit by
its SHA-1 hash.
The particular commit which "master" refers to is a branch head.
Now, when you create a commit in this state, the branch named "master"
is updated with the SHA-1 of the new commit. So let's say you create a
new repo and have three commits. Your history would look like this:
a---b---c master (HEAD is "ref: refs/heads/master")
That is, if you look at .git/HEAD, it will say "ref:
refs/heads/master" and if you look at .git/refs/heads/master it will
have the SHA-1 of commit "c". If you create a new commit:
a---b---c---d master (HEAD is "ref: refs/heads/master")
.git/HEAD still says "ref: refs/heads/master" but now
.git/refs/heads/master has the SHA-1 of commit "d".
Okay, now let's talk about what happens when you type:
$ git checkout master^
At this point, git updates HEAD to contain the SHA-1 of "c":
a---b---c---d master (HEAD is c's SHA-1)
You now have a "detached HEAD" because HEAD doesn't refer to any named
branch. Instead it refers to a specific commit by its SHA-1. So let's
create a new commit while HEAD is detached:
a---b---c---d master
\
e (HEAD is e's SHA-1)
So, yes, you've created a "branch" in the DAG sense of the word. But
this branch is anonymous since it has no name. That means that commit
"e" is subject to garbage collection and may be removed. If you want
to keep it around, then you need to create a name for it. Git provides
you a number of ways to "name" commits:
$ git checkout -b foo # (1)
$ git branch foo # (2)
$ git tag foo # (3)
(1) will create .git/refs/heads/foo, make it have the SHA-1 of commit
"e", then update HEAD to say "ref: refs/heads/foo". You are now "on"
branch "foo" and any commits you create will update
.git/refs/heads/foo:
a---b---c---d master
\
e foo (HEAD is "ref: refs/heads/foo")
(2) will also create .refs/heads/foo, and make it have the SHA-1 of
commit "e", but will leave HEAD as it is:
a---b---c---d master
\
e foo (HEAD is SHA-1 of "e")
You still have a detached HEAD and any commits you create that descend
from "e" are still subject to garbage collection (although "e" itself
is not), as follows:
a---b---c---d master
\
e <-- foo
\
f (HEAD is SHA-1 of "f")
(3) creates .refs/tags/foo, but is otherwise the same as (2).
So that was a really long explanation, but I hope it clears things up.
I think the disconnect between you and Junio is that you're thinking
of branches in the DAG sense of the word, while Junio is talking about
them in the context of git.
j.
next prev parent reply other threads:[~2010-01-30 4:54 UTC|newest]
Thread overview: 118+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-01-29 20:20 master^ is not a local branch -- huh?!? Ron1
2010-01-29 20:27 ` Jacob Helwig
2010-01-29 20:35 ` Sverre Rabbelier
2010-01-29 20:38 ` Jacob Helwig
2010-01-29 20:48 ` Junio C Hamano
2010-01-29 20:56 ` Sverre Rabbelier
2010-01-29 21:09 ` [PATCH] checkout: warn about 'branch name' rather than 'local branch' Sverre Rabbelier
2010-01-29 21:19 ` [PATCH] checkout: Fix test for s/local branch/branch name/ change Jacob Helwig
2010-01-29 21:20 ` Sverre Rabbelier
2010-01-29 21:40 ` [PATCH] checkout: warn about 'branch name' rather than 'local branch' Nicolas Pitre
2010-01-29 21:50 ` Ron Garret
2010-01-29 21:42 ` Junio C Hamano
2010-01-29 21:45 ` Sverre Rabbelier
2010-01-29 21:35 ` master^ is not a local branch -- huh?!? Junio C Hamano
2010-01-29 21:20 ` Nicolas Pitre
2010-01-29 21:21 ` Sverre Rabbelier
2010-01-29 21:29 ` Nicolas Pitre
2010-01-29 21:32 ` Sverre Rabbelier
2010-01-29 21:51 ` Nicolas Pitre
2010-01-29 21:58 ` Junio C Hamano
2010-01-29 22:00 ` Sverre Rabbelier
2010-01-29 22:34 ` Nicolas Pitre
2010-01-29 22:39 ` Junio C Hamano
2010-01-29 22:46 ` Jacob Helwig
2010-01-29 23:43 ` Nicolas Pitre
2010-01-30 0:14 ` Junio C Hamano
2010-01-30 0:18 ` Sverre Rabbelier
2010-01-30 0:29 ` Junio C Hamano
2010-01-30 0:35 ` Sverre Rabbelier
2010-01-30 0:38 ` Michael Witten
2010-01-30 0:39 ` Nicolas Pitre
2010-01-30 1:01 ` Mark Lodato
2010-01-30 1:22 ` Nicolas Pitre
2010-01-30 2:38 ` Ron Garret
2010-01-30 2:59 ` Junio C Hamano
2010-01-30 3:26 ` Ron Garret
2010-01-30 4:03 ` Nicolas Pitre
2010-01-30 5:06 ` Jay Soffian
2010-01-30 5:09 ` Junio C Hamano
2010-01-30 4:52 ` Jay Soffian [this message]
2010-01-30 5:15 ` Nicolas Pitre
2010-01-30 5:21 ` Junio C Hamano
2010-01-30 6:25 ` Ron Garret
2010-01-30 18:25 ` Junio C Hamano
2010-01-30 5:45 ` Jay Soffian
2010-01-30 5:18 ` Junio C Hamano
2010-01-30 6:23 ` Ron Garret
2010-01-30 2:40 ` Mark Lodato
2010-01-30 3:11 ` Nicolas Pitre
2010-01-30 3:59 ` Mark Lodato
2010-01-30 4:39 ` Nicolas Pitre
2010-01-30 5:05 ` Nicolas Pitre
2010-01-30 5:11 ` Jay Soffian
2010-01-30 5:25 ` Nicolas Pitre
2010-01-30 5:53 ` Mark Lodato
2010-01-30 6:03 ` Junio C Hamano
2010-01-30 8:59 ` Jeff King
2010-01-30 18:40 ` Ron Garret
2010-01-29 23:16 ` A Large Angry SCM
2010-01-29 21:49 ` Junio C Hamano
2010-01-30 2:13 ` Johannes Schindelin
2010-01-30 3:15 ` Nicolas Pitre
2010-01-29 20:35 ` Johannes Schindelin
2010-01-29 21:16 ` Ron1
2010-01-29 21:25 ` Jacob Helwig
2010-01-29 21:43 ` Ron Garret
2010-01-29 21:59 ` Junio C Hamano
2010-01-29 22:18 ` Ron Garret
2010-01-31 7:32 ` Junio C Hamano
2010-01-29 20:32 ` Octavio Alvarez
2010-01-29 21:34 ` Ron Garret
2010-01-29 22:32 ` Octavio Alvarez
2010-01-29 22:47 ` Ron Garret
2010-01-29 23:05 ` Octavio Alvarez
2010-01-29 23:12 ` Junio C Hamano
2010-01-29 23:30 ` Ron Garret
2010-01-29 23:28 ` Julian Phillips
2010-01-30 0:14 ` Ron Garret
2010-01-30 0:18 ` Ron Garret
2010-01-30 19:02 ` Junio C Hamano
2010-01-30 19:24 ` Ron Garret
2010-01-29 20:36 ` Scott R. Godin
2010-01-29 21:24 ` Ron Garret
2010-01-29 21:28 ` Sverre Rabbelier
2010-01-29 21:40 ` Ron Garret
2010-01-29 21:54 ` Junio C Hamano
2010-01-29 22:12 ` Ron Garret
2010-01-30 0:33 ` Michael Witten
2010-01-30 3:06 ` Junio C Hamano
2010-01-30 6:16 ` Ron Garret
2010-01-30 6:45 ` Junio C Hamano
2010-01-30 7:31 ` Ron Garret
2010-01-30 8:02 ` Junio C Hamano
2010-01-30 8:56 ` Ron Garret
-- strict thread matches above, loose matches on Subject: below --
2010-02-01 11:52 Steve Diver
2010-02-01 17:38 ` Junio C Hamano
2010-02-01 17:58 ` Sergei Organov
2010-02-01 22:52 ` Ron Garret
2010-02-01 23:01 ` Petr Baudis
2010-02-01 23:25 ` Nicolas Pitre
2010-02-01 23:37 ` Junio C Hamano
2010-02-01 23:56 ` Ron Garret
2010-02-02 0:15 ` Petr Baudis
2010-02-02 0:45 ` Ron Garret
2010-02-02 0:53 ` Junio C Hamano
2010-02-02 1:12 ` Ron Garret
2010-02-02 19:19 ` J. Bruce Fields
2010-02-02 22:04 ` Ron Garret
2010-02-03 18:27 ` J. Bruce Fields
2010-02-02 4:05 ` Nicolas Pitre
2010-02-02 5:23 ` Ron Garret
2010-02-02 5:43 ` Nicolas Pitre
2010-02-02 21:07 ` tytso
2010-02-02 0:26 ` Junio C Hamano
2010-02-02 0:21 ` Junio C Hamano
2010-02-01 18:12 ` Nicolas Pitre
2010-02-01 18:27 ` Jay Soffian
2010-02-01 22:34 ` Steve Diver
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=76718491001292052x7f46d479lfeff7b66121502c3@mail.gmail.com \
--to=jaysoffian@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=ron1@flownet.com \
/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;
as well as URLs for NNTP newsgroup(s).