All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: master^ is not a local branch -- huh?!?
@ 2010-02-01 11:52 Steve Diver
  2010-02-01 17:38 ` Junio C Hamano
  0 siblings, 1 reply; 111+ messages in thread
From: Steve Diver @ 2010-02-01 11:52 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Nicolas Pitre, Mark Lodato, Sverre Rabbelier, Git List, Ron1,
	Jacob Helwig

On 30/01/2010 06:03, Junio C Hamano wrote:

>Nicolas Pitre <nico@fluxnic.net> writes:

>>First, I'm afraid that "Checking out commit 'foobar'" might be confusing
>>as this may happen through either a remote branch, a tag, or any random
>>commit.  It seems to me that "Checking out 'v2.5'" is less confusing

>>than "Checking out commit 'v2.5'".  But that's a minor detail and
>>probably a personal preference.
...
>>To the contrary: this "detached HEAD" is exactly what you need if you
>>want to relate to any documentation or perform a search for more

>>information.  Like it or not, this detached HEAD term is exactly what
>>this Git concept is all about and how it is designated everywhere.  The
>>sooner Git users see and learn about it the better.

>As I am not good at keeping track of different proposals to change this
>word here and that word there, I expect this will probably need at least
>few rotations of earth to get input from people in different timezones,

>and I think this is post 1.7.0 item anyway, I'll queue the attached draft
>in 'pu' and keep it there, to make it easier for others to tweak the
>message.


Would it be a safe assumption to describe a 'detached HEAD' state as
being synonymous with a (local) personal scratchpad or temporary
workspace based on and from the original committed object?

If this assumption is correct, then maybe this notion of a scratchpad
may be more intuitive and conceptual to new users without getting
bogged down with the necessary semantics of the terms used, but can
also preserve references to 'detached HEAD' in the documentation for a
fuller explanation.


A scratchpad or temporary workspace description alludes to its semi
permanent nature, and can warn that the subsequent commits may be lost
through aging and garbage collection until the user "commits" to
saving their progress through the creation a new branch, and thereby
making them permanent.


I must say the explanations presented in this thread have shed some
light on what is on the face of it a common trap that leaves new users
wondering "What happened to my work!" and I thank you all.

Steve

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-02-01 11:52 master^ is not a local branch -- huh?!? Steve Diver
@ 2010-02-01 17:38 ` Junio C Hamano
  2010-02-01 17:58   ` Sergei Organov
  2010-02-01 18:12   ` Nicolas Pitre
  0 siblings, 2 replies; 111+ messages in thread
From: Junio C Hamano @ 2010-02-01 17:38 UTC (permalink / raw)
  To: Steve Diver
  Cc: Nicolas Pitre, Mark Lodato, Sverre Rabbelier, Git List, Ron1,
	Jacob Helwig

Steve Diver <squelch2@googlemail.com> writes:

> Would it be a safe assumption to describe a 'detached HEAD' state as
> being synonymous with a (local) personal scratchpad or temporary
> workspace based on and from the original committed object?

A commonly used term since we started discussing the detached HEAD late
2006 (v1.5.0 timeframe) is a "temporary branch" or a "throw-away" branch.
See c847f53 (Detached HEAD (experimental), 2007-01-01), for example.

I do not think we need yet another term "scratchpad" for this, but what is
important is that both introductory and full documentation explain the
detached HEAD well.

Currently we say:

    Detached HEAD
    -------------

    It is sometimes useful to be able to 'checkout' a commit that is
    not at the tip of one of your branches.  The most obvious
    example is to check out the commit at a tagged official release
    point, like this:

    ------------
    $ git checkout v2.6.18
    ------------

    Earlier versions of git did not allow this and asked you to
    create a temporary branch using the `-b` option, but starting from
    version 1.5.0, the above command 'detaches' your HEAD from the
    current branch and directly points at the commit named by the tag
    (`v2.6.18` in the example above).

If read carefully (some may argue that it does not need a very careful
reading to get it, though), this hints that "detached HEAD" state is a
substitute for using a temporary branch, but it may not be strong enough.

I thought that a documentation update in this area was already planned?

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  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 18:12   ` Nicolas Pitre
  1 sibling, 1 reply; 111+ messages in thread
From: Sergei Organov @ 2010-02-01 17:58 UTC (permalink / raw)
  To: Git List; +Cc: Junio C Hamano

Junio C Hamano <gitster@pobox.com> writes:
> Steve Diver <squelch2@googlemail.com> writes:

[...]

> If read carefully (some may argue that it does not need a very careful
> reading to get it, though), this hints that "detached HEAD" state is a
> substitute for using a temporary branch, but it may not be strong
> enough.

For my rather fresh eye it looks more like unnamed (anonymous?) branch
than a temporary one. Doesn't detached HEAD behave exactly like a
regular HEAD but pointing to the tip of an unnamed branch?

-- Sergei.

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-02-01 17:38 ` Junio C Hamano
  2010-02-01 17:58   ` Sergei Organov
@ 2010-02-01 18:12   ` Nicolas Pitre
  2010-02-01 18:27     ` Jay Soffian
  2010-02-01 22:34     ` Steve Diver
  1 sibling, 2 replies; 111+ messages in thread
From: Nicolas Pitre @ 2010-02-01 18:12 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Jay Soffian, Steve Diver, Mark Lodato, Sverre Rabbelier,
	Git List, Ron1, Jacob Helwig

On Mon, 1 Feb 2010, Junio C Hamano wrote:

> I do not think we need yet another term "scratchpad" for this, but what is
> important is that both introductory and full documentation explain the
> detached HEAD well.
> 
> Currently we say:
> 
>     Detached HEAD
>     -------------
> 
>     It is sometimes useful to be able to 'checkout' a commit that is
>     not at the tip of one of your branches.  The most obvious
>     example is to check out the commit at a tagged official release
>     point, like this:
> 
>     ------------
>     $ git checkout v2.6.18
>     ------------
> 
>     Earlier versions of git did not allow this and asked you to
>     create a temporary branch using the `-b` option, but starting from
>     version 1.5.0, the above command 'detaches' your HEAD from the
>     current branch and directly points at the commit named by the tag
>     (`v2.6.18` in the example above).
> 
> If read carefully (some may argue that it does not need a very careful
> reading to get it, though), this hints that "detached HEAD" state is a
> substitute for using a temporary branch, but it may not be strong enough.
> 
> I thought that a documentation update in this area was already planned?

Jay Soffian (added to CC) agreed to augment the documentation with the 
comprehensive explanation he posted to the list lately.


Nicolas

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-02-01 18:12   ` Nicolas Pitre
@ 2010-02-01 18:27     ` Jay Soffian
  2010-02-01 22:34     ` Steve Diver
  1 sibling, 0 replies; 111+ messages in thread
From: Jay Soffian @ 2010-02-01 18:27 UTC (permalink / raw)
  To: Nicolas Pitre
  Cc: Junio C Hamano, Steve Diver, Mark Lodato, Sverre Rabbelier,
	Git List, Ron1, Jacob Helwig

On Mon, Feb 1, 2010 at 1:12 PM, Nicolas Pitre <nico@fluxnic.net> wrote:
>> I thought that a documentation update in this area was already planned?
>
> Jay Soffian (added to CC) agreed to augment the documentation with the
> comprehensive explanation he posted to the list lately.

I talked to him, he didn't forget, and he'll try his best to submit a
patch this week. :-)

j.

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-02-01 18:12   ` Nicolas Pitre
  2010-02-01 18:27     ` Jay Soffian
@ 2010-02-01 22:34     ` Steve Diver
  1 sibling, 0 replies; 111+ messages in thread
From: Steve Diver @ 2010-02-01 22:34 UTC (permalink / raw)
  To: Nicolas Pitre
  Cc: Junio C Hamano, Jay Soffian, Mark Lodato, Sverre Rabbelier,
	Git List, Ron1, Jacob Helwig

On 1 February 2010 18:12, Nicolas Pitre <nico@fluxnic.net> wrote:
> On Mon, 1 Feb 2010, Junio C Hamano wrote:
>
>> I do not think we need yet another term "scratchpad" for this, but what is
>> important is that both introductory and full documentation explain the
>> detached HEAD well.
>>
>> Currently we say:
>>
>>     Detached HEAD
>>     -------------
>>
>>     It is sometimes useful to be able to 'checkout' a commit that is
>>     not at the tip of one of your branches.  The most obvious
>>     example is to check out the commit at a tagged official release
>>     point, like this:
>>
>>     ------------
>>     $ git checkout v2.6.18
>>     ------------
>>
>>     Earlier versions of git did not allow this and asked you to
>>     create a temporary branch using the `-b` option, but starting from
>>     version 1.5.0, the above command 'detaches' your HEAD from the
>>     current branch and directly points at the commit named by the tag
>>     (`v2.6.18` in the example above).
>>
>> If read carefully (some may argue that it does not need a very careful
>> reading to get it, though), this hints that "detached HEAD" state is a
>> substitute for using a temporary branch, but it may not be strong enough.
>>
>> I thought that a documentation update in this area was already planned?

A "temporary branch" is probably the simplest description, and would
make it easier to grasp the concept in plain language for those that
are new to Git without glazing over.

Is how it worked pre version 1.5.0 now moot in terms of reference?
Probably the first encounter a user might have is when they arrive at
a detached HEAD situation and receive the message that prompted Ron
Garret to start this thread. The concept of an automatic temporary
branch might be easier to understand from the outset without needing
reference to the "old ways" ;)

As an aside, I believe a common misconception is for a user to think
they are checking out a single file revision which could be the most
likely mechanism to lead them into an inadvertent detached HEAD state.
Any improvement in both the first line message and the full
documentation would be most helpful.

>
> Jay Soffian (added to CC) agreed to augment the documentation with the
> comprehensive explanation he posted to the list lately.
>
That is good news indeed.

Steve

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-02-01 17:58   ` Sergei Organov
@ 2010-02-01 22:52     ` Ron Garret
  2010-02-01 23:01       ` Petr Baudis
                         ` (3 more replies)
  0 siblings, 4 replies; 111+ messages in thread
From: Ron Garret @ 2010-02-01 22:52 UTC (permalink / raw)
  To: git

In article <87aavsu9b3.fsf@osv.gnss.ru>, Sergei Organov <osv@javad.com> 
wrote:

> Junio C Hamano <gitster@pobox.com> writes:
> > Steve Diver <squelch2@googlemail.com> writes:
> 
> [...]
> 
> > If read carefully (some may argue that it does not need a very careful
> > reading to get it, though), this hints that "detached HEAD" state is a
> > substitute for using a temporary branch, but it may not be strong
> > enough.
> 
> For my rather fresh eye it looks more like unnamed (anonymous?) branch
> than a temporary one. Doesn't detached HEAD behave exactly like a
> regular HEAD but pointing to the tip of an unnamed branch?

I strongly concur with this.

And as long as I'm weighing in, it would also help to prevent confusion 
if it were made clear that this unnamed branch doesn't actually come 
into existence unless and until you do a commit.

rg

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-02-01 22:52     ` Ron Garret
@ 2010-02-01 23:01       ` Petr Baudis
  2010-02-01 23:25       ` Nicolas Pitre
                         ` (2 subsequent siblings)
  3 siblings, 0 replies; 111+ messages in thread
From: Petr Baudis @ 2010-02-01 23:01 UTC (permalink / raw)
  To: Ron Garret; +Cc: git

On Mon, Feb 01, 2010 at 02:52:08PM -0800, Ron Garret wrote:
> In article <87aavsu9b3.fsf@osv.gnss.ru>, Sergei Organov <osv@javad.com> 
> wrote:
> 
> > Junio C Hamano <gitster@pobox.com> writes:
> > > Steve Diver <squelch2@googlemail.com> writes:
> > 
> > [...]
> > 
> > > If read carefully (some may argue that it does not need a very careful
> > > reading to get it, though), this hints that "detached HEAD" state is a
> > > substitute for using a temporary branch, but it may not be strong
> > > enough.
> > 
> > For my rather fresh eye it looks more like unnamed (anonymous?) branch
> > than a temporary one. Doesn't detached HEAD behave exactly like a
> > regular HEAD but pointing to the tip of an unnamed branch?
> 
> I strongly concur with this.
> 
> And as long as I'm weighing in, it would also help to prevent confusion 
> if it were made clear that this unnamed branch doesn't actually come 
> into existence unless and until you do a commit.

That statement is not quite consistent with the Git model. A branch is a
pointer. Detached HEAD is "unnamed" branch pointer (as in, you can refer
to it by the default HEAD alias, but not by any other name). In this
sense, the moment you create detached HEAD, you created the anonymous
branch, and the moment you check out something else, it is gone in a
wisp of smoke again.

The act of committing does not come into the picture at all. Committing
is the act of saving a commit to the database and *updating* the current
branch pointer to point at it. However, it does not affect what branch
pointer is the current one. It is important to realize that:

	* Branches refer to commits.
	* Commits do not refer to branches!

That is, when you create a commit, it is not _tied_ to a particular
branch. Thus, when you create a commit, you could not have created any
branch, and creating a branch [pointer] is unrelated to creating any
commits.

-- 
				Petr "Pasky" Baudis
If you can't see the value in jet powered ants you should turn in
your nerd card. -- Dunbal (464142)

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  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-02  0:21       ` Junio C Hamano
  3 siblings, 0 replies; 111+ messages in thread
From: Nicolas Pitre @ 2010-02-01 23:25 UTC (permalink / raw)
  To: Ron Garret; +Cc: git

On Mon, 1 Feb 2010, Ron Garret wrote:

> In article <87aavsu9b3.fsf@osv.gnss.ru>, Sergei Organov <osv@javad.com> 
> wrote:
> 
> > Junio C Hamano <gitster@pobox.com> writes:
> > > Steve Diver <squelch2@googlemail.com> writes:
> > 
> > [...]
> > 
> > > If read carefully (some may argue that it does not need a very careful
> > > reading to get it, though), this hints that "detached HEAD" state is a
> > > substitute for using a temporary branch, but it may not be strong
> > > enough.
> > 
> > For my rather fresh eye it looks more like unnamed (anonymous?) branch
> > than a temporary one. Doesn't detached HEAD behave exactly like a
> > regular HEAD but pointing to the tip of an unnamed branch?
> 
> I strongly concur with this.
> 
> And as long as I'm weighing in, it would also help to prevent confusion 
> if it were made clear that this unnamed branch doesn't actually come 
> into existence unless and until you do a commit.

Nope.  Creating a commit doesn't create any branch.  A commit creation 
merely adds a new node in the history graph, and links it to the commit 
that was the current one before that commit operation.  If HEAD is 
_attached_ to a branch then the branch pointer is also updated to point 
to that new commit.  If HEAD is _detached_ then no branch is updated and 
HEAD simply carries a direct reference to that new commit.

At a later time you can:

1) Create a new branch pointer which default value is the commit pointed to
   by HEAD.  This is true whether or not HEAD is detached, but in this 
   case this is an interesting property.

2) Move HEAD somewhere else by performing a checkout.  If HEAD was 
   detached then its last position is simply forgotten and those 
   commits that were performed while HEAD was detached, if any, are 
   simply left dangling and eventually garbage collected.  If however a 
   new branch pointer was created in (1) then those commits won't be 
   dangling.

In any case, a detached HEAD is not only a temporary branch, it is also 
a volatile branch.  And in the Git model, it is simply not a branch at 
all.  Hence the 2 states for HEAD: either detached, or attached to a 
branch pointer.


Nicolas

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  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:21       ` Junio C Hamano
  3 siblings, 1 reply; 111+ messages in thread
From: Junio C Hamano @ 2010-02-01 23:37 UTC (permalink / raw)
  To: Ron Garret; +Cc: git

Ron Garret <ron1@flownet.com> writes:

>> For my rather fresh eye it looks more like unnamed (anonymous?) branch
>> than a temporary one. Doesn't detached HEAD behave exactly like a
>> regular HEAD but pointing to the tip of an unnamed branch?
>
> I strongly concur with this.
>
> And as long as I'm weighing in, it would also help to prevent confusion 
> if it were made clear that this unnamed branch doesn't actually come 
> into existence unless and until you do a commit.

This shows that you are still thinking a branch is a line (or multiple
lines).  It is not.

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  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:26           ` Junio C Hamano
  0 siblings, 2 replies; 111+ messages in thread
From: Ron Garret @ 2010-02-01 23:56 UTC (permalink / raw)
  To: git

In article <7vwrywplxz.fsf@alter.siamese.dyndns.org>,
 Junio C Hamano <gitster@pobox.com> wrote:

> Ron Garret <ron1@flownet.com> writes:
> 
> >> For my rather fresh eye it looks more like unnamed (anonymous?) branch
> >> than a temporary one. Doesn't detached HEAD behave exactly like a
> >> regular HEAD but pointing to the tip of an unnamed branch?
> >
> > I strongly concur with this.
> >
> > And as long as I'm weighing in, it would also help to prevent confusion 
> > if it were made clear that this unnamed branch doesn't actually come 
> > into existence unless and until you do a commit.
> 
> This shows that you are still thinking a branch is a line (or multiple
> lines).  It is not.

The git user's guide says it is:

"When we need to be precise, we will use the word "branch" to mean a 
line of development..."

But I understand that a branch is not necessarily a line.  In general 
it's a DAG.  I get that.

The manual goes on to say:

"...and "branch head" (or just "head") to mean a reference to the most 
recent commit on a branch."

There are two ways this can be interpreted:

1.  A commit pointed to by a branch head cannot have any descendants.  
Because if it did it would not be the most recent commit on that branch, 
and by definition a branch head must point at the most recent commit.

2.  Any commit can be considered a branch head for a branch consisting 
of (for example) the transitive closure of its ancestors.

(Note that if I were being really strict with my terminology I would 
have to say: any commit can be considered the most recent commit for a 
branch consisting of...  Because a branch head by definition is a 
*reference* to a commit, so strictly speaking a commit cannot be a 
branch head.  The problem is that there are three concepts in play, but 
only two terms by which to refer to them.)

I personally think interpretation #1 makes more sense, and is a better 
match to most people's intuitions about what it means to be a branch 
head.  But in neither case does simply moving HEAD "create" a branch.  
Even under interpretation 2, all those anonymous branches were there all 
along.  You don't "create" anything, temporary or otherwise, simply by 
moving HEAD.

rg

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  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:26           ` Junio C Hamano
  1 sibling, 1 reply; 111+ messages in thread
From: Petr Baudis @ 2010-02-02  0:15 UTC (permalink / raw)
  To: Ron Garret; +Cc: git

On Mon, Feb 01, 2010 at 03:56:31PM -0800, Ron Garret wrote:
> In article <7vwrywplxz.fsf@alter.siamese.dyndns.org>,
>  Junio C Hamano <gitster@pobox.com> wrote:
> > Ron Garret <ron1@flownet.com> writes:
> > > And as long as I'm weighing in, it would also help to prevent confusion 
> > > if it were made clear that this unnamed branch doesn't actually come 
> > > into existence unless and until you do a commit.
> > 
> > This shows that you are still thinking a branch is a line (or multiple
> > lines).  It is not.
> 
> The git user's guide says it is:
> 
> "When we need to be precise, we will use the word "branch" to mean a 
> line of development..."
> 
> But I understand that a branch is not necessarily a line.  In general 
> it's a DAG.  I get that.

Again, no. In the most narrow sense, "branch == branch head". Branch is
just a pointer. Which is the reason why your original statement does not
make sense.

We could say that the "branch closure" is the DAG of ancestry of the
commit we point to. We use "branch" in that sense since we have to
express ourselves in natural language, we are not in a calculus class,
there is mapping to various real-world and other-VCS concepts in play,
etc. But in order to use "branch" in the ambiguous sense, you should
first realize what it means in the _strict_ sense, so that you
understand the texts correctly and don't reach wrong conclusions or
create invalid concepts like "branches coming into existence". :-)

-- 
				Petr "Pasky" Baudis
If you can't see the value in jet powered ants you should turn in
your nerd card. -- Dunbal (464142)

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-02-01 22:52     ` Ron Garret
                         ` (2 preceding siblings ...)
  2010-02-01 23:37       ` Junio C Hamano
@ 2010-02-02  0:21       ` Junio C Hamano
  3 siblings, 0 replies; 111+ messages in thread
From: Junio C Hamano @ 2010-02-02  0:21 UTC (permalink / raw)
  To: Ron Garret; +Cc: git

Ron Garret <ron1@flownet.com> writes:

>> For my rather fresh eye it looks more like unnamed (anonymous?) branch
>> than a temporary one. Doesn't detached HEAD behave exactly like a
>> regular HEAD but pointing to the tip of an unnamed branch?
>
> I strongly concur with this.
>
> And as long as I'm weighing in, it would also help to prevent confusion 
> if it were made clear that this unnamed branch doesn't actually come 
> into existence unless and until you do a commit.

After re-reading this three times, I actually cannot tell which one you
think is the confused misconception: (1) unnamed branch does not exist
until you commit, or (2) unnamed branch does exist immediately you
detach.

Let's say you have this history:

    ---A---B HEAD == master

When drawing commit ancestry in ASCII art, uppercase letters in the
drawing denote commits.  Time flows from left to right and we don't write
arrows to show B is a child of A.  On the right, above or below commit, we
also write refs (i.e. tags, branches and HEAD).  When we say "HEAD ==
master", we mean HEAD is a symref to master ref (if we really want to be
anal, 'refs/heads/master' might be more technically correct but most often
it is clear from the context).

So by the above picture, we mean "There is a history that ends with B,
whose parent is A and it came from somewhere.  'master' branch points at B
and HEAD symref points at 'master' so that is the current branch".

Here is what happens when you make changes and "git commit" it.

(0) Normal case.

    ---A---B---C HEAD == master

    The new state is recorded as a tree, a new commit C is created to wrap
    that tree, C is made a child of B (because HEAD pointed at it), and
    finally, master is moved to point at that commit C (because HEAD
    pointed at 'master').

Notice that two "HEAD pointed at" mean slightly different things in the
above sentence.  In the former context of determining the commit to become
the parent of a new commit, we want commit, and "evaluating HEAD by
checking at what it points at" wants to return commit, so even though
technically HEAD at this point would be:

    $ cat .git/HEAD
    ref: refs/heads/master"

IOW, it points at 'master' branch, we look beyond it and talk about the
commit that is pointed at refs/heads/master.

In the latter, we want to determine if there is a branch we would
want to update to point at the newly created commit, so we look at
HEAD and notice it points at refs/heads/master.  We update it,
instead of storing the value of C directly in HEAD.

Now, "git checkout master^0" would do this:

    ---A---B---C HEAD (detached)
                 master

There are two pointers.

    $ cat .git/HEAD
    562d53fa69933b3ade2691b99cbe67722313f43c
    $ cat .git/refs/heads/master
    562d53fa69933b3ade2691b99cbe67722313f43c

They point at the same commit C (let's pretend 562d53... is C).

You make changes and create a commit.  What happens?

(1) A new tree is created and wrapped in a new commit D, whose parent is
    C.

                 D    we have not updated
                /     any ref yet
    ---A---B---C

    We used the fact that HEAD points at C (in the first "what commit is
    pointed?" sense) to determine the parent of D.

(2) We decide what pointer to move to point at this commit.  HEAD does not
    point at any branch (it directly pointed at commit C), so we do not
    move any named branch, but move only HEAD.  The end result is:

                 D HEAD (detached)
                /
    ---A---B---C master

    Now you then do "git checkout -b side".  What happens?

(3) We create a new branch "side" at the commit HEAD points at (we could
    have said "git checkout -b side HEAD"), and make HEAD point at that
    branch.

                 D HEAD == side
                /
    ---A---B---C master


Now, when we say "branch", we do not mean the "line" between C and D.
"master" branch is not a line before A, between A and B and between B and
C concatenated together.  "master branch" in git simply points at C in the
above graph.

Especailly, there is no special "master"-ness to the line between B and C.
B can be reached from both 'master' and 'side' branches.  A corollary is
that a line between C and D does not have any special 'side'-ness either,
as later you can fork other branches from D.

Similarly, in picture (2) where HEAD is still detached, there is no
special 'HEAD'-ness to the line between C and D.

Similarly in the picture where you had HEAD that was detached that pointed
at C:

    ---A---B---C HEAD (detached)

there is no HEAD-ness in any of the line segment depicted.  The same goes
for all the lines depicted in picture (2); between these two pictures, the
only change made was a commit on the detached HEAD.  From the perspective
of "branches", there is no change.

Calling detached HEAD as "temporary" or "anonymous" branch is fine, but
then we should consider the state immediately after detaching the HEAD
equally valid "anonymous" branch as in picture (2).

Putting it in another way, a branch in git is _not_ the name given to line
segments that _led_ to the point the branch points at (i.e. past history).
Think of a branch as the point where your next commit advances from
(i.e. future history).

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-02-01 23:56         ` Ron Garret
  2010-02-02  0:15           ` Petr Baudis
@ 2010-02-02  0:26           ` Junio C Hamano
  1 sibling, 0 replies; 111+ messages in thread
From: Junio C Hamano @ 2010-02-02  0:26 UTC (permalink / raw)
  To: Ron Garret; +Cc: git

Ron Garret <ron1@flownet.com> writes:

>> This shows that you are still thinking a branch is a line (or multiple
>> lines).  It is not.
>
> The git user's guide says it is:
>
> "When we need to be precise, we will use the word "branch" to mean a 
> line of development..."

I think the last paragraph "to put it in another way" in my other message
to you will clear this confusion.

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  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  4:05               ` Nicolas Pitre
  0 siblings, 2 replies; 111+ messages in thread
From: Ron Garret @ 2010-02-02  0:45 UTC (permalink / raw)
  To: git

In article <20100202001530.GL9553@machine.or.cz>,
 Petr Baudis <pasky@suse.cz> wrote:

> On Mon, Feb 01, 2010 at 03:56:31PM -0800, Ron Garret wrote:
> > In article <7vwrywplxz.fsf@alter.siamese.dyndns.org>,
> >  Junio C Hamano <gitster@pobox.com> wrote:
> > > Ron Garret <ron1@flownet.com> writes:
> > > > And as long as I'm weighing in, it would also help to prevent confusion 
> > > > if it were made clear that this unnamed branch doesn't actually come 
> > > > into existence unless and until you do a commit.
> > > 
> > > This shows that you are still thinking a branch is a line (or multiple
> > > lines).  It is not.
> > 
> > The git user's guide says it is:
> > 
> > "When we need to be precise, we will use the word "branch" to mean a 
> > line of development..."
> > 
> > But I understand that a branch is not necessarily a line.  In general 
> > it's a DAG.  I get that.
> 
> Again, no. In the most narrow sense, "branch == branch head".

The manual specifically contradicts you, so either you are wrong or the 
manual is wrong.

Don't forget that what is at issue here is not how git works (I'm pretty 
sure everyone is on the same page about that) but how to explain it to 
someone who is not already familiar with it.  So it's important to use 
terminology that is consistent with what the manual says.

> Branch is just a pointer.

No, a branch is not "just" a pointer.  At the very least it's a pointer 
with a name.  The SHA1 hash of a blob is a pointer too.  But it's not a 
branch.  The SHA1 hash of a commit is a pointer too, but if you were to 
consider that a branch then "branch" would simply become synonymous with 
"commit" and the term would lose its utility.

> Which is the reason why your original statement does not
> make sense.

That remains to be seen.  I believe that on the manual's definition of 
"branch" my statement not only makes sense, but is actually correct.

> We could say that the "branch closure" is the DAG of ancestry of the
> commit we point to. We use "branch" in that sense since we have to
> express ourselves in natural language, we are not in a calculus class,
> there is mapping to various real-world and other-VCS concepts in play,
> etc. But in order to use "branch" in the ambiguous sense, you should
> first realize what it means in the _strict_ sense, so that you
> understand the texts correctly and don't reach wrong conclusions or
> create invalid concepts like "branches coming into existence". :-)

I am trying to be as strict as I can according to what is in the 
documentation.

rg

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  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  4:05               ` Nicolas Pitre
  1 sibling, 1 reply; 111+ messages in thread
From: Junio C Hamano @ 2010-02-02  0:53 UTC (permalink / raw)
  To: Ron Garret; +Cc: git

Ron Garret <ron1@flownet.com> writes:

> The manual specifically contradicts you, so either you are wrong or the 
> manual is wrong.

In case you haven't noticed, Pasky is one of the old timers and he knows a
thing or two about the git's world model.

And I do not see a contradiction in what the manual describes and "a
branch is a named pointer to a commit" (although "named" can probably be
omitted as "unnamed pointer" is not useful at the UI level).

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-02-02  0:53               ` Junio C Hamano
@ 2010-02-02  1:12                 ` Ron Garret
  2010-02-02 19:19                   ` J. Bruce Fields
  0 siblings, 1 reply; 111+ messages in thread
From: Ron Garret @ 2010-02-02  1:12 UTC (permalink / raw)
  To: git

In article <7vk4uwmp95.fsf@alter.siamese.dyndns.org>,
 Junio C Hamano <gitster@pobox.com> wrote:

> Ron Garret <ron1@flownet.com> writes:
> 
> > The manual specifically contradicts you, so either you are wrong or the 
> > manual is wrong.
> 
> In case you haven't noticed, Pasky is one of the old timers and he knows a
> thing or two about the git's world model.

My intent was not to diss Pasky, it was just to point out a disconnect 
between what he was saying and what the manual says.  It's quite 
possible that the manual is wrong or out of date or just misleading.  
But it says what it says.

> And I do not see a contradiction in what the manual describes and "a
> branch is a named pointer to a commit" (although "named" can probably be
> omitted as "unnamed pointer" is not useful at the UI level).

But that's not what the manual says.  The manual says, "When we need to 
be precise, we will use the word "branch" to mean a line of 
development..."  Those are the first words in the section entitled 
"Understanding history: What is a branch?"  It certainly appears to the 
untrained eye that that is intended to be the definition of a branch.

Maybe the manual just needs to be updated.  "A named pointer to a 
commit" is a useful definition, and a lot clearer than "a line of 
development" (I don't even know what that means).  I do think it's 
important to keep "named" to distinguish them from, for example, SHA1 
hashes which are (or at least can be) unnamed pointers to commits.

In fact, the whole issue of detached/attached HEAD comes down to whether 
HEAD is a direct reference to a commit through its hash, or an indirect 
reference to a commit through a named reference that it "drags along" 
the next time a commit is, er, committed.  :-)

BTW, my intent here is not to critique git's design, or to pump myself 
up as some kind of an expert or to cut anybody down or anything like 
that.  I'm just trying to point out how what is written down can lead to 
confusion for someone who doesn't know what's going on, and to make some 
constructive suggestions on how the situation could be improved.  That's 
all.

rg

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-02-02  0:45             ` Ron Garret
  2010-02-02  0:53               ` Junio C Hamano
@ 2010-02-02  4:05               ` Nicolas Pitre
  2010-02-02  5:23                 ` Ron Garret
  1 sibling, 1 reply; 111+ messages in thread
From: Nicolas Pitre @ 2010-02-02  4:05 UTC (permalink / raw)
  To: Ron Garret; +Cc: git

On Mon, 1 Feb 2010, Ron Garret wrote:

> In article <20100202001530.GL9553@machine.or.cz>,
>  Petr Baudis <pasky@suse.cz> wrote:
> 
> > On Mon, Feb 01, 2010 at 03:56:31PM -0800, Ron Garret wrote:
> > > In article <7vwrywplxz.fsf@alter.siamese.dyndns.org>,
> > >  Junio C Hamano <gitster@pobox.com> wrote:
> > > > Ron Garret <ron1@flownet.com> writes:
> > > > > And as long as I'm weighing in, it would also help to prevent confusion 
> > > > > if it were made clear that this unnamed branch doesn't actually come 
> > > > > into existence unless and until you do a commit.
> > > > 
> > > > This shows that you are still thinking a branch is a line (or multiple
> > > > lines).  It is not.
> > > 
> > > The git user's guide says it is:
> > > 
> > > "When we need to be precise, we will use the word "branch" to mean a 
> > > line of development..."
> > > 
> > > But I understand that a branch is not necessarily a line.  In general 
> > > it's a DAG.  I get that.
> > 
> > Again, no. In the most narrow sense, "branch == branch head".
> 
> The manual specifically contradicts you, so either you are wrong or the 
> manual is wrong.

In that case it's most probably the manual which is wrong.

> Don't forget that what is at issue here is not how git works (I'm pretty 
> sure everyone is on the same page about that) but how to explain it to 
> someone who is not already familiar with it.  So it's important to use 
> terminology that is consistent with what the manual says.

Or rather that the manual has to be debugged and be brought in sync with 
reality.  All the people who had their hands dirty with the code usually 
hang here, and what they say has precedence with whatever is in the 
manual.

It is good of course that you bring those issues to our attention.  but 
it is more likely that the manual needs fixing than anything else.


Nicolas

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  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
  0 siblings, 2 replies; 111+ messages in thread
From: Ron Garret @ 2010-02-02  5:23 UTC (permalink / raw)
  To: git

In article <alpine.LFD.2.00.1002012253260.1681@xanadu.home>,
 Nicolas Pitre <nico@fluxnic.net> wrote:

> On Mon, 1 Feb 2010, Ron Garret wrote:
> 
> > In article <20100202001530.GL9553@machine.or.cz>,
> >  Petr Baudis <pasky@suse.cz> wrote:
> > 
> > > On Mon, Feb 01, 2010 at 03:56:31PM -0800, Ron Garret wrote:
> > > > In article <7vwrywplxz.fsf@alter.siamese.dyndns.org>,
> > > >  Junio C Hamano <gitster@pobox.com> wrote:
> > > > > Ron Garret <ron1@flownet.com> writes:
> > > > > > And as long as I'm weighing in, it would also help to prevent 
> > > > > > confusion 
> > > > > > if it were made clear that this unnamed branch doesn't actually 
> > > > > > come 
> > > > > > into existence unless and until you do a commit.
> > > > > 
> > > > > This shows that you are still thinking a branch is a line (or 
> > > > > multiple
> > > > > lines).  It is not.
> > > > 
> > > > The git user's guide says it is:
> > > > 
> > > > "When we need to be precise, we will use the word "branch" to mean a 
> > > > line of development..."
> > > > 
> > > > But I understand that a branch is not necessarily a line.  In general 
> > > > it's a DAG.  I get that.
> > > 
> > > Again, no. In the most narrow sense, "branch == branch head".
> > 
> > The manual specifically contradicts you, so either you are wrong or the 
> > manual is wrong.
> 
> In that case it's most probably the manual which is wrong.

OK.  That happens.

> > Don't forget that what is at issue here is not how git works (I'm pretty 
> > sure everyone is on the same page about that) but how to explain it to 
> > someone who is not already familiar with it.  So it's important to use 
> > terminology that is consistent with what the manual says.
> 
> Or rather that the manual has to be debugged and be brought in sync with 
> reality.

Sure.  I'm agnostic about how this synchronization happens.  But I think 
it's important that it happen, otherwise a lot of people will remain 
confused, and that would be a shame.

> All the people who had their hands dirty with the code usually 
> hang here, and what they say has precedence with whatever is in the 
> manual.

Yes, but what they say still ought to pass some basic tests of utility.  
For example, a definition of "branch" that makes it effectively 
synonymous with "commit" is probably not useful.

> It is good of course that you bring those issues to our attention.  but 
> it is more likely that the manual needs fixing than anything else.

That's fine.  My only aim here is to raise the issue.

By the way, if you (plural) think it would be helpful I'd be happy to 
take a stab at rewriting this part of the manual.  Writing docs is a 
drag, but it would probably be a useful exercise for me.

rg

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-02-02  5:23                 ` Ron Garret
@ 2010-02-02  5:43                   ` Nicolas Pitre
  2010-02-02 21:07                   ` tytso
  1 sibling, 0 replies; 111+ messages in thread
From: Nicolas Pitre @ 2010-02-02  5:43 UTC (permalink / raw)
  To: Ron Garret; +Cc: git

On Mon, 1 Feb 2010, Ron Garret wrote:

>  Nicolas Pitre <nico@fluxnic.net> wrote:
> 
> > It is good of course that you bring those issues to our attention.  but 
> > it is more likely that the manual needs fixing than anything else.
> 
> That's fine.  My only aim here is to raise the issue.
> 
> By the way, if you (plural) think it would be helpful I'd be happy to 
> take a stab at rewriting this part of the manual.  Writing docs is a 
> drag, but it would probably be a useful exercise for me.

Please feel free to contribute.  We are all volunteers here and extra 
help is always welcome. The file Documentation/SubmittingPatches should 
give you lots of useful hints.


Nicolas

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-02-02  1:12                 ` Ron Garret
@ 2010-02-02 19:19                   ` J. Bruce Fields
  2010-02-02 22:04                     ` Ron Garret
  0 siblings, 1 reply; 111+ messages in thread
From: J. Bruce Fields @ 2010-02-02 19:19 UTC (permalink / raw)
  To: Ron Garret; +Cc: git

On Mon, Feb 01, 2010 at 05:12:42PM -0800, Ron Garret wrote:
> In article <7vk4uwmp95.fsf@alter.siamese.dyndns.org>,
>  Junio C Hamano <gitster@pobox.com> wrote:
> 
> > Ron Garret <ron1@flownet.com> writes:
> > 
> > > The manual specifically contradicts you, so either you are wrong or the 
> > > manual is wrong.
> > 
> > In case you haven't noticed, Pasky is one of the old timers and he knows a
> > thing or two about the git's world model.
> 
> My intent was not to diss Pasky, it was just to point out a disconnect 
> between what he was saying and what the manual says.  It's quite 
> possible that the manual is wrong or out of date or just misleading.  
> But it says what it says.
> 
> > And I do not see a contradiction in what the manual describes and "a
> > branch is a named pointer to a commit" (although "named" can probably be
> > omitted as "unnamed pointer" is not useful at the UI level).
> 
> But that's not what the manual says.  The manual says, "When we need to 
> be precise, we will use the word "branch" to mean a line of 
> development..."  Those are the first words in the section entitled 
> "Understanding history: What is a branch?"  It certainly appears to the 
> untrained eye that that is intended to be the definition of a branch.

My memory is that I'd seen the word "branch" used for both meanings (a
linear piece of history, and a ref under ref/heads/), so figured we
needed terms for both.

But then I didn't really use that distinction anywhere.  On a quick skim
the only instance I can see of the first sense is in
http://kernel.org/pub/software/scm/git-core/docs/user-manual.html#counting-commits-on-a-branch,
which could probably be reworded.

It still may be worth acknowledging the confusion; e.g., something like:

	In the above diagram, "A", "B", and "master" are all references
	to a point in history.  We call all three "branches".

	Informally, the word "branch" is sometimes also used to the
	entire line of development leading up to one of these points,
	or, more generally, to any individual line of development.  But
	when speaking about git, a "branch" (or "branch head") will
	always be a reference to a point in history, and in particular a
	reference which may be advanced to new commits by future
	development.

Eh, I don't know if that's helpful; maybe that section could just be
deleted.  Or replaced by a more general discusion of the ref/ namespace.

--b.

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-02-02  5:23                 ` Ron Garret
  2010-02-02  5:43                   ` Nicolas Pitre
@ 2010-02-02 21:07                   ` tytso
  1 sibling, 0 replies; 111+ messages in thread
From: tytso @ 2010-02-02 21:07 UTC (permalink / raw)
  To: Ron Garret; +Cc: git

On Mon, Feb 01, 2010 at 09:23:12PM -0800, Ron Garret wrote:
> That's fine.  My only aim here is to raise the issue.
> 
> By the way, if you (plural) think it would be helpful I'd be happy to 
> take a stab at rewriting this part of the manual.  Writing docs is a 
> drag, but it would probably be a useful exercise for me.

It's definitely helpful to have someone who is learning how things
works to point out deficiencies and (ideally) suggest improvements to
the documentation.  Most of us here either were around at the
beginning, or (like myself) have used git long enough that we *know*
how things works, and reading the manual with the eyes of a novice is
a skill that few experts have.  It's why tech writers are (well, should
be) paid the big bucks.  :-)

					- Ted

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-02-02 19:19                   ` J. Bruce Fields
@ 2010-02-02 22:04                     ` Ron Garret
  2010-02-03 18:27                       ` J. Bruce Fields
  0 siblings, 1 reply; 111+ messages in thread
From: Ron Garret @ 2010-02-02 22:04 UTC (permalink / raw)
  To: git

In article <20100202191942.GB9628@fieldses.org>,
 "J. Bruce Fields" <bfields@fieldses.org> wrote:

> On Mon, Feb 01, 2010 at 05:12:42PM -0800, Ron Garret wrote:
> > In article <7vk4uwmp95.fsf@alter.siamese.dyndns.org>,
> >  Junio C Hamano <gitster@pobox.com> wrote:
> > 
> > > Ron Garret <ron1@flownet.com> writes:
> > > 
> > > > The manual specifically contradicts you, so either you are wrong or the 
> > > > manual is wrong.
> > > 
> > > In case you haven't noticed, Pasky is one of the old timers and he knows 
> > > a
> > > thing or two about the git's world model.
> > 
> > My intent was not to diss Pasky, it was just to point out a disconnect 
> > between what he was saying and what the manual says.  It's quite 
> > possible that the manual is wrong or out of date or just misleading.  
> > But it says what it says.
> > 
> > > And I do not see a contradiction in what the manual describes and "a
> > > branch is a named pointer to a commit" (although "named" can probably be
> > > omitted as "unnamed pointer" is not useful at the UI level).
> > 
> > But that's not what the manual says.  The manual says, "When we need to 
> > be precise, we will use the word "branch" to mean a line of 
> > development..."  Those are the first words in the section entitled 
> > "Understanding history: What is a branch?"  It certainly appears to the 
> > untrained eye that that is intended to be the definition of a branch.
> 
> My memory is that I'd seen the word "branch" used for both meanings (a
> linear piece of history, and a ref under ref/heads/), so figured we
> needed terms for both.
> 
> But then I didn't really use that distinction anywhere.  On a quick skim
> the only instance I can see of the first sense is in
> http://kernel.org/pub/software/scm/git-core/docs/user-manual.html#counting-com
> mits-on-a-branch,
> which could probably be reworded.
> 
> It still may be worth acknowledging the confusion; e.g., something like:
> 
> 	In the above diagram, "A", "B", and "master" are all references
> 	to a point in history.  We call all three "branches".
> 
> 	Informally, the word "branch" is sometimes also used to the
> 	entire line of development leading up to one of these points,
> 	or, more generally, to any individual line of development.  But
> 	when speaking about git, a "branch" (or "branch head") will
> 	always be a reference to a point in history, and in particular a
> 	reference which may be advanced to new commits by future
> 	development.
> 
> Eh, I don't know if that's helpful; maybe that section could just be
> deleted.  Or replaced by a more general discusion of the ref/ namespace.

FWIW, I find the above verbiage to to be very clear, much better than 
what is there now.  You might also add that branches are almost exactly 
the same as tags.  The only difference (AFAIK) is that tags get dragged 
along by commits and resets and tags don't.

rg

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-02-02 22:04                     ` Ron Garret
@ 2010-02-03 18:27                       ` J. Bruce Fields
  0 siblings, 0 replies; 111+ messages in thread
From: J. Bruce Fields @ 2010-02-03 18:27 UTC (permalink / raw)
  To: Ron Garret; +Cc: git

On Tue, Feb 02, 2010 at 02:04:22PM -0800, Ron Garret wrote:
> In article <20100202191942.GB9628@fieldses.org>,
>  "J. Bruce Fields" <bfields@fieldses.org> wrote:
> 
> > My memory is that I'd seen the word "branch" used for both meanings (a
> > linear piece of history, and a ref under ref/heads/), so figured we
> > needed terms for both.
> > 
> > But then I didn't really use that distinction anywhere.  On a quick skim
> > the only instance I can see of the first sense is in
> > http://kernel.org/pub/software/scm/git-core/docs/user-manual.html#counting-com
> > mits-on-a-branch,
> > which could probably be reworded.
> > 
> > It still may be worth acknowledging the confusion; e.g., something like:
> > 
> > 	In the above diagram, "A", "B", and "master" are all references
> > 	to a point in history.  We call all three "branches".
> > 
> > 	Informally, the word "branch" is sometimes also used to the
> > 	entire line of development leading up to one of these points,
> > 	or, more generally, to any individual line of development.  But
> > 	when speaking about git, a "branch" (or "branch head") will
> > 	always be a reference to a point in history, and in particular a
> > 	reference which may be advanced to new commits by future
> > 	development.
> > 
> > Eh, I don't know if that's helpful; maybe that section could just be
> > deleted.  Or replaced by a more general discusion of the ref/ namespace.
> 
> FWIW, I find the above verbiage to to be very clear, much better than 
> what is there now.  You might also add that branches are almost exactly 
> the same as tags.  The only difference (AFAIK) is that tags get dragged 
> along by commits and resets and tags don't.

Might also be worth considering whether this:

	http://kernel.org/pub/software/scm/git-core/docs/user-manual.html#how-git-stores-references

or some other general introduction to refs, should be moved to appear
earlier in the manual.

Apologies, though, I can't volunteer for now; if you'd like any of this
to happen, I'd recommend sending Junio patches.  (I'll try to read them
if you cc: me.)

--b.

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-29 20:35   ` Johannes Schindelin
  2010-01-29 21:16     ` Ron1
@ 2010-01-31  7:32     ` Junio C Hamano
  1 sibling, 0 replies; 111+ messages in thread
From: Junio C Hamano @ 2010-01-31  7:32 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Jacob Helwig, Ron1, git

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

> Just as a general hint, I think the best documentation about Git was 
> written by J. Bruce Fields (the user manual) and Scott Chacon (everything 
> that has GitHub written on it, and Git Pro, and much, much more).

The last one is "Pro Git": http://progit.org/book/; highly recommended.

> ... If you
> happen to speak Japanese, Junio's book might help you understand the ideas 
> behind the current Git user interface, too.

Nah, I don't talk about UIs.  I talk more about concepts.

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-30 19:02               ` Junio C Hamano
@ 2010-01-30 19:24                 ` Ron Garret
  0 siblings, 0 replies; 111+ messages in thread
From: Ron Garret @ 2010-01-30 19:24 UTC (permalink / raw)
  To: git

In article <7veil7pgb2.fsf@alter.siamese.dyndns.org>,
 Junio C Hamano <gitster@pobox.com> wrote:

> Ron Garret <ron1@flownet.com> writes:
> 
> >> > > If I do a git reset --hard then I get the old version, but I lose my 
> >> > > HEAD pointer so that git diff doesn't give me what I want any more.
> 
> I think it would be helpful to point out one issue that may hurt you (and
> anybody who thinks "git update --tree" without --index is a good idea).
> 
> Keeping the index and HEAD in sync but matching the work tree files to
> that of a different commit has one major downside.  To git, a work tree
> file that does not exist in the index is a yet-to-be-added-untracked file
> (that is how and why "rm --cached file" works, for example).  It won't
> participate in the diff output (other than being treated as "no such file
> in the work tree version").
> 
> Suppose that you used to have a path in older revision, but not in the
> current revision.  You remove everything from the work tree and replace it
> with the files in the older revision, and you do not touch HEAD nor index.
> "git diff -R" appears to show "what changed since that older version and
> the latest", because it compares what is in the index relative to what is
> in the work tree.  Nice.
> 
> Not quite.  Since the index does not know that path you recently removed,
> you won't see that path.  If you run "git ls-files" for a list of files
> known to git, it wouldn't be shown either.
> 
> Your original "git checkout master^" is a valid and probably the optimal
> way to get a checkout of a older revision (which you could feed to your
> running Lisp interpreter, in addition to being able to run "less" and
> "make" on them).  Exactly because the index is updated to that of the
> older version, you won't lose the sight of the path that you removed in a
> later version, and you can review the change with "git diff -R master".
> 
> I think this is an XY problem that comes from your wanting to use "git
> diff" (compare work tree with index) instead of "git diff $commit", and
> that was because you wanted to use "HEAD" as a name of a commit.  If you
> used a branch name you originally came from, none of this desire to "keep
> index intact" or "keep HEAD intact" would have been necessary.

That's a very good point.

> But this is all tangent; I think you now know more about git to improve
> your IDE integration, without fighting with git but instead taking
> advantage of it.

I hope so :-)

Thanks to everyone who responded in this thread.  It's been very 
educational.  I am very impressed at how supportive this community is to 
a newcomer like me.

rg

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-30  0:18             ` Ron Garret
@ 2010-01-30 19:02               ` Junio C Hamano
  2010-01-30 19:24                 ` Ron Garret
  0 siblings, 1 reply; 111+ messages in thread
From: Junio C Hamano @ 2010-01-30 19:02 UTC (permalink / raw)
  To: Ron Garret; +Cc: git

Ron Garret <ron1@flownet.com> writes:

>> > > If I do a git reset --hard then I get the old version, but I lose my 
>> > > HEAD pointer so that git diff doesn't give me what I want any more.

I think it would be helpful to point out one issue that may hurt you (and
anybody who thinks "git update --tree" without --index is a good idea).

Keeping the index and HEAD in sync but matching the work tree files to
that of a different commit has one major downside.  To git, a work tree
file that does not exist in the index is a yet-to-be-added-untracked file
(that is how and why "rm --cached file" works, for example).  It won't
participate in the diff output (other than being treated as "no such file
in the work tree version").

Suppose that you used to have a path in older revision, but not in the
current revision.  You remove everything from the work tree and replace it
with the files in the older revision, and you do not touch HEAD nor index.
"git diff -R" appears to show "what changed since that older version and
the latest", because it compares what is in the index relative to what is
in the work tree.  Nice.

Not quite.  Since the index does not know that path you recently removed,
you won't see that path.  If you run "git ls-files" for a list of files
known to git, it wouldn't be shown either.

Your original "git checkout master^" is a valid and probably the optimal
way to get a checkout of a older revision (which you could feed to your
running Lisp interpreter, in addition to being able to run "less" and
"make" on them).  Exactly because the index is updated to that of the
older version, you won't lose the sight of the path that you removed in a
later version, and you can review the change with "git diff -R master".

I think this is an XY problem that comes from your wanting to use "git
diff" (compare work tree with index) instead of "git diff $commit", and
that was because you wanted to use "HEAD" as a name of a commit.  If you
used a branch name you originally came from, none of this desire to "keep
index intact" or "keep HEAD intact" would have been necessary.

But this is all tangent; I think you now know more about git to improve
your IDE integration, without fighting with git but instead taking
advantage of it.

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-30  8:59                 ` Jeff King
@ 2010-01-30 18:40                   ` Ron Garret
  0 siblings, 0 replies; 111+ messages in thread
From: Ron Garret @ 2010-01-30 18:40 UTC (permalink / raw)
  To: git

In article <20100130085957.GA20112@coredump.intra.peff.net>,
 Jeff King <peff@peff.net> wrote:

>      I can't think of an improved message that
>      would make the situation clear without adding a bunch of annoying
>      text.

In situations like that a pointer to the docs, or a keyword to search on 
is often sufficient.

rg

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-30  6:25                                             ` Ron Garret
@ 2010-01-30 18:25                                               ` Junio C Hamano
  0 siblings, 0 replies; 111+ messages in thread
From: Junio C Hamano @ 2010-01-30 18:25 UTC (permalink / raw)
  To: Ron Garret; +Cc: git

Ron Garret <ron1@flownet.com> writes:

>> Also it would be nicer (just a personal preference) if a picture that
>> forks only one branch forks it upwards, like this:
>> 
>>              o---o
>>             /    
>>     ---o---o---o
>> 
>> not downwards, like this:
>> 
>>     ---o---o---o
>>             \
>>              o---o
>
> Just out of curiosity, why does this matter to you?

Imagine you pick up the whole assembly and let it fall (gravity works from
top to bottom of the sheet of paper it is printed on, not from above down
to the face of paper it is printed on)?  Which one looks more stable and
would land on the floor as-is?

The top one, of course.  It sits better when printed, and especially so
when it is presented as an illustration that comes before a paragraph,
which is a more-or-less rectangular-looking block of text; at least it
looks that way to me.

Didn't I say it is just a "personal preference"?  ;-)

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-29 21:51               ` Nicolas Pitre
  2010-01-29 21:58                 ` Junio C Hamano
@ 2010-01-30  8:59                 ` Jeff King
  2010-01-30 18:40                   ` Ron Garret
  1 sibling, 1 reply; 111+ messages in thread
From: Jeff King @ 2010-01-30  8:59 UTC (permalink / raw)
  To: Nicolas Pitre
  Cc: Sverre Rabbelier, Junio C Hamano, Git List, Ron1, Jacob Helwig

On Fri, Jan 29, 2010 at 04:51:18PM -0500, Nicolas Pitre wrote:

> > Using a detached head is a more advanced feature than wanting to
> > checkout a remote branch locally, creating a local tracking branch. As
> > such, 'git checkout origin/topic' now means the same as 'git checkout
> > -t origin/topic', and you can get the old behavior back by doing 'git
> > checkout origin/topic^0'.
> 
> What purpose does this "feature" serve?  Making sure people remain 
> stupid and get even more confused when the special dwimery doesn't work 
> because they don't know the difference between a local branch and a 
> remote tracking branch?
> 
> And now people will be left wondering why after a fetch they don't get 
> the latest stuff when they do "git checkout topic" again.  Is this any 
> better?

I am entering the discussion a bit late, and things have moved on from
this point, but I wanted to mention that I have in the past made the
same argument that you have in your second paragraph (that you leave
users _more_ confused after a fetch), but somebody (I think Jay) managed
to convince me otherwise.

The saving feature is that we now print out the symmetric difference
information between a branch and its upstream during checkout. So the
user experience looks like:

  $ git checkout topic
  Branch topic set up to track remote branch topic from origin.
  Switched to a new branch 'topic'

  ... time passes ...

  $ git fetch
  ...
     9f137a4..22ac6a6  topic      -> origin/topic

  $ git checkout topic
  Switched to branch 'topic'
  Your branch is behind 'origin/topic' by 6 commits, and can be fast-forwarded.

So I think it is not quite as bad as at least I had originally thought.
There are still a few rough edges, though:

  1. If I stay on the 'topic' branch and run "git fetch", then I don't
     see the checkout message. If I don't understand that a local branch
     has been created, I might expect the new changes to be present. But
     they're not. If I do a pull instead, it does "just work", even if I
     am clueless about the local branch.

     I wonder if a "fetch" which updates the upstream branch of the
     current HEAD should print something like the "Your branch is
     behind..." message.

  2. If I am clueless that the local branch exists, I can see that there
     are new changes that I can "fast forward". But if I am clueless
     about local branches, do I know that means I need to run "git merge
     origin/topic"?  However, I can't think of an improved message that
     would make the situation clear without adding a bunch of annoying
     text.

-Peff

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-30  8:02                     ` Junio C Hamano
@ 2010-01-30  8:56                       ` Ron Garret
  0 siblings, 0 replies; 111+ messages in thread
From: Ron Garret @ 2010-01-30  8:56 UTC (permalink / raw)
  To: git

In article <7vhbq4xbok.fsf@alter.siamese.dyndns.org>,
 Junio C Hamano <gitster@pobox.com> wrote:

> Ron Garret <ron1@flownet.com> writes:
> 
> > It wouldn't.  Was this a trick question?  Did you mean to ask what would 
> > happen if I ran commit -a?
> 
> I didn't mean _literally_ "git commit".  Any random thing you may want to
> do when you come back to work the next day and find a checked out work
> tree.  Viewing, editing, committing, etc.

Then I really don't understand the issue.  I'd be in a situation that is 
no different from (in fact indistinguishable from) having manually 
edited my code so that it looks like an earlier checked-in version.  
What's the problem?

rg

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-30  7:31                   ` Ron Garret
@ 2010-01-30  8:02                     ` Junio C Hamano
  2010-01-30  8:56                       ` Ron Garret
  0 siblings, 1 reply; 111+ messages in thread
From: Junio C Hamano @ 2010-01-30  8:02 UTC (permalink / raw)
  To: Ron Garret; +Cc: git

Ron Garret <ron1@flownet.com> writes:

> It wouldn't.  Was this a trick question?  Did you mean to ask what would 
> happen if I ran commit -a?

I didn't mean _literally_ "git commit".  Any random thing you may want to
do when you come back to work the next day and find a checked out work
tree.  Viewing, editing, committing, etc.

>> *1* As a set of "building blocks" to implement "reset" and "checkout", I
>> don't necessarily agree that "update" would be a good way to go from the
>> implementation standpoint, but that is a totally separate matter.
>
> Did you mean "don't necessarily DISagree"?

I have huge doubts that "update" is the best way to do reset/checkout.

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-30  6:45                 ` Junio C Hamano
@ 2010-01-30  7:31                   ` Ron Garret
  2010-01-30  8:02                     ` Junio C Hamano
  0 siblings, 1 reply; 111+ messages in thread
From: Ron Garret @ 2010-01-30  7:31 UTC (permalink / raw)
  To: git

In article <7vaavw1478.fsf@alter.siamese.dyndns.org>,
 Junio C Hamano <gitster@pobox.com> wrote:

> Ron Garret <ron1@flownet.com> writes:
> 
> > No, because it would make it much easier to map intent back into a 
> > command that implements that intent.  Don't forget, this whole thing 
> > began because I wanted to do something very simple, tried what seemed to 
> > be the obvious way to do it, and stumbled accidentally on an advanced 
> > feature.  That would not have happened if I'd been able to just do a git 
> > update --tree master^.
> 
> Doing that _will_ confuse you in your next step.  Can you explain what
> happens if you run "git commit" from that state,

Nothing.

> why "git commit" does so,

Because my index would be empty.

> and how that is useful?

It wouldn't.  Was this a trick question?  Did you mean to ask what would 
happen if I ran commit -a?

> You may be too narrowly focused on only one single step, but I am more
> worried about the whole user experience: "I managed to do this, I am
> happy, but then the next step doesn't make much sense.  Now what?"

I think you may be making some unwarranted assumptions about my end goal.

> > What difference does that make?  Sure, there would be ways to shoot 
> > yourself in the foot with git update, but there is no shortage of ways 
> > to shoot yourself in the foot now.
> 
> As long as you have a coherent picture of the workflow individual commands
> are supporting, there is no "shoot yourself in the foot".  "git update" on
> the other hand is _designed_ not to allow such a coherent picture to be
> formed in the user's head, by letting random combinations that may or may
> not make sense.

That is a valid point.  I guess this depends on whether you think of git 
as merely a revision control system for computer source code, or if you 
think of it as a more general tool that can and should be used in other 
kinds of applications as well.

> > BTW, nothing prevents you from providing the usual repertoire of 
> > higher-level functionality as thin layers on top of something like git 
> > update.
> 
> That is more or less the same as what I said in the footnote, which you
> didn't quote from my message.

Yes, sorry about that.

> The flexibility of "update" may help Porcelain writers to pick and use
> only useful/usable combinations to present "the usual repertoire" for end
> users.  At the philosophical level of "building blocks", I do not oppose
> to such flexibility [*1*].
> 
> But.
> 
> As the main point of Michael's message was that he thought it may make
> things less confusing to the end users, I am pointing out that unleashing
> such an uncontrolled flexibility directly to end users will _not_ help
> reduce their confusion.
> 
> [Footnote]
> 
> *1* As a set of "building blocks" to implement "reset" and "checkout", I
> don't necessarily agree that "update" would be a good way to go from the
> implementation standpoint, but that is a totally separate matter.

Did you mean "don't necessarily DISagree"?

rg

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-30  6:16               ` Ron Garret
@ 2010-01-30  6:45                 ` Junio C Hamano
  2010-01-30  7:31                   ` Ron Garret
  0 siblings, 1 reply; 111+ messages in thread
From: Junio C Hamano @ 2010-01-30  6:45 UTC (permalink / raw)
  To: Ron Garret; +Cc: git

Ron Garret <ron1@flownet.com> writes:

> No, because it would make it much easier to map intent back into a 
> command that implements that intent.  Don't forget, this whole thing 
> began because I wanted to do something very simple, tried what seemed to 
> be the obvious way to do it, and stumbled accidentally on an advanced 
> feature.  That would not have happened if I'd been able to just do a git 
> update --tree master^.

Doing that _will_ confuse you in your next step.  Can you explain what
happens if you run "git commit" from that state, why "git commit" does so,
and how that is useful?

You may be too narrowly focused on only one single step, but I am more
worried about the whole user experience: "I managed to do this, I am
happy, but then the next step doesn't make much sense.  Now what?"

> What difference does that make?  Sure, there would be ways to shoot 
> yourself in the foot with git update, but there is no shortage of ways 
> to shoot yourself in the foot now.

As long as you have a coherent picture of the workflow individual commands
are supporting, there is no "shoot yourself in the foot".  "git update" on
the other hand is _designed_ not to allow such a coherent picture to be
formed in the user's head, by letting random combinations that may or may
not make sense.

> BTW, nothing prevents you from providing the usual repertoire of 
> higher-level functionality as thin layers on top of something like git 
> update.

That is more or less the same as what I said in the footnote, which you
didn't quote from my message.

The flexibility of "update" may help Porcelain writers to pick and use
only useful/usable combinations to present "the usual repertoire" for end
users.  At the philosophical level of "building blocks", I do not oppose
to such flexibility [*1*].

But.

As the main point of Michael's message was that he thought it may make
things less confusing to the end users, I am pointing out that unleashing
such an uncontrolled flexibility directly to end users will _not_ help
reduce their confusion.

[Footnote]

*1* As a set of "building blocks" to implement "reset" and "checkout", I
don't necessarily agree that "update" would be a good way to go from the
implementation standpoint, but that is a totally separate matter.

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-30  5:21                                           ` Junio C Hamano
@ 2010-01-30  6:25                                             ` Ron Garret
  2010-01-30 18:25                                               ` Junio C Hamano
  0 siblings, 1 reply; 111+ messages in thread
From: Ron Garret @ 2010-01-30  6:25 UTC (permalink / raw)
  To: git

In article <7v1vh8417w.fsf@alter.siamese.dyndns.org>,
 Junio C Hamano <gitster@pobox.com> wrote:

> Nicolas Pitre <nico@fluxnic.net> writes:
> 
> > Could you please take this really nice explanation and make it into a 
> > patch adding a "Detached HEAD" section in the git-checkout.txt manual 
> > page please?
> 
> Good suggestion.
> 
> I'd be happier if the description didn't say "SHA-1", but instead said
> "object name".
> 
> Also it would be nicer (just a personal preference) if a picture that
> forks only one branch forks it upwards, like this:
> 
>              o---o
>             /    
>     ---o---o---o
> 
> not downwards, like this:
> 
>     ---o---o---o
>             \
>              o---o

Just out of curiosity, why does this matter to you?  Downwards seems 
more intuitive to me.  Time should advance left to right and top to 
bottom IMHO.

rg

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-30  4:52                                       ` Jay Soffian
  2010-01-30  5:15                                         ` Nicolas Pitre
  2010-01-30  5:18                                         ` Junio C Hamano
@ 2010-01-30  6:23                                         ` Ron Garret
  2 siblings, 0 replies; 111+ messages in thread
From: Ron Garret @ 2010-01-30  6:23 UTC (permalink / raw)
  To: git

In article 
<76718491001292052x7f46d479lfeff7b66121502c3@mail.gmail.com>,
 Jay Soffian <jaysoffian@gmail.com> wrote:

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

[snip]

> So that was a really long explanation, but I hope it clears things up.

Yes, that was very helpful, thank you.

Might it make more sense to talk about "anonymous branches" or "unnamed 
branches" instead of "detached heads"?  I think something like the 
following would be much easier to grasp:

WARNING: Your HEAD is now pointing to a commit that is not a named
branch head.  As a result of this, any commits off of this one may
be lost during the next garbage collection.  If you want to prevent
this, you should give this branch head a name by doing ...

rg

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-30  3:06             ` Junio C Hamano
@ 2010-01-30  6:16               ` Ron Garret
  2010-01-30  6:45                 ` Junio C Hamano
  0 siblings, 1 reply; 111+ messages in thread
From: Ron Garret @ 2010-01-30  6:16 UTC (permalink / raw)
  To: git

In article <7vvdek70ma.fsf@alter.siamese.dyndns.org>,
 Junio C Hamano <gitster@pobox.com> wrote:

> Michael Witten <mfwitten@gmail.com> writes:
> 
> > Isn't the difference between 'checkout' and 'reset' almost essentially
> > a matter of whether the branch reference (HEAD), index, and tree are
> > modified? Couldn't these commands be merged into one command or make
> > use of one command?
> 
> I don't think that reduces any confusion.

Ahem... as the confused one here I respectfully disagree.

> By exposing orthogonal options like --index, --head, etc., you are opening
> yourself to nonsensical combinations that were never possible with the
> existing command set, and I suspect it would make it even more confusing,
> not less.

No, because it would make it much easier to map intent back into a 
command that implements that intent.  Don't forget, this whole thing 
began because I wanted to do something very simple, tried what seemed to 
be the obvious way to do it, and stumbled accidentally on an advanced 
feature.  That would not have happened if I'd been able to just do a git 
update --tree master^.

> What does "git update --detach $commit" _really_ mean, for example?

What difference does that make?  Sure, there would be ways to shoot 
yourself in the foot with git update, but there is no shortage of ways 
to shoot yourself in the foot now.  And now if you shoot yourself in the 
foot you have to start by trying to figure out where the bullet came 
from.

BTW, nothing prevents you from providing the usual repertoire of 
higher-level functionality as thin layers on top of something like git 
update.

> You can of course say "it detaches the HEAD at $commit, but otherwise does
> not change anything else", but such a mechanical description does not give
> an answer that helps end users.  "What would I do after doing that?" and
> "What would I use this for?" are the questions they need an answer to.

Sure.  So document the combinations that make sense, and then say "You 
can mix and match the options in other ways, but you probably shouldn't 
unless you really know what you're doing."  Done.

> Flexibility and orthogonality is often good, but uncontrolled flexibility
> is not.

That seems to me to run directly counter to the design philosophy behind 
git.

rg

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-30  4:39                                         ` Nicolas Pitre
  2010-01-30  5:05                                           ` Nicolas Pitre
  2010-01-30  5:53                                           ` Mark Lodato
@ 2010-01-30  6:03                                           ` Junio C Hamano
  2 siblings, 0 replies; 111+ messages in thread
From: Junio C Hamano @ 2010-01-30  6:03 UTC (permalink / raw)
  To: Nicolas Pitre; +Cc: Mark Lodato, Sverre Rabbelier, Git List, Ron1, Jacob Helwig

Nicolas Pitre <nico@fluxnic.net> writes:

> First, I'm afraid that "Checking out commit 'foobar'" might be confusing 
> as this may happen through either a remote branch, a tag, or any random 
> commit.  It seems to me that "Checking out 'v2.5'" is less confusing 
> than "Checking out commit 'v2.5'".  But that's a minor detail and 
> probably a personal preference.
> ...
> To the contrary: this "detached HEAD" is exactly what you need if you 
> want to relate to any documentation or perform a search for more 
> information.  Like it or not, this detached HEAD term is exactly what 
> this Git concept is all about and how it is designated everywhere.  The 
> sooner Git users see and learn about it the better.

As I am not good at keeping track of different proposals to change this
word here and that word there, I expect this will probably need at least
few rotations of earth to get input from people in different timezones,
and I think this is post 1.7.0 item anyway, I'll queue the attached draft
in 'pu' and keep it there, to make it easier for others to tweak the
message.

-- >8 --
Subject: [PATCH] Reword "detached HEAD" notification

The old "advice" message explained how to create a branch after going into
a detached HEAD state but didn't make it clear why the user may want to do
so.  Also "moving to ... which isn't a local branch" was unclear if it is
complaining, if it is describing the new state, or if it is explaining why
the HEAD is detached (the true reason is the last one).

Give the established phrase 'detached HEAD' first to make it easy for
users to look up the concept in documentation, and briefly describe what
can be done in the state (i.e. play around without having to clean up)
before telling the user how to keep what was done during the temporary
state.

Allow the long description to be hidden by setting advice.detachedHead
configuration to false.

We might want to customize the advice depending on how the commit to check
out was spelled (e.g. instead of "new-branch-name", we way want to say
"topic" when "git checkout origin/topic" triggered this message) in later
updates, but this encapsulates that into a separate function and it should
be a good first step.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 Documentation/config.txt |    5 +++++
 advice.c                 |    2 ++
 advice.h                 |    1 +
 builtin-checkout.c       |   18 ++++++++++++++++--
 t/t7201-co.sh            |   32 ++++++++++++++++++++++----------
 5 files changed, 46 insertions(+), 12 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 17901e2..fee44d8 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -138,6 +138,11 @@ advice.*::
 		Advice on how to set your identity configuration when
 		your information is guessed from the system username and
 		domain name. Default: true.
+
+	detachedHead::
+		Advice shown when you used linkgit::git-checkout[1] to
+		move to the detach HEAD state, to instruct how to create
+		a local branch after the fact.  Default: true.
 --
 
 core.fileMode::
diff --git a/advice.c b/advice.c
index 936d98b..0be4b5f 100644
--- a/advice.c
+++ b/advice.c
@@ -5,6 +5,7 @@ int advice_status_hints = 1;
 int advice_commit_before_merge = 1;
 int advice_resolve_conflict = 1;
 int advice_implicit_identity = 1;
+int advice_detached_head = 1;
 
 static struct {
 	const char *name;
@@ -15,6 +16,7 @@ static struct {
 	{ "commitbeforemerge", &advice_commit_before_merge },
 	{ "resolveconflict", &advice_resolve_conflict },
 	{ "implicitidentity", &advice_implicit_identity },
+	{ "detachedhead", &advice_detached_head },
 };
 
 int git_default_advice_config(const char *var, const char *value)
diff --git a/advice.h b/advice.h
index 9b7a3ad..3244ebb 100644
--- a/advice.h
+++ b/advice.h
@@ -8,6 +8,7 @@ extern int advice_status_hints;
 extern int advice_commit_before_merge;
 extern int advice_resolve_conflict;
 extern int advice_implicit_identity;
+extern int advice_detached_head;
 
 int git_default_advice_config(const char *var, const char *value);
 
diff --git a/builtin-checkout.c b/builtin-checkout.c
index 5277817..c5ab783 100644
--- a/builtin-checkout.c
+++ b/builtin-checkout.c
@@ -488,6 +488,20 @@ static void report_tracking(struct branch_info *new)
 	strbuf_release(&sb);
 }
 
+static void detach_advice(const char *old_path, const char *new_name)
+{
+	const char fmt[] =
+	"Note: checking out '%s'.\n\n"
+	"You are in 'detached HEAD' state. You can look around, make experimental\n"
+	"changes and commit them, and you can discard any commits you make in this\n"
+	"state without impacting any branches by performing another checkout.\n\n"
+	"If you want to create a new branch to retain commits you create, you may\n"
+	"do so (now or later) by using -b with the checkout command again. Example:\n\n"
+	"  git checkout -b new_branch_name\n\n";
+
+	fprintf(stderr, fmt, new_name);
+}
+
 static void update_refs_for_switch(struct checkout_opts *opts,
 				   struct branch_info *old,
 				   struct branch_info *new)
@@ -522,8 +536,8 @@ static void update_refs_for_switch(struct checkout_opts *opts,
 		update_ref(msg.buf, "HEAD", new->commit->object.sha1, NULL,
 			   REF_NODEREF, DIE_ON_ERR);
 		if (!opts->quiet) {
-			if (old->path)
-				fprintf(stderr, "Note: moving to '%s' which isn't a local branch\nIf you want to create a new branch from this checkout, you may do so\n(now or later) by using -b with the checkout command again. Example:\n  git checkout -b <new_branch_name>\n", new->name);
+			if (old->path && advice_detached_head)
+				detach_advice(old->path, new->name);
 			describe_detached_head("HEAD is now at", new->commit);
 		}
 	}
diff --git a/t/t7201-co.sh b/t/t7201-co.sh
index 6442f71..d20ed61 100755
--- a/t/t7201-co.sh
+++ b/t/t7201-co.sh
@@ -166,19 +166,31 @@ test_expect_success 'checkout -m with merge conflict' '
 	! test -s current
 '
 
-test_expect_success 'checkout to detach HEAD' '
+test_expect_success 'checkout to detach HEAD (with advice declined)' '
 
+	git config advice.detachedHead false &&
 	git checkout -f renamer && git clean -f &&
 	git checkout renamer^ 2>messages &&
-	(cat >messages.expect <<EOF
-Note: moving to '\''renamer^'\'' which isn'\''t a local branch
-If you want to create a new branch from this checkout, you may do so
-(now or later) by using -b with the checkout command again. Example:
-  git checkout -b <new_branch_name>
-HEAD is now at 7329388... Initial A one, A two
-EOF
-) &&
-	test_cmp messages.expect messages &&
+	grep "HEAD is now at 7329388" messages &&
+	test 1 -eq $(wc -l <messages) &&
+	H=$(git rev-parse --verify HEAD) &&
+	M=$(git show-ref -s --verify refs/heads/master) &&
+	test "z$H" = "z$M" &&
+	if git symbolic-ref HEAD >/dev/null 2>&1
+	then
+		echo "OOPS, HEAD is still symbolic???"
+		false
+	else
+		: happy
+	fi
+'
+
+test_expect_success 'checkout to detach HEAD' '
+	git config advice.detachedHead true &&
+	git checkout -f renamer && git clean -f &&
+	git checkout renamer^ 2>messages &&
+	grep "HEAD is now at 7329388" messages &&
+	test 1 -lt $(wc -l <messages) &&
 	H=$(git rev-parse --verify HEAD) &&
 	M=$(git show-ref -s --verify refs/heads/master) &&
 	test "z$H" = "z$M" &&
-- 
1.7.0.rc0.187.g226c

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-30  4:39                                         ` Nicolas Pitre
  2010-01-30  5:05                                           ` Nicolas Pitre
@ 2010-01-30  5:53                                           ` Mark Lodato
  2010-01-30  6:03                                           ` Junio C Hamano
  2 siblings, 0 replies; 111+ messages in thread
From: Mark Lodato @ 2010-01-30  5:53 UTC (permalink / raw)
  To: Nicolas Pitre
  Cc: Junio C Hamano, Sverre Rabbelier, Git List, Ron1, Jacob Helwig

On Fri, Jan 29, 2010 at 11:39 PM, Nicolas Pitre <nico@fluxnic.net> wrote:
> First, I'm afraid that "Checking out commit 'foobar'" might be confusing
> as this may happen through either a remote branch, a tag, or any random
> commit.  It seems to me that "Checking out 'v2.5'" is less confusing
> than "Checking out commit 'v2.5'".  But that's a minor detail and
> probably a personal preference.

I'm fine with "Checking out 'v2.5'".

> I consider that starting the explanation paragraph with " any commits
> you make will be lost" is even more unfriendly, and misleading.  That is
> sure to scare people needlessly.

See wording below.

> I think your wording is just too far on the negative side, and makes Git
> look like an even more difficult tool than it actually is.  And you help
> no one by stating things that are not exactly true even if the truth
> implies that you need to know what you're doing.

What is not true?  Sure, they're not really "lost", but there's no
concise yet fully correct way to say the full truth.  Would you prefer
"discarded"?

> The _whole_ and only
> point of a detached HEAD is actually to be able to make commits even
> without having to create a new branch first.

Wrong.  I have never (purposefully) made a commit on a detached HEAD,
yet I use a detached HEAD all the time.  Why?  Because I checkout a
particular commit to look at code at a given location.  For example, I
recently ran "git checkout v1.6.6.1".  I did not intend to make any
commits on this; I just wanted to look at and compile code at a
particular version.  I think most users do the same thing.  The reason
for the warning is that folks make a mistake of trying to commit
without first switching back to (or creating) a branch.


Anyway, how about the following message, which is more in line with
Junio's last version?

-- >8 -- not a patch -- >8 --
Checking out 'master^0'.

This is not a local branch head, so you are in a 'detached HEAD' state.
If you only plan to look at files, this is fine.  However, any commits you
make will not update a branch, and may be discarded when you check out
another branch or commit.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

 git checkout -b <new_branch_name>

HEAD is now at a9d7c95... Merge branch 'maint'
-- 8< -- not a patch -- 8< --

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-30  5:15                                         ` Nicolas Pitre
  2010-01-30  5:21                                           ` Junio C Hamano
@ 2010-01-30  5:45                                           ` Jay Soffian
  1 sibling, 0 replies; 111+ messages in thread
From: Jay Soffian @ 2010-01-30  5:45 UTC (permalink / raw)
  To: Nicolas Pitre; +Cc: Junio C Hamano, Ron Garret, git

On Sat, Jan 30, 2010 at 12:15 AM, Nicolas Pitre <nico@fluxnic.net> wrote:
> Could you please take this really nice explanation and make it into a
> patch adding a "Detached HEAD" section in the git-checkout.txt manual
> page please?

Will do, and I'll even make the branches go upwards. :-)

j.

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-30  5:11                                             ` Jay Soffian
@ 2010-01-30  5:25                                               ` Nicolas Pitre
  0 siblings, 0 replies; 111+ messages in thread
From: Nicolas Pitre @ 2010-01-30  5:25 UTC (permalink / raw)
  To: Jay Soffian
  Cc: Mark Lodato, Junio C Hamano, Sverre Rabbelier, Git List, Ron1,
	Jacob Helwig

On Sat, 30 Jan 2010, Jay Soffian wrote:

> This sounds right to me too. There's nothing wrong with having a
> detached HEAD, and nothing wrong with creating commits in that state.
> You're effectively creating an anonymous branch in the DAG and it's
> subject to garbage collection if you move away from that anonymous
> branch w/o naming it.
> 
> Pedantic note: you don't lose those commits at the next checkout. They
> are merely subject to garbage collection (and not until they age out
> of HEAD's reflog). I know you know that, just being precise. :-)

Being the actual author of the code managing the separate HEAD reflog, I 
do know that indeed.  ;-)


Nicolas

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  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  5:45                                           ` Jay Soffian
  1 sibling, 1 reply; 111+ messages in thread
From: Junio C Hamano @ 2010-01-30  5:21 UTC (permalink / raw)
  To: Nicolas Pitre; +Cc: Jay Soffian, Ron Garret, git

Nicolas Pitre <nico@fluxnic.net> writes:

> Could you please take this really nice explanation and make it into a 
> patch adding a "Detached HEAD" section in the git-checkout.txt manual 
> page please?

Good suggestion.

I'd be happier if the description didn't say "SHA-1", but instead said
"object name".

Also it would be nicer (just a personal preference) if a picture that
forks only one branch forks it upwards, like this:

             o---o
            /    
    ---o---o---o

not downwards, like this:

    ---o---o---o
            \
             o---o

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-30  4:52                                       ` Jay Soffian
  2010-01-30  5:15                                         ` Nicolas Pitre
@ 2010-01-30  5:18                                         ` Junio C Hamano
  2010-01-30  6:23                                         ` Ron Garret
  2 siblings, 0 replies; 111+ messages in thread
From: Junio C Hamano @ 2010-01-30  5:18 UTC (permalink / raw)
  To: Jay Soffian; +Cc: Ron Garret, git

Jay Soffian <jaysoffian@gmail.com> writes:

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

Yeah, in short, a "branch" is a point, not a line (or lines) of
development that leads to a point, as I said in the beginning.

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-30  4:52                                       ` Jay Soffian
@ 2010-01-30  5:15                                         ` Nicolas Pitre
  2010-01-30  5:21                                           ` 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
  2 siblings, 2 replies; 111+ messages in thread
From: Nicolas Pitre @ 2010-01-30  5:15 UTC (permalink / raw)
  To: Jay Soffian; +Cc: Junio C Hamano, Ron Garret, git

[-- Attachment #1: Type: TEXT/PLAIN, Size: 612 bytes --]

On Fri, 29 Jan 2010, Jay Soffian wrote:

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

Could you please take this really nice explanation and make it into a 
patch adding a "Detached HEAD" section in the git-checkout.txt manual 
page please?


Nicolas

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-30  5:05                                           ` Nicolas Pitre
@ 2010-01-30  5:11                                             ` Jay Soffian
  2010-01-30  5:25                                               ` Nicolas Pitre
  0 siblings, 1 reply; 111+ messages in thread
From: Jay Soffian @ 2010-01-30  5:11 UTC (permalink / raw)
  To: Nicolas Pitre
  Cc: Mark Lodato, Junio C Hamano, Sverre Rabbelier, Git List, Ron1,
	Jacob Helwig

On Sat, Jan 30, 2010 at 12:05 AM, Nicolas Pitre <nico@fluxnic.net> wrote:
> Thinking more about it, I still consider that making 'git commit' more
> noisy is the wrong approach.  Again, the problem is not about making
> commits on a detached HEAD.  but rather about losing those commits at
> the next 'git checkout'.  Probably a warning should be made when that
> checkout is attempted after one or more commits were made on a detached
> HEAD instead, and refuse the checkout by default unless it is forced (-f
> is already taken for some other force meaning).  The warning should say
> how not to lose those commits by suggesting a branch creation, or give
> the hint for performing the checkout anyway.

This sounds right to me too. There's nothing wrong with having a
detached HEAD, and nothing wrong with creating commits in that state.
You're effectively creating an anonymous branch in the DAG and it's
subject to garbage collection if you move away from that anonymous
branch w/o naming it.

Pedantic note: you don't lose those commits at the next checkout. They
are merely subject to garbage collection (and not until they age out
of HEAD's reflog). I know you know that, just being precise. :-)

j.

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-30  3:26                                       ` Ron Garret
  2010-01-30  4:03                                         ` Nicolas Pitre
@ 2010-01-30  5:09                                         ` Junio C Hamano
  1 sibling, 0 replies; 111+ messages in thread
From: Junio C Hamano @ 2010-01-30  5:09 UTC (permalink / raw)
  To: Ron Garret; +Cc: git

Ron Garret <ron1@flownet.com> writes:

>> 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.
>
> OK.  The docs do not make that clear at all.  In fact, the following 
> statement, copied straight from the manual, flatly contradicts what you 
> just said:

There are many places in the documentation that simply predate the
introduction of detached HEAD.  The description talks as if you cannot be
in any state other than on a particular branch.  For example, "git pull"
talks about choosing where to fetch from and what to merge to the head
based on what your current branch is---obviously such a description is
ancient and doesn't talk about what should happen when you do not simply
have any "current" branch.

So it is understandable that you get confused and it is all
documentation's fault, not yours.

> "The special symbol "HEAD" can always be used to refer to the current 
> branch."
>
> Always.  Except when it can't.

Exactly.

We would need to update the documentation.  While doing so, a general
guideline would be to keep in mind that they were written back when you
had to always be on _a_ branch (and they called it "current branch",
"branch HEAD points at", etc.).  When they describe that "the current
branch is updated in such and such way", what happens in a detached HEAD
state is that only the HEAD pointer that directly points at the "currently
checked out commit" is updated, without affecting _any_ branch.

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-30  4:03                                         ` Nicolas Pitre
@ 2010-01-30  5:06                                           ` Jay Soffian
  0 siblings, 0 replies; 111+ messages in thread
From: Jay Soffian @ 2010-01-30  5:06 UTC (permalink / raw)
  To: Nicolas Pitre; +Cc: Ron Garret, git

On Fri, Jan 29, 2010 at 11:03 PM, Nicolas Pitre <nico@fluxnic.net> wrote:
> Have a look at http://eagain.net/articles/git-for-computer-scientists/
>
> That's one of the clearest explanation of the Git branching model I've
> seen.

Ah, I never realized this before, but it doesn't include any
discussion/graphic of what a detached HEAD is. It only shows HEAD
referring to a named branch.

> There is no contradiction.  The "detached HEAD" corresponds to HEAD
> pointing at no branch in particular.  There is just no current branch in
> that case.

Again (referring to my last message), I think Ron's confusion is that
"branch" can mean either a branch in the DAG which is your repo's
history, or it can mean a named branch (something under .git/refs),
and they aren't necessarily the same, although around here when we say
"branch" we almost always mean a named branch.

When HEAD is detached and you create a commit, you're effectively
creating a branch in the DAG, but this branch is anonymous and subject
to garbage collection.

j.

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  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:53                                           ` Mark Lodato
  2010-01-30  6:03                                           ` Junio C Hamano
  2 siblings, 1 reply; 111+ messages in thread
From: Nicolas Pitre @ 2010-01-30  5:05 UTC (permalink / raw)
  To: Mark Lodato
  Cc: Junio C Hamano, Sverre Rabbelier, Git List, Ron1, Jacob Helwig

On Fri, 29 Jan 2010, Nicolas Pitre wrote:

> On Fri, 29 Jan 2010, Mark Lodato wrote:
> 
> > This discussion brings up another good point: The main worry about a
> > detached head is losing commits.  Back in 2008, it was suggested to
> > have a warning when committing on a detached HEAD:
> > 
> > http://kerneltrap.org/mailarchive/git/2008/9/2/3169744
> > 
> > This was before the advice system, so folks complained about it
> > getting in the way, and it was never implemented.  Since we now have a
> > way to easily turn off the warning, perhaps we should bring this topic
> > up again (probably as a separate thread.)
> 
> Possibly.  I don't like the message proposed in that patch though.  
> Since the warning when actually detaching HEAD is about to become way 
> more prominent, the per-commit warning doesn't have to be that noisy 
> anymore.

Thinking more about it, I still consider that making 'git commit' more 
noisy is the wrong approach.  Again, the problem is not about making 
commits on a detached HEAD.  but rather about losing those commits at 
the next 'git checkout'.  Probably a warning should be made when that 
checkout is attempted after one or more commits were made on a detached 
HEAD instead, and refuse the checkout by default unless it is forced (-f 
is already taken for some other force meaning).  The warning should say 
how not to lose those commits by suggesting a branch creation, or give 
the hint for performing the checkout anyway.


Nicolas

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-30  2:59                                     ` Junio C Hamano
  2010-01-30  3:26                                       ` Ron Garret
@ 2010-01-30  4:52                                       ` Jay Soffian
  2010-01-30  5:15                                         ` Nicolas Pitre
                                                           ` (2 more replies)
  1 sibling, 3 replies; 111+ messages in thread
From: Jay Soffian @ 2010-01-30  4:52 UTC (permalink / raw)
  To: Junio C Hamano, Ron Garret; +Cc: git

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.

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-30  3:59                                       ` Mark Lodato
@ 2010-01-30  4:39                                         ` Nicolas Pitre
  2010-01-30  5:05                                           ` Nicolas Pitre
                                                             ` (2 more replies)
  0 siblings, 3 replies; 111+ messages in thread
From: Nicolas Pitre @ 2010-01-30  4:39 UTC (permalink / raw)
  To: Mark Lodato
  Cc: Junio C Hamano, Sverre Rabbelier, Git List, Ron1, Jacob Helwig

[-- Attachment #1: Type: TEXT/PLAIN, Size: 4993 bytes --]

On Fri, 29 Jan 2010, Mark Lodato wrote:

> On Fri, Jan 29, 2010 at 10:11 PM, Nicolas Pitre <nico@fluxnic.net> wrote:
> > On Fri, 29 Jan 2010, Mark Lodato wrote:
> >> On Fri, Jan 29, 2010 at 8:22 PM, Nicolas Pitre <nico@fluxnic.net> wrote:
> >> > On Fri, 29 Jan 2010, Mark Lodato wrote:
> >> >
> >> >> Still, I find it slightly confusing and unfriendly.  How about the following?
> >> >
> >> >> Checking out commit 'master^0'.
> >> >>
> >> >> Since this is not a local branch head, any commits you make will be lost
> >> >> when you check out another branch or commit.  (In git terminology, HEAD
> >> >> is detached.)  If you just wish to look at files without committing,
> >> >> this is fine.  If you wish to make commits and retain them, you may
> >> >> create a new branch by running:
> >> >>
> >> >>   git checkout -b <new_branch_name>
> >> >
> >> > This gives the impression that any commit you make on a detached HEAD
> >> > are going to be lost, unless you create a new branch first.
> >>
> >> What about "...you may want to create..."?  This does not imply that
> >> creating a new branch now is the *only* way, just the most likely.  If
> >> a user knows another way, that user probably does not need this
> >> warning in the first place.
> >
> > Still, you don't know what way the unsuspected user will take to get
> > there.
> 
> Sorry, I don't understand.  What do you mean by "take to get there"?
> Are you referring to how the user arrived in this detached HEAD state,

Yes.

> or what the user wishes to do next?  Either way, I still am not sure
> why this wording is no good.  Could please elaborate?

First, I'm afraid that "Checking out commit 'foobar'" might be confusing 
as this may happen through either a remote branch, a tag, or any random 
commit.  It seems to me that "Checking out 'v2.5'" is less confusing 
than "Checking out commit 'v2.5'".  But that's a minor detail and 
probably a personal preference.

>   Note: 'master^0' isn't a local branch head;
> 
> This isn't very friendly.  It sounds like an admonition.  Rather, I
> suggest that the first sentence be similar to, but distinct from,
> "Switched to branch foo," to inform the user that they did something
> different, which may or may not be intentional.

I consider that starting the explanation paragraph with " any commits 
you make will be lost" is even more unfriendly, and misleading.  That is 
sure to scare people needlessly.

>   You are in 'detached HEAD' state. You can look around, make experimental
>   changes and commit them, and you can discard any commits you make in this
>   state without impacting any branches by checking out another branch.
> 
> First, we shouldn't start off with the term "detached HEAD".  I used a
> parenthetical comment to mention it, in case the user wants to look it
> up or refer to this state.  Otherwise, the term conveys no meaning,
> unless one understand enough about git to not need this advice.

To the contrary: this "detached HEAD" is exactly what you need if you 
want to relate to any documentation or perform a search for more 
information.  Like it or not, this detached HEAD term is exactly what 
this Git concept is all about and how it is designated everywhere.  The 
sooner Git users see and learn about it the better.

> Second, this advice should be a warning that commits may be lost
> unless one knows what one is doing.  Saying "you can discard commits"
> makes it sound like a feature!  Sure, that may be so for advanced
> users, but for beginners (for whom this advice is intended), this is a
> common trap.  I tried to word the advice so that the users will know
> that they should not commit without first creating a branch (or
> knowing what they're doing), but that if they don't commit, there's no
> problem.  The wording quoted above does not convey this meaning to me.

I think your wording is just too far on the negative side, and makes Git 
look like an even more difficult tool than it actually is.  And you help 
no one by stating things that are not exactly true even if the truth 
implies that you need to know what you're doing.  The _whole_ and only 
point of a detached HEAD is actually to be able to make commits even 
without having to create a new branch first.

> This discussion brings up another good point: The main worry about a
> detached head is losing commits.  Back in 2008, it was suggested to
> have a warning when committing on a detached HEAD:
> 
> http://kerneltrap.org/mailarchive/git/2008/9/2/3169744
> 
> This was before the advice system, so folks complained about it
> getting in the way, and it was never implemented.  Since we now have a
> way to easily turn off the warning, perhaps we should bring this topic
> up again (probably as a separate thread.)

Possibly.  I don't like the message proposed in that patch though.  
Since the warning when actually detaching HEAD is about to become way 
more prominent, the per-commit warning doesn't have to be that noisy 
anymore.


Nicolas

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  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
  1 sibling, 1 reply; 111+ messages in thread
From: Nicolas Pitre @ 2010-01-30  4:03 UTC (permalink / raw)
  To: Ron Garret; +Cc: git

On Fri, 29 Jan 2010, Ron Garret wrote:

> In article <7vbpgc8fhb.fsf@alter.siamese.dyndns.org>,
>  Junio C Hamano <gitster@pobox.com> wrote:
> 
> > "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.
> 
> Ah, then you're right.  I really don't get it yet.

Have a look at http://eagain.net/articles/git-for-computer-scientists/

That's one of the clearest explanation of the Git branching model I've 
seen.

> > 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.
> 
> OK.  The docs do not make that clear at all.  In fact, the following 
> statement, copied straight from the manual, flatly contradicts what you 
> just said:
> 
> "The special symbol "HEAD" can always be used to refer to the current 
> branch."
> 
> Always.  Except when it can't.

There is no contradiction.  The "detached HEAD" corresponds to HEAD 
pointing at no branch in particular.  There is just no current branch in 
that case.

> Soooo.....
> 
> Sometimes HEAD can refer to a branch head which is a pointer to a 
> commit, and sometimes HEAD can refer to a commit directly without 
> indirecting through a branch head (lower case), in which case it is 
> detached.  Is that right?

Exact.

> If that's true, then I'm back to wondering what good is a detached head.  
> Why would you ever want one?  What can you do with a detached head that 
> you could not do just as easily without one?

By definition, remote tracking branches are "read-only" because we want 
those branch heads to reflect what the remote repository they're 
tracking has.  In other words, you're not supposed to add commits to a 
remote branch or it would move that branch to the new commit which is no 
longer a representation of the corresponding remote repository.  In 
order to actually add commits on top of a remote branch, you first have 
to make a local branch being a copy of the remote branch of interest 
(which in practice means only making the local branch point at the same 
commit node as the remote branch) and then any commit will advance that 
local branch and leave the remote branch behind.

But what if you just want to check out the content corresponding to that 
remote branch without adding any new commits?  What if you wish to do 
the same with a tag instead of a branch (a tag being immutable)?

If you could have HEAD pointing to a tag or a remote branch then many 
operations such as 'git commit' would need to be blocked in order to 
preserve the read-only nature of such references.

The detached HEAD solves the issue really neatly in those cases.  
Instead of having HEAD pointing to a remote branch record, the detached 
HEAD points directly at the provided commit from the remote branch head 
or tag, and any commit operation will simply update that direct 
reference alone, creating a fork point in the history graph.

If you wish to preserve this branch in the graph sense then you can 
create a new branch head with the current HEAD position.  Or if you 
don't care about those commits you made on the detached HEAD, then 
simply moving HEAD to anything else with another checkout command will 
drop and forget about that string of commits you created.

So a detached HEAD is useful for checking out a read-only branch or tag 
without having to forbid a bunch of operations or needing for you to 
create a dummy temporary local branch just for the purpose of such a 
checkout.  Many operations with intermediate states such as 'git rebase' 
or 'git bisect' can be implemented without polluting the branch 
namespace, etc.


Nicolas

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-30  3:11                                     ` Nicolas Pitre
@ 2010-01-30  3:59                                       ` Mark Lodato
  2010-01-30  4:39                                         ` Nicolas Pitre
  0 siblings, 1 reply; 111+ messages in thread
From: Mark Lodato @ 2010-01-30  3:59 UTC (permalink / raw)
  To: Nicolas Pitre
  Cc: Junio C Hamano, Sverre Rabbelier, Git List, Ron1, Jacob Helwig

On Fri, Jan 29, 2010 at 10:11 PM, Nicolas Pitre <nico@fluxnic.net> wrote:
> On Fri, 29 Jan 2010, Mark Lodato wrote:
>> On Fri, Jan 29, 2010 at 8:22 PM, Nicolas Pitre <nico@fluxnic.net> wrote:
>> > On Fri, 29 Jan 2010, Mark Lodato wrote:
>> >
>> >> Still, I find it slightly confusing and unfriendly.  How about the following?
>> >
>> >> Checking out commit 'master^0'.
>> >>
>> >> Since this is not a local branch head, any commits you make will be lost
>> >> when you check out another branch or commit.  (In git terminology, HEAD
>> >> is detached.)  If you just wish to look at files without committing,
>> >> this is fine.  If you wish to make commits and retain them, you may
>> >> create a new branch by running:
>> >>
>> >>   git checkout -b <new_branch_name>
>> >
>> > This gives the impression that any commit you make on a detached HEAD
>> > are going to be lost, unless you create a new branch first.
>>
>> What about "...you may want to create..."?  This does not imply that
>> creating a new branch now is the *only* way, just the most likely.  If
>> a user knows another way, that user probably does not need this
>> warning in the first place.
>
> Still, you don't know what way the unsuspected user will take to get
> there.

Sorry, I don't understand.  What do you mean by "take to get there"?
Are you referring to how the user arrived in this detached HEAD state,
or what the user wishes to do next?  Either way, I still am not sure
why this wording is no good.  Could please elaborate?

> Do you still have a problem with the latest version of the text from
> Junio?  Looks like you based your modification on an earlier version.

Yes, I do.  I thought his earlier version was more clear.  Particularly:

  Note: 'master^0' isn't a local branch head;

This isn't very friendly.  It sounds like an admonition.  Rather, I
suggest that the first sentence be similar to, but distinct from,
"Switched to branch foo," to inform the user that they did something
different, which may or may not be intentional.

  You are in 'detached HEAD' state. You can look around, make experimental
  changes and commit them, and you can discard any commits you make in this
  state without impacting any branches by checking out another branch.

First, we shouldn't start off with the term "detached HEAD".  I used a
parenthetical comment to mention it, in case the user wants to look it
up or refer to this state.  Otherwise, the term conveys no meaning,
unless one understand enough about git to not need this advice.

Second, this advice should be a warning that commits may be lost
unless one knows what one is doing.  Saying "you can discard commits"
makes it sound like a feature!  Sure, that may be so for advanced
users, but for beginners (for whom this advice is intended), this is a
common trap.  I tried to word the advice so that the users will know
that they should not commit without first creating a branch (or
knowing what they're doing), but that if they don't commit, there's no
problem.  The wording quoted above does not convey this meaning to me.

  If you want to create a new branch to retain commits you create, you may
  do so (now or later) by using -b with the checkout command again. Example:

    git checkout -b <new_branch_name>

I basically retained this, with rewording.


This discussion brings up another good point: The main worry about a
detached head is losing commits.  Back in 2008, it was suggested to
have a warning when committing on a detached HEAD:

http://kerneltrap.org/mailarchive/git/2008/9/2/3169744

This was before the advice system, so folks complained about it
getting in the way, and it was never implemented.  Since we now have a
way to easily turn off the warning, perhaps we should bring this topic
up again (probably as a separate thread.)

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  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:09                                         ` Junio C Hamano
  2010-01-30  4:52                                       ` Jay Soffian
  1 sibling, 2 replies; 111+ messages in thread
From: Ron Garret @ 2010-01-30  3:26 UTC (permalink / raw)
  To: git

In article <7vbpgc8fhb.fsf@alter.siamese.dyndns.org>,
 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.

That could well be, but it's not for lack of trying :-)

> A git branch is _not_ a line (nor multiple
> lines) of development.  It is merely a _point_ in the history.

By "middle of a branch" I simply meant "a commit that already has one or 
more descendants" (or, to be even more precise, a commit that has one or 
more commits that reference that commit as one of their predecessors).  
I do understand that histories aren't linear.

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

Ah, then you're right.  I really don't get it yet.

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

OK.  The docs do not make that clear at all.  In fact, the following 
statement, copied straight from the manual, flatly contradicts what you 
just said:

"The special symbol "HEAD" can always be used to refer to the current 
branch."

Always.  Except when it can't.

Soooo.....

Sometimes HEAD can refer to a branch head which is a pointer to a 
commit, and sometimes HEAD can refer to a commit directly without 
indirecting through a branch head (lower case), in which case it is 
detached.  Is that right?

If that's true, then I'm back to wondering what good is a detached head.  
Why would you ever want one?  What can you do with a detached head that 
you could not do just as easily without one?

rg

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-30  2:13         ` Johannes Schindelin
@ 2010-01-30  3:15           ` Nicolas Pitre
  0 siblings, 0 replies; 111+ messages in thread
From: Nicolas Pitre @ 2010-01-30  3:15 UTC (permalink / raw)
  To: Johannes Schindelin
  Cc: Junio C Hamano, Sverre Rabbelier, Git List, Ron1, Jacob Helwig

On Sat, 30 Jan 2010, Johannes Schindelin wrote:

> Hi,
> 
> On Fri, 29 Jan 2010, Nicolas Pitre wrote:
> 
> > With all due respects, I don't share Dscho's sentiment about Git's 
> > alleged non user-friendliness.
> 
> Of course you don't.  You are a Git oldtimer.  Probably you do not even 
> have much exposure to complete programming newbies.

Welllll... That depends.

If you mean people who, despite a CS degree, are still unable to figure 
out if some loop exit condition should be > or >= except by testing the 
compiled code and see if a crash occurs, then yes I do feel the pain of 
being exposed to such people way too often for my taste.  And frankly I 
just don't care if those people can't grok the Git UI.

Git is meant to be a tool for people performing a minimum of development 
tasks.  If those people can't grasp the Git UI and concepts with little 
effort then they're either 1) uninterested or 2) incompetent.  For the 
uninterested people there are GUIs out there.  And don't get me started 
on the incompetent ones.

And for the rest of the world, such as my boss, there is gitweb.

> Well, guess what.  I have.  And guess what even more: they are the 
> majority, not you and me.

Did you ever got them to use P4?  I'm convinced that learning how to use 
P4 for a Git user is way more painful than a P4 user to learn Git.  
Similarly for Arch or many other alternatives.

HG looks easier?  Sure.  But it isn't exactly as flexible and powerful 
as Git is though.  You prefer a less powerful but simpler tool? OK just 
go with HG then -- I have no problem with that.  Even SVN might be just 
what you need.  But if you prefer the power of Git then there is a price 
to pay for it.  Making Git simpler would inevitably reduces its power.

I hope newbies won't stay newbies all their life.  If the majority of 
all the people are newbies then no need to wonder why there is so much 
crap being produced by the computing industry then.  Learning isn't only 
a nasty thing that they force you to do at school and which you get over 
with once you escape from there.

Incidentally we've been getting more positive feedback than negative 
ones about Git from newbies on this list lately.  That might be because 
our UI, although still not perfect, improved quite a bit, and most 
probably because the documentation surrounding Git has improved 
tremendously too.


Nicolas

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-30  2:40                                   ` Mark Lodato
@ 2010-01-30  3:11                                     ` Nicolas Pitre
  2010-01-30  3:59                                       ` Mark Lodato
  0 siblings, 1 reply; 111+ messages in thread
From: Nicolas Pitre @ 2010-01-30  3:11 UTC (permalink / raw)
  To: Mark Lodato
  Cc: Junio C Hamano, Sverre Rabbelier, Git List, Ron1, Jacob Helwig

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1407 bytes --]

On Fri, 29 Jan 2010, Mark Lodato wrote:

> On Fri, Jan 29, 2010 at 8:22 PM, Nicolas Pitre <nico@fluxnic.net> wrote:
> > On Fri, 29 Jan 2010, Mark Lodato wrote:
> >
> >> Still, I find it slightly confusing and unfriendly.  How about the following?
> >
> > It is slightly inaccurate.
> 
> Is the following the only inaccuracy?  Do you have any other feedback?
> 
> >> Checking out commit 'master^0'.
> >>
> >> Since this is not a local branch head, any commits you make will be lost
> >> when you check out another branch or commit.  (In git terminology, HEAD
> >> is detached.)  If you just wish to look at files without committing,
> >> this is fine.  If you wish to make commits and retain them, you may
> >> create a new branch by running:
> >>
> >>   git checkout -b <new_branch_name>
> >
> > This gives the impression that any commit you make on a detached HEAD
> > are going to be lost, unless you create a new branch first.
> 
> What about "...you may want to create..."?  This does not imply that
> creating a new branch now is the *only* way, just the most likely.  If
> a user knows another way, that user probably does not need this
> warning in the first place.

Still, you don't know what way the unsuspected user will take to get 
there.

Do you still have a problem with the latest version of the text from 
Junio?  Looks like you based your modification on an earlier version.


Nicolas

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-30  0:33           ` Michael Witten
@ 2010-01-30  3:06             ` Junio C Hamano
  2010-01-30  6:16               ` Ron Garret
  0 siblings, 1 reply; 111+ messages in thread
From: Junio C Hamano @ 2010-01-30  3:06 UTC (permalink / raw)
  To: Michael Witten; +Cc: Ron Garret, git

Michael Witten <mfwitten@gmail.com> writes:

> Isn't the difference between 'checkout' and 'reset' almost essentially
> a matter of whether the branch reference (HEAD), index, and tree are
> modified? Couldn't these commands be merged into one command or make
> use of one command?

I don't think that reduces any confusion.

By exposing orthogonal options like --index, --head, etc., you are opening
yourself to nonsensical combinations that were never possible with the
existing command set, and I suspect it would make it even more confusing,
not less.

What does "git update --detach $commit" _really_ mean, for example?

You can of course say "it detaches the HEAD at $commit, but otherwise does
not change anything else", but such a mechanical description does not give
an answer that helps end users.  "What would I do after doing that?" and
"What would I use this for?" are the questions they need an answer to.

What matters is "after doing this, next commit will record _this_, which
is often what users want in _that_ situation, and that is why this
combination of options makes sense."  Do all (or majority) of option
combinations to your "update" think have _meaning_ in that sense?  I don't
think so.

Flexibility and orthogonality is often good, but uncontrolled flexibility
is not.  And I suspect your "git update" is just an uncontrolled mess that
would not help users [*1*].

[Footnote]

*1* It is a different matter to have something like that as an ingredient
to build Porcelain scripts out of.  Porcelain writers may appreciate the
flexibility and they will choose to use only combinations that make sense
for the situation they are trying to deal with.

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  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:52                                       ` Jay Soffian
  0 siblings, 2 replies; 111+ messages in thread
From: Junio C Hamano @ 2010-01-30  2:59 UTC (permalink / raw)
  To: Ron Garret; +Cc: git

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.

> 2.  There are a lot of things in the documentation that turn out, now 
> that I understand what is going on, to be subtly misleading.  For 
> example, "A single git repository can track development on multiple 
> branches. It does this by keeping a list of heads which reference the 
> latest commit on each branch."  That last part is only true if the heads 
> are not "detached".

This is from old terminology.  We used to use "head" (lowercase) and
"branches" pretty much interchangeably and the quoted description is from
the era _before_ detached HEAD was invented, as a way to quickly get a
temporary state where you can browse around freely and without having to
worry about having to clean up afterwards even if you made commits in that
state by simply going back to an attached state.

So do a "s/a list of heads/a list of branch pointers/" replacement and you
will be fine.

> Another example: "The HEAD then refers to the SHA-1 of the commit 
> instead of to a branch, and git branch shows that you are no longer on a 
> branch:"  But you *are* on a branch, you just aren't at the head of the 
> branch.

No, you are _literally_ not on _any_ branch at that point.

Making a commit from that state does not advance _any_ branch and doing
"reset --hard $commit" from that state does not affect _any_ branch.

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-30  1:22                                 ` Nicolas Pitre
  2010-01-30  2:38                                   ` Ron Garret
@ 2010-01-30  2:40                                   ` Mark Lodato
  2010-01-30  3:11                                     ` Nicolas Pitre
  1 sibling, 1 reply; 111+ messages in thread
From: Mark Lodato @ 2010-01-30  2:40 UTC (permalink / raw)
  To: Nicolas Pitre
  Cc: Junio C Hamano, Sverre Rabbelier, Git List, Ron1, Jacob Helwig

On Fri, Jan 29, 2010 at 8:22 PM, Nicolas Pitre <nico@fluxnic.net> wrote:
> On Fri, 29 Jan 2010, Mark Lodato wrote:
>
>> Still, I find it slightly confusing and unfriendly.  How about the following?
>
> It is slightly inaccurate.

Is the following the only inaccuracy?  Do you have any other feedback?

>> Checking out commit 'master^0'.
>>
>> Since this is not a local branch head, any commits you make will be lost
>> when you check out another branch or commit.  (In git terminology, HEAD
>> is detached.)  If you just wish to look at files without committing,
>> this is fine.  If you wish to make commits and retain them, you may
>> create a new branch by running:
>>
>>   git checkout -b <new_branch_name>
>
> This gives the impression that any commit you make on a detached HEAD
> are going to be lost, unless you create a new branch first.

What about "...you may want to create..."?  This does not imply that
creating a new branch now is the *only* way, just the most likely.  If
a user knows another way, that user probably does not need this
warning in the first place.

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  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  2:40                                   ` Mark Lodato
  1 sibling, 1 reply; 111+ messages in thread
From: Ron Garret @ 2010-01-30  2:38 UTC (permalink / raw)
  To: git

In article <alpine.LFD.2.00.1001292013150.1681@xanadu.home>,
 Nicolas Pitre <nico@fluxnic.net> wrote:

> On Fri, 29 Jan 2010, Mark Lodato wrote:
> 
> > Still, I find it slightly confusing and unfriendly.  How about the 
> > following?
> 
> It is slightly inaccurate.
> 
> > Checking out commit 'master^0'.
> > 
> > Since this is not a local branch head, any commits you make will be lost
> > when you check out another branch or commit.  (In git terminology, HEAD
> > is detached.)  If you just wish to look at files without committing,
> > this is fine.  If you wish to make commits and retain them, you may
> > create a new branch by running:
> > 
> >   git checkout -b <new_branch_name>
> 
> This gives the impression that any commit you make on a detached HEAD 
> are going to be lost, unless you create a new branch first.
> 
> And again, it is a good thing to have "detached HEAD" in there so to 
> relate to existing documentation easily.
> 
> > I think the above wording is fine for both commits (e.g. master^0) and
> > remote branches (e.g. origin/pu).  With other wording, we may wish to
> > have two slightly different messages depending on what the user typed.
> 
> You could have tags too.  So instead of trying to be too smart, it is 
> best to simply display the provided name without qualifier.
> 
> > Also, I am not a big fan of "local branch head".  How about "not the
> > name of a local branch"?  I'm not sure...
> 
> The confusion that started this thread was about "master^" which might 
> be interpreted as the name of a local branch except for the fact that we 
> want one commit back.  So using "local commit head" is more precise.

Since it is my confusion that started this thread (and I suppose is in 
part responsible for continuing it) I should be clear that master^ was 
just an example.  My first attempt to roll back to an earlier version 
was actually "git checkout HEAD^".  That produced the same result, since 
HEAD was pointing to master at the time.  But one of the things I 
realized was that HEAD was a variable, and so I chose to frame my 
example in terms of master instead of HEAD in order to eliminate 
ambiguity.

FWIW, here are some observations based on my current understanding:

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.

2.  There are a lot of things in the documentation that turn out, now 
that I understand what is going on, to be subtly misleading.  For 
example, "A single git repository can track development on multiple 
branches. It does this by keeping a list of heads which reference the 
latest commit on each branch."  That last part is only true if the heads 
are not "detached".

I do not yet understand enough about git to know if this is a reasonable 
suggestion, but one possibility is to separate the notion of a head from 
the notion of a pointer to a commit.  A head would be a pointer to a 
commit that can only point to a commit with no descendants, whereas a 
pointer could point anywhere.  What is now called HEAD would be a 
pointer, not a head under this ontology.

Another example: "The HEAD then refers to the SHA-1 of the commit 
instead of to a branch, and git branch shows that you are no longer on a 
branch:"  But you *are* on a branch, you just aren't at the head of the 
branch.  In fact, by the definition of branch the whole concept of "not 
being on a branch" is non-sensical.  (Isn't that part of the whole point 
of git?  That everything is a branch?)

3.  These observations suggest ways in which the situation could be 
improved.

First, I think Michael Witten is on the right track with his proposal 
for a redesign of git-checkout and the new git-update command (though I 
have not yet had time to think deeply about the details).  There are 
only a small number of things that are actually going on under the hood, 
and the closer the map between the command set and those primitive 
operations can be made the better.

Second, the real problem underlying the original warning that started 
all this is that if you do a commit from a "detached head" then you have 
effectively created a branch whether you meant to or not.  This suggests 
a very straightforward warning:

"WARNING: Your HEAD is now pointing to a commit that has descendants.
If you do a commit from here, you will be creating a branch.  If this
is not what you intend, read the documentation and achieve clarity before
proceeding.  If you just want to bail out of this situation without
doing your homework, do a 'git checkout master' or something like that."

Or something like that :-)

rg

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-29 21:20       ` Nicolas Pitre
  2010-01-29 21:21         ` Sverre Rabbelier
  2010-01-29 21:49         ` Junio C Hamano
@ 2010-01-30  2:13         ` Johannes Schindelin
  2010-01-30  3:15           ` Nicolas Pitre
  2 siblings, 1 reply; 111+ messages in thread
From: Johannes Schindelin @ 2010-01-30  2:13 UTC (permalink / raw)
  To: Nicolas Pitre
  Cc: Junio C Hamano, Sverre Rabbelier, Git List, Ron1, Jacob Helwig

Hi,

On Fri, 29 Jan 2010, Nicolas Pitre wrote:

> With all due respects, I don't share Dscho's sentiment about Git's 
> alleged non user-friendliness.

Of course you don't.  You are a Git oldtimer.  Probably you do not even 
have much exposure to complete programming newbies.

Well, guess what.  I have.  And guess what even more: they are the 
majority, not you and me.

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  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:40                                   ` Mark Lodato
  0 siblings, 2 replies; 111+ messages in thread
From: Nicolas Pitre @ 2010-01-30  1:22 UTC (permalink / raw)
  To: Mark Lodato
  Cc: Junio C Hamano, Sverre Rabbelier, Git List, Ron1, Jacob Helwig

On Fri, 29 Jan 2010, Mark Lodato wrote:

> Still, I find it slightly confusing and unfriendly.  How about the following?

It is slightly inaccurate.

> Checking out commit 'master^0'.
> 
> Since this is not a local branch head, any commits you make will be lost
> when you check out another branch or commit.  (In git terminology, HEAD
> is detached.)  If you just wish to look at files without committing,
> this is fine.  If you wish to make commits and retain them, you may
> create a new branch by running:
> 
>   git checkout -b <new_branch_name>

This gives the impression that any commit you make on a detached HEAD 
are going to be lost, unless you create a new branch first.

And again, it is a good thing to have "detached HEAD" in there so to 
relate to existing documentation easily.

> I think the above wording is fine for both commits (e.g. master^0) and
> remote branches (e.g. origin/pu).  With other wording, we may wish to
> have two slightly different messages depending on what the user typed.

You could have tags too.  So instead of trying to be too smart, it is 
best to simply display the provided name without qualifier.

> Also, I am not a big fan of "local branch head".  How about "not the
> name of a local branch"?  I'm not sure...

The confusion that started this thread was about "master^" which might 
be interpreted as the name of a local branch except for the fact that we 
want one commit back.  So using "local commit head" is more precise.


Nicolas

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-30  0:29                             ` Junio C Hamano
                                                 ` (2 preceding siblings ...)
  2010-01-30  0:39                               ` Nicolas Pitre
@ 2010-01-30  1:01                               ` Mark Lodato
  2010-01-30  1:22                                 ` Nicolas Pitre
  3 siblings, 1 reply; 111+ messages in thread
From: Mark Lodato @ 2010-01-30  1:01 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Sverre Rabbelier, Nicolas Pitre, Git List, Ron1, Jacob Helwig

On Fri, Jan 29, 2010 at 7:29 PM, Junio C Hamano <gitster@pobox.com> wrote:
> How about this?
>
> -- >8 -- not a patch -- >8 --
> Note: 'master^0' isn't a local branch head;
>
> You are in 'detached HEAD' state. You can look around, make experimental
> changes and commit them, and you can discard any commits you make in this
> state without impacting any branches by checking out another branch.
>
> If you want to create a new branch to retain commits you create, you may
> do so (now or later) by using -b with the checkout command again. Example:
>
>  git checkout -b <new_branch_name>
>
> HEAD is now at a9d7c95... Merge branch 'maint'
> -- 8< -- not a patch -- 8< --

First off, I would like to voice support for such a warning.  This is
so much more clear than the current message.

Still, I find it slightly confusing and unfriendly.  How about the following?

-- >8 -- not a patch -- >8 --
Checking out commit 'master^0'.

Since this is not a local branch head, any commits you make will be lost
when you check out another branch or commit.  (In git terminology, HEAD
is detached.)  If you just wish to look at files without committing,
this is fine.  If you wish to make commits and retain them, you may
create a new branch by running:

  git checkout -b <new_branch_name>

HEAD is now at a9d7c95... Merge branch 'maint'
 - 8< -- not a patch -- 8< --

I think the above wording is fine for both commits (e.g. master^0) and
remote branches (e.g. origin/pu).  With other wording, we may wish to
have two slightly different messages depending on what the user typed.

Also, I am not a big fan of "local branch head".  How about "not the
name of a local branch"?  I'm not sure...

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  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
  3 siblings, 0 replies; 111+ messages in thread
From: Nicolas Pitre @ 2010-01-30  0:39 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Sverre Rabbelier, Git List, Ron1, Jacob Helwig

On Fri, 29 Jan 2010, Junio C Hamano wrote:

> How about this?
> 
> -- >8 -- not a patch -- >8 --
> Note: 'master^0' isn't a local branch head;
> 
> You are in 'detached HEAD' state. You can look around, make experimental
> changes and commit them, and you can discard any commits you make in this
> state without impacting any branches by checking out another branch.

s/checking out another branch/performing another checkout/

> If you want to create a new branch to retain commits you create, you may
> do so (now or later) by using -b with the checkout command again. Example:
> 
>   git checkout -b <new_branch_name>
> 
> HEAD is now at a9d7c95... Merge branch 'maint'
> -- 8< -- not a patch -- 8< --
> 
> Again, everything except for the last line would disappear by setting the
> advice.detachedHEAD configuration to false.

Looks fine to me.


Nicolas

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  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
  3 siblings, 0 replies; 111+ messages in thread
From: Michael Witten @ 2010-01-30  0:38 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Sverre Rabbelier, Nicolas Pitre, Git List, Ron1, Jacob Helwig

On Fri, Jan 29, 2010 at 6:29 PM, Junio C Hamano <gitster@pobox.com> wrote:
> The "state" was not about the work-tree state, but about the
> "detached HEAD" state, which I didn't make it clear.

Maybe we should just introduce people to a more explicit command like
the hypothetical 'update' command I sketch here:

    http://marc.info/?l=git&m=126481166426896&w=2

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-30  0:29                             ` Junio C Hamano
@ 2010-01-30  0:35                               ` Sverre Rabbelier
  2010-01-30  0:38                               ` Michael Witten
                                                 ` (2 subsequent siblings)
  3 siblings, 0 replies; 111+ messages in thread
From: Sverre Rabbelier @ 2010-01-30  0:35 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Nicolas Pitre, Git List, Ron1, Jacob Helwig

Heya,

On Sat, Jan 30, 2010 at 01:29, Junio C Hamano <gitster@pobox.com> wrote:
> True.  And I am a moron.

Not at all, you worded it very nicely I think.

> How about this?

Definitely a major improvement, nice.

-- 
Cheers,

Sverre Rabbelier

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-29 22:12         ` Ron Garret
@ 2010-01-30  0:33           ` Michael Witten
  2010-01-30  3:06             ` Junio C Hamano
  0 siblings, 1 reply; 111+ messages in thread
From: Michael Witten @ 2010-01-30  0:33 UTC (permalink / raw)
  To: Ron Garret; +Cc: git, Junio C Hamano

On Fri, Jan 29, 2010 at 4:12 PM, Ron Garret <ron1@flownet.com> wrote:
> In article <7vmxzwh906.fsf@alter.siamese.dyndns.org>,
>  Junio C Hamano <gitster@pobox.com> wrote:
>
>> Sverre Rabbelier <srabbelier@gmail.com> writes:
>>
>> > On Fri, Jan 29, 2010 at 22:24, Ron Garret <ron1@flownet.com> wrote:
>> >> Yes, I read that.  But what I'm trying to do is not just *look* at the
>> >> history, I want to restore my working tree to a previous version.  The
>> >> "Exploring History" section of the docs doesn't say how to do that.
>> >
>> > Do you want to restore your working tree only, or also throw away the
>> > history? If the former, you could look at 'git revert',...
>>
>> I think he wanted to check paths out of a commit and the set of paths
>> happened to be "everything".
>>
>> IOW, "checkout $commit ."
>
> Yes!!!  That's it exactly!

However, that updates the index and doesn't delete files that didn't
exist in $commit, and you said earlier that you don't want to update
the index (though perhaps you didn't really know what you wanted
there).

My idea:

Isn't the difference between 'checkout' and 'reset' almost essentially
a matter of whether the branch reference (HEAD), index, and tree are
modified? Couldn't these commands be merged into one command or make
use of one command?

Rather than relying on flags like --hard, --soft, and --mixed, why not
*also* provide flags for specifying at a finer granularity what is
desired for the index, working tree, and HEAD.

Then:
    git checkout $commit
does a lot of its work through something like:
    git update --index --tree --detach $commit

Also:
    git checkout $commit $f
translates:
    git update --index --tree --keep-tracked-files $commit $f

Also:
    git reset [--mixed] $commit
translates:
    git update --index --head $commit

Also:
    git reset --soft $commit
translates:
    git update --head $commit

Also:
    git reset --hard $commit
translates:
    git update --index --tree --head $commit

And so on.

In fact, with --no-* flags, you could modify 'reset' and 'checkout'
commands from their defaults. So, to update all of the paths
(including deleting tracked files not in $commit), but keep the index
untouched, we have:

    git checkout --no-update-index --no-update-keep-files $commit .

Of course, you might as well just use the hypothetical 'update'
command directly:

    git update --tree $commit .

Sincerely,
Michael Witten

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-30  0:18                           ` Sverre Rabbelier
@ 2010-01-30  0:29                             ` Junio C Hamano
  2010-01-30  0:35                               ` Sverre Rabbelier
                                                 ` (3 more replies)
  0 siblings, 4 replies; 111+ messages in thread
From: Junio C Hamano @ 2010-01-30  0:29 UTC (permalink / raw)
  To: Sverre Rabbelier; +Cc: Nicolas Pitre, Git List, Ron1, Jacob Helwig

Sverre Rabbelier <srabbelier@gmail.com> writes:

> I think the "this state" needs to be changed, it currently suggests
> what you mention earlier in you reply, that it's about the current
> state, even if you make commits on top of that. Maybe something in the
> spirit of "If you want to create a new branch from ?? where you are at
> the moment you follow these instructions ??".

True.  And I am a moron.

The "state" was not about the work-tree state, but about the
"detached HEAD" state, which I didn't make it clear.

I also didn't address "scariness" point from Nico.  And scariness can be
removed by describing things in a positive way.

How about this?

-- >8 -- not a patch -- >8 --
Note: 'master^0' isn't a local branch head;

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by checking out another branch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new_branch_name>

HEAD is now at a9d7c95... Merge branch 'maint'
-- 8< -- not a patch -- 8< --

Again, everything except for the last line would disappear by setting the
advice.detachedHEAD configuration to false.

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-30  0:14           ` Ron Garret
@ 2010-01-30  0:18             ` Ron Garret
  2010-01-30 19:02               ` Junio C Hamano
  0 siblings, 1 reply; 111+ messages in thread
From: Ron Garret @ 2010-01-30  0:18 UTC (permalink / raw)
  To: git

In article <ron1-A99355.16145629012010@news.gmane.org>,
 Ron Garret <ron1@flownet.com> wrote:

> In article <bd7fb2a884e55e176eea3002fd0c68dd@212.159.54.234>,
>  Julian Phillips <julian@quantumfyre.co.uk> wrote:
> 
> > On Fri, 29 Jan 2010 14:47:49 -0800, Ron Garret <ron1@flownet.com> wrote:
> > > My actual use case is very complicated, but here's a simplified version:
> > > 
> > > Suppose I'm using git as a back-end for a wiki.  I want to look at the 
> > > state of the entire wiki as it was in some point in the past, and I also
> > 
> > > want to be able to look at the diffs between individual pages as they 
> > > were then and as they are now.  The most straightforward way I can think
> > 
> > > of to do that is to simply copy an old commit into my working tree 
> > > without changing anything else.  Then I can look at the old version by 
> > > simply looking at the files, and I can get the diffs by simply doing a 
> > > git diff.
> > > 
> > > If I do a git reset --hard then I get the old version, but I lose my 
> > > HEAD pointer so that git diff doesn't give me what I want any more.
> > > 
> > > BTW, it turns out that git checkout [commit] . doesn't do the right 
> > > thing either.  Apparently, it still updates my index, so git diff still 
> > > doesn't do the right thing.
> > 
> > If I understand what you want correctly, then:
> > 
> > git diff --cached -R [path]
> > 
> > should be the appropriate command after the "git checkout <commit> .".
> 
> Yep, that works.  Alternatively, is there a way to clear the index?  
> Seems like that would be better.

Well, whaddyaknow: git reset without any arguments has a use after all 
:-)

rg

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-30  0:14                         ` Junio C Hamano
@ 2010-01-30  0:18                           ` Sverre Rabbelier
  2010-01-30  0:29                             ` Junio C Hamano
  0 siblings, 1 reply; 111+ messages in thread
From: Sverre Rabbelier @ 2010-01-30  0:18 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Nicolas Pitre, Git List, Ron1, Jacob Helwig

Heya,

On Sat, Jan 30, 2010 at 01:14, Junio C Hamano <gitster@pobox.com> wrote:
> +"If you want to create a new branch from this state, you may do so\n"
> +"(now or later) by using -b with the checkout command again.

I think the "this state" needs to be changed, it currently suggests
what you mention earlier in you reply, that it's about the current
state, even if you make commits on top of that. Maybe something in the
spirit of "If you want to create a new branch from ?? where you are at
the moment you follow these instructions ??".

-- 
Cheers,

Sverre Rabbelier

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-29 23:43                       ` Nicolas Pitre
@ 2010-01-30  0:14                         ` Junio C Hamano
  2010-01-30  0:18                           ` Sverre Rabbelier
  0 siblings, 1 reply; 111+ messages in thread
From: Junio C Hamano @ 2010-01-30  0:14 UTC (permalink / raw)
  To: Nicolas Pitre; +Cc: Sverre Rabbelier, Git List, Ron1, Jacob Helwig

Nicolas Pitre <nico@fluxnic.net> writes:

> To the contrary, I think it is about time we use proper Git jargon.  
> Otherwise how can we expect people to relate to the documentation where 
> that jargon is indeed used?  Even on this very mailing list we refer to 
> that state as a "detached HEAD".  And Google gives precisely the right 
> info with "detached HEAD" while any other verbiage might not.
>
> And just saying that "you're not on any branch anymore" is still leaving 
> the user wondering why.  At least with the "isn't a local branch head" 
> the user has 2 clues: it has to be a _local_ branch and a branch _head_ 
> not to create a detached HEAD.  So I still prefer the above rewording.

I can buy that argument, except for three minor points:

 - I think we also should give information necessary to judge if the user
   wants to stay in the detached HEAD state.  IOW, "Why am I getting an
   insn to create a new branch?  What is wrong with this detached HEAD
   state?  Why would I want a local branch?" are still not explained with
   the updated message.

 - Do we "create" a detached HEAD, or are we just "detaching HEAD"?

 - Running "checkout -b" now will create a new branch from that checkout,
   but doing so _later_ won't necessarily do so from that _checkout_.

So how about doing this (changes to advice.[ch] are omitted)?

diff --git a/builtin-checkout.c b/builtin-checkout.c
index 5277817..41fc00a 100644
--- a/builtin-checkout.c
+++ b/builtin-checkout.c
@@ -522,8 +522,16 @@ static void update_refs_for_switch(struct checkout_opts *opts,
 		update_ref(msg.buf, "HEAD", new->commit->object.sha1, NULL,
 			   REF_NODEREF, DIE_ON_ERR);
 		if (!opts->quiet) {
-			if (old->path)
-				fprintf(stderr, "Note: moving to '%s' which isn't a local branch\nIf you want to create a new branch from this checkout, you may do so\n(now or later) by using -b with the checkout command again. Example:\n  git checkout -b <new_branch_name>\n", new->name);
+			if (old->path && advice_detached_head)
+				fprintf(stderr,
+"Note: '%s' isn't a local branch head.\n\n"
+"HEAD is detached at that commit. You can look around, even make changes\n"
+"and record them in new commits, but any new commit you make from now on\n"
+"will be lost when you check out another branch.\n"
+"If you want to create a new branch from this state, you may do so\n"
+"(now or later) by using -b with the checkout command again. Example:\n"
+"  git checkout -b <new_branch_name>\n\n",
+					new->name);
 			describe_detached_head("HEAD is now at", new->commit);
 		}
 	}

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-29 23:28         ` Julian Phillips
@ 2010-01-30  0:14           ` Ron Garret
  2010-01-30  0:18             ` Ron Garret
  0 siblings, 1 reply; 111+ messages in thread
From: Ron Garret @ 2010-01-30  0:14 UTC (permalink / raw)
  To: git

In article <bd7fb2a884e55e176eea3002fd0c68dd@212.159.54.234>,
 Julian Phillips <julian@quantumfyre.co.uk> wrote:

> On Fri, 29 Jan 2010 14:47:49 -0800, Ron Garret <ron1@flownet.com> wrote:
> > My actual use case is very complicated, but here's a simplified version:
> > 
> > Suppose I'm using git as a back-end for a wiki.  I want to look at the 
> > state of the entire wiki as it was in some point in the past, and I also
> 
> > want to be able to look at the diffs between individual pages as they 
> > were then and as they are now.  The most straightforward way I can think
> 
> > of to do that is to simply copy an old commit into my working tree 
> > without changing anything else.  Then I can look at the old version by 
> > simply looking at the files, and I can get the diffs by simply doing a 
> > git diff.
> > 
> > If I do a git reset --hard then I get the old version, but I lose my 
> > HEAD pointer so that git diff doesn't give me what I want any more.
> > 
> > BTW, it turns out that git checkout [commit] . doesn't do the right 
> > thing either.  Apparently, it still updates my index, so git diff still 
> > doesn't do the right thing.
> 
> If I understand what you want correctly, then:
> 
> git diff --cached -R [path]
> 
> should be the appropriate command after the "git checkout <commit> .".

Yep, that works.  Alternatively, is there a way to clear the index?  
Seems like that would be better.

rg

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  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
  1 sibling, 1 reply; 111+ messages in thread
From: Nicolas Pitre @ 2010-01-29 23:43 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Sverre Rabbelier, Git List, Ron1, Jacob Helwig

On Fri, 29 Jan 2010, Junio C Hamano wrote:

> Any comment on my previous rewording patch ($gmane/138369)?

A bit too verbose (even if it can be configured out) and frightening I'd 
say.

> "Note: '%s' isn't a local branch head: creating a detached HEAD\n"
> "If you want to create a new branch from this checkout, you may do so\n"
> "(now or later) by using -b with the checkout command again. Example:\n"
> "  git checkout -b <new_branch_name>\n", new->name);
> 
> A major difference I think is that I avoided a jargon (detached HEAD), and
> chose not to say why the input was interpreted as a request to switch to
> that state.

To the contrary, I think it is about time we use proper Git jargon.  
Otherwise how can we expect people to relate to the documentation where 
that jargon is indeed used?  Even on this very mailing list we refer to 
that state as a "detached HEAD".  And Google gives precisely the right 
info with "detached HEAD" while any other verbiage might not.

And just saying that "you're not on any branch anymore" is still leaving 
the user wondering why.  At least with the "isn't a local branch head" 
the user has 2 clues: it has to be a _local_ branch and a branch _head_ 
not to create a detached HEAD.  So I still prefer the above rewording.

> Oh, of course, I also added advice.detachedHEAD to squelch it ;-)

That is indeed an excellent idea.


Nicolas

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-29 23:12         ` Junio C Hamano
@ 2010-01-29 23:30           ` Ron Garret
  0 siblings, 0 replies; 111+ messages in thread
From: Ron Garret @ 2010-01-29 23:30 UTC (permalink / raw)
  To: git

In article <7vk4v0fqts.fsf@alter.siamese.dyndns.org>,
 Junio C Hamano <gitster@pobox.com> wrote:

> Ron Garret <ron1@flownet.com> writes:
> 
> > My actual use case is very complicated, but here's a simplified version:
> >
> > Suppose I'm using git as a back-end for a wiki.  I want to look at the 
> > state of the entire wiki as it was in some point in the past, and I also 
> > want to be able to look at the diffs between individual pages as they 
> > were then and as they are now.
> 
> Don't think you are so special ;-)

Never.  :-)

> "git checkout $that_old_commit" was
> invented _exactly_ for that use case.  You can look around from that
> state, and when you are done sightseeing, you can come back by doing a
> "git checkout master" (or whichever branch you want to be on).

Yes, that's what I would have expected.  Except that it not only updates 
my working tree, it updates my head also, so git diff doesn't give me 
the diffs that I want.  (This makes sense for the usual use case.)

> You don't necessarily have to check out an old state if the only thing
> you are interested in is to review how the contents changed over time.
> Use "git log -p" (from the current tip) for that.
> 
> If you chose to have an old checkout and then traverse the changes over
> time leading to the current tip, you would say "git log -p ..master"
> instead.

There's also this:


git rev-list HEAD -- [filename]

git ls-tree [some-hash-from-the-list-above]

Then for each line in the result:

git cat-file blob [hash] > [filename]


which seems like a horrible hack, but actually does what I want.

rg

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  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:28         ` Julian Phillips
  2010-01-30  0:14           ` Ron Garret
  2 siblings, 1 reply; 111+ messages in thread
From: Julian Phillips @ 2010-01-29 23:28 UTC (permalink / raw)
  To: Ron Garret; +Cc: git

On Fri, 29 Jan 2010 14:47:49 -0800, Ron Garret <ron1@flownet.com> wrote:
> My actual use case is very complicated, but here's a simplified version:
> 
> Suppose I'm using git as a back-end for a wiki.  I want to look at the 
> state of the entire wiki as it was in some point in the past, and I also

> want to be able to look at the diffs between individual pages as they 
> were then and as they are now.  The most straightforward way I can think

> of to do that is to simply copy an old commit into my working tree 
> without changing anything else.  Then I can look at the old version by 
> simply looking at the files, and I can get the diffs by simply doing a 
> git diff.
> 
> If I do a git reset --hard then I get the old version, but I lose my 
> HEAD pointer so that git diff doesn't give me what I want any more.
> 
> BTW, it turns out that git checkout [commit] . doesn't do the right 
> thing either.  Apparently, it still updates my index, so git diff still 
> doesn't do the right thing.

If I understand what you want correctly, then:

git diff --cached -R [path]

should be the appropriate command after the "git checkout <commit> .".

-- 
Julian

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-29 21:32             ` Sverre Rabbelier
  2010-01-29 21:51               ` Nicolas Pitre
@ 2010-01-29 23:16               ` A Large Angry SCM
  1 sibling, 0 replies; 111+ messages in thread
From: A Large Angry SCM @ 2010-01-29 23:16 UTC (permalink / raw)
  To: Sverre Rabbelier
  Cc: Nicolas Pitre, Junio C Hamano, Git List, Ron1, Jacob Helwig

Sverre Rabbelier wrote:
> Heya,
> 
> On Fri, Jan 29, 2010 at 22:29, Nicolas Pitre <nico@fluxnic.net> wrote:
>> Then who was arguing about making Git more user friendly rather
>> then less?
> 
> Using a detached head is a more advanced feature than wanting to
> checkout a remote branch locally, creating a local tracking branch. As
> such, 'git checkout origin/topic' now means the same as 'git checkout
> -t origin/topic', and you can get the old behavior back by doing 'git
> checkout origin/topic^0'. I don't see what the problem is, if you're
> using a detached head you're an advanced enough git user that you can
> remember that you can use '^0' to detach your head. It's not all that
> uncommon to do 'git checkout HEAD^0' to detach your head to the
> current branch, no?
> 

[I'm still catching up on this thread]

What we call 'Detached head' is _the_ normal way ti use git for quite a 
number of users. And given the current UI, it's not really advanced.

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  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
  2 siblings, 1 reply; 111+ messages in thread
From: Junio C Hamano @ 2010-01-29 23:12 UTC (permalink / raw)
  To: Ron Garret; +Cc: git

Ron Garret <ron1@flownet.com> writes:

> My actual use case is very complicated, but here's a simplified version:
>
> Suppose I'm using git as a back-end for a wiki.  I want to look at the 
> state of the entire wiki as it was in some point in the past, and I also 
> want to be able to look at the diffs between individual pages as they 
> were then and as they are now.

Don't think you are so special ;-) "git checkout $that_old_commit" was
invented _exactly_ for that use case.  You can look around from that
state, and when you are done sightseeing, you can come back by doing a
"git checkout master" (or whichever branch you want to be on).

You don't necessarily have to check out an old state if the only thing
you are interested in is to review how the contents changed over time.
Use "git log -p" (from the current tip) for that.

If you chose to have an old checkout and then traverse the changes over
time leading to the current tip, you would say "git log -p ..master"
instead.

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  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:28         ` Julian Phillips
  2 siblings, 0 replies; 111+ messages in thread
From: Octavio Alvarez @ 2010-01-29 23:05 UTC (permalink / raw)
  To: Ron Garret, git

On Fri, 29 Jan 2010 14:47:49 -0800, Ron Garret <ron1@flownet.com> wrote:
>
> My actual use case is very complicated, but here's a simplified version:
>
> Suppose I'm using git as a back-end for a wiki.  I want to look at the
> state of the entire wiki as it was in some point in the past,

mkdir new_dir; git archive --format=tar tree-ish | tar -C new_dir -x

Of course, this is slower than just checking out the files that differ,
I agree.

> and I also
> want to be able to look at the diffs between individual pages as they
> were then and as they are now.

git diff commit-ish1 commit-ish2 file1 file2 ...

Or you could just clone it and compare whatever you want there and just
erase when done. This would allow you to do "git pull" from the origin.

> If I do a git reset --hard then I get the old version, but I lose my
> HEAD pointer so that git diff doesn't give me what I want any more.

You could tag the current version before resetting and then issue
git reset --hard the_tag, but I guess you would run into race conditions:
someone updates the wiki while the HEAD is in another commit.

Hope it helps. :-)

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-29 22:32     ` Octavio Alvarez
@ 2010-01-29 22:47       ` Ron Garret
  2010-01-29 23:05         ` Octavio Alvarez
                           ` (2 more replies)
  0 siblings, 3 replies; 111+ messages in thread
From: Ron Garret @ 2010-01-29 22:47 UTC (permalink / raw)
  To: git

In article <op.u7bfjni44oyyg1@alvarezp-ws>,
 "Octavio Alvarez" <alvarezp@alvarezp.ods.org> wrote:

> On Fri, 29 Jan 2010 13:34:01 -0800, Ron Garret <ron1@flownet.com> wrote:
> 
> > In article <op.u7a909hf4oyyg1@alvarezp-ws>,
> >  "Octavio Alvarez" <alvarezp@alvarezp.ods.org> wrote:
> >
> >> On Fri, 29 Jan 2010 12:20:46 -0800, Ron1 <ron1@flownet.com> wrote:
> >>
> >> It means that if you switch to master^ and commit, your commit will
> >> be applied but not tracked (since there is not any branch to advance).
> >>
> >> You would need to do git checkout -b 'new_branch', and then commit.
> >> Now, new_branch will advance with your new commit.
> >
> > OK, I think I understand that.
> >
> > Here's the thing: I can do this:
> >
> > git checkout commit-id filename
> >
> > and restore a particular revision of a particular file to my working
> > tree without affecting my HEAD pointer.  I would expect then that
> >
> > git checkout commit-id
> >
> > with no filename would do the same thing, except restore the entire tree
> > from that commit (including deleting files that didnt' exist then).  And
> > indeed it does that (or at least appears to -- I haven't explored this
> > in depth), except that it DOES move my HEAD pointer to this weird
> > non-branch thing.
> 
> I see. You somehow imply that "git checkout commit-id" overlaps with
> "git reset --hard commit-id".

I'm not intentionally implying that.  I don't think git reset --hard 
does what I want either (but I could be wrong about that).

> Even assuming the behavior was not documented in man git-checkout, the
> second example looks useless. What is your use case? What would you do
> after having all the files in the tree switched to another commit,
> without actually updating HEAD to the commit, other than git reset --hard
> again or git revert?

My actual use case is very complicated, but here's a simplified version:

Suppose I'm using git as a back-end for a wiki.  I want to look at the 
state of the entire wiki as it was in some point in the past, and I also 
want to be able to look at the diffs between individual pages as they 
were then and as they are now.  The most straightforward way I can think 
of to do that is to simply copy an old commit into my working tree 
without changing anything else.  Then I can look at the old version by 
simply looking at the files, and I can get the diffs by simply doing a 
git diff.

If I do a git reset --hard then I get the old version, but I lose my 
HEAD pointer so that git diff doesn't give me what I want any more.

BTW, it turns out that git checkout [commit] . doesn't do the right 
thing either.  Apparently, it still updates my index, so git diff still 
doesn't do the right thing.

rg

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-29 22:39                     ` Junio C Hamano
@ 2010-01-29 22:46                       ` Jacob Helwig
  2010-01-29 23:43                       ` Nicolas Pitre
  1 sibling, 0 replies; 111+ messages in thread
From: Jacob Helwig @ 2010-01-29 22:46 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Nicolas Pitre, Sverre Rabbelier, Git List, Ron1

On Fri, Jan 29, 2010 at 14:39, Junio C Hamano <gitster@pobox.com> wrote:
> Any comment on my previous rewording patch ($gmane/138369)?
>
> "Note: '%s' isn't a local branch head: creating a detached HEAD\n"
> "If you want to create a new branch from this checkout, you may do so\n"
> "(now or later) by using -b with the checkout command again. Example:\n"
> "  git checkout -b <new_branch_name>\n", new->name);
>
> A major difference I think is that I avoided a jargon (detached HEAD), and
> chose not to say why the input was interpreted as a request to switch to
> that state.
>
> Oh, of course, I also added advice.detachedHEAD to squelch it ;-)
>

For what it's worth, I'm +1 for this.  Especially the ability to squelch it.

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  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
  0 siblings, 2 replies; 111+ messages in thread
From: Junio C Hamano @ 2010-01-29 22:39 UTC (permalink / raw)
  To: Nicolas Pitre
  Cc: Junio C Hamano, Sverre Rabbelier, Git List, Ron1, Jacob Helwig

Nicolas Pitre <nico@fluxnic.net> writes:

> On Fri, 29 Jan 2010, Junio C Hamano wrote:
>
>> We used to just say "topic is not a rev nor path" and failed when the user
>> said "git checkout topic".  And the magic kicks in when there is only one
>> "remotes/*/topic".
>> 
>> Because this cannot be any request other than to check out a local branch
>> "topic", and because there is no place more sensible than the "topic"
>> taken from the "origin" (as that is the sole place that has "topic"), it
>> dwims as a shorthand for "checkout -b topic origin/topic" and tells you
>> that it did so.
>
> OK.  That is probably sensible.
>
> I don't think any improvement on the detached head message should 
> presume on this though.
>
> And it might be a good idea to say explicitly that what happened is the 
> creation of a detached HEAD, like in:

Any comment on my previous rewording patch ($gmane/138369)?

"Note: '%s' isn't a local branch head: creating a detached HEAD\n"
"If you want to create a new branch from this checkout, you may do so\n"
"(now or later) by using -b with the checkout command again. Example:\n"
"  git checkout -b <new_branch_name>\n", new->name);

A major difference I think is that I avoided a jargon (detached HEAD), and
chose not to say why the input was interpreted as a request to switch to
that state.

Oh, of course, I also added advice.detachedHEAD to squelch it ;-)

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  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
  1 sibling, 1 reply; 111+ messages in thread
From: Nicolas Pitre @ 2010-01-29 22:34 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Sverre Rabbelier, Git List, Ron1, Jacob Helwig

On Fri, 29 Jan 2010, Junio C Hamano wrote:

> We used to just say "topic is not a rev nor path" and failed when the user
> said "git checkout topic".  And the magic kicks in when there is only one
> "remotes/*/topic".
> 
> Because this cannot be any request other than to check out a local branch
> "topic", and because there is no place more sensible than the "topic"
> taken from the "origin" (as that is the sole place that has "topic"), it
> dwims as a shorthand for "checkout -b topic origin/topic" and tells you
> that it did so.

OK.  That is probably sensible.

I don't think any improvement on the detached head message should 
presume on this though.

And it might be a good idea to say explicitly that what happened is the 
creation of a detached HEAD, like in:

diff --git a/builtin-checkout.c b/builtin-checkout.c
index 5277817..c0a44d7 100644
--- a/builtin-checkout.c
+++ b/builtin-checkout.c
@@ -523,7 +523,10 @@ static void update_refs_for_switch(struct checkout_opts *opts,
 			   REF_NODEREF, DIE_ON_ERR);
 		if (!opts->quiet) {
 			if (old->path)
-				fprintf(stderr, "Note: moving to '%s' which isn't a local branch\nIf you want to create a new branch from this checkout, you may do so\n(now or later) by using -b with the checkout command again. Example:\n  git checkout -b <new_branch_name>\n", new->name);
+				fprintf(stderr, "Note: '%s' isn't a local branch head: creating a detached HEAD\n"
+						"If you want to create a new branch from this checkout, you may do so\n"
+						"(now or later) by using -b with the checkout command again. Example:\n"
+						"  git checkout -b <new_branch_name>\n", new->name);
 			describe_detached_head("HEAD is now at", new->commit);
 		}
 	}

(string split onto multiple lines for easier source reading)

I think this is important to 1) mention the notion of a branch _head_, 
and 2) mention "detached HEAD" explicitly for people to be directed to 
appropriate documentation.  So with this change you know exactly what 
happened and why.


Nicolas

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-29 21:34   ` Ron Garret
@ 2010-01-29 22:32     ` Octavio Alvarez
  2010-01-29 22:47       ` Ron Garret
  0 siblings, 1 reply; 111+ messages in thread
From: Octavio Alvarez @ 2010-01-29 22:32 UTC (permalink / raw)
  To: Ron Garret, git

On Fri, 29 Jan 2010 13:34:01 -0800, Ron Garret <ron1@flownet.com> wrote:

> In article <op.u7a909hf4oyyg1@alvarezp-ws>,
>  "Octavio Alvarez" <alvarezp@alvarezp.ods.org> wrote:
>
>> On Fri, 29 Jan 2010 12:20:46 -0800, Ron1 <ron1@flownet.com> wrote:
>>
>> It means that if you switch to master^ and commit, your commit will
>> be applied but not tracked (since there is not any branch to advance).
>>
>> You would need to do git checkout -b 'new_branch', and then commit.
>> Now, new_branch will advance with your new commit.
>
> OK, I think I understand that.
>
> Here's the thing: I can do this:
>
> git checkout commit-id filename
>
> and restore a particular revision of a particular file to my working
> tree without affecting my HEAD pointer.  I would expect then that
>
> git checkout commit-id
>
> with no filename would do the same thing, except restore the entire tree
> from that commit (including deleting files that didnt' exist then).  And
> indeed it does that (or at least appears to -- I haven't explored this
> in depth), except that it DOES move my HEAD pointer to this weird
> non-branch thing.

I see. You somehow imply that "git checkout commit-id" overlaps with
"git reset --hard commit-id".

Even assuming the behavior was not documented in man git-checkout, the
second example looks useless. What is your use case? What would you do
after having all the files in the tree switched to another commit,
without actually updating HEAD to the commit, other than git reset --hard
again or git revert?

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-29 21:59           ` Junio C Hamano
@ 2010-01-29 22:18             ` Ron Garret
  0 siblings, 0 replies; 111+ messages in thread
From: Ron Garret @ 2010-01-29 22:18 UTC (permalink / raw)
  To: git

In article <7veil8h8rk.fsf@alter.siamese.dyndns.org>,
 Junio C Hamano <gitster@pobox.com> wrote:

> Ron Garret <ron1@flownet.com> writes:
> 
> > Of course it's possible.  It git can complain and do something (which is 
> > what it does now) then it can just as easily complain and do nothing.
> 
> It is not complaining.  It is telling you that you might have triggered an
> advanced feature you may not be prepared to use yet.
> 
> So forbidding the advanced feature from everybody won't be a solution.

s/complain/warn/

I'm just suggesting that maybe triggering the advanced feature ought not 
to be such an easy thing to do by accident.  It's certainly possible to 
make that change.  Reasonable people could disagree over whether this is 
desirable, or whether it would be better to just add this to a FAQ 
somewhere, or maybe even just leave this as a rite of passage.  
Apparently I'm the first person to ever have this problem or it would 
not have triggered so much discussion.

rg

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-29 21:54       ` Junio C Hamano
@ 2010-01-29 22:12         ` Ron Garret
  2010-01-30  0:33           ` Michael Witten
  0 siblings, 1 reply; 111+ messages in thread
From: Ron Garret @ 2010-01-29 22:12 UTC (permalink / raw)
  To: git

In article <7vmxzwh906.fsf@alter.siamese.dyndns.org>,
 Junio C Hamano <gitster@pobox.com> wrote:

> Sverre Rabbelier <srabbelier@gmail.com> writes:
> 
> > On Fri, Jan 29, 2010 at 22:24, Ron Garret <ron1@flownet.com> wrote:
> >> Yes, I read that.  But what I'm trying to do is not just *look* at the
> >> history, I want to restore my working tree to a previous version.  The
> >> "Exploring History" section of the docs doesn't say how to do that.
> >
> > Do you want to restore your working tree only, or also throw away the
> > history? If the former, you could look at 'git revert',...
> 
> I think he wanted to check paths out of a commit and the set of paths
> happened to be "everything".
> 
> IOW, "checkout $commit ."

Yes!!!  That's it exactly!

rg

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-29 21:58                 ` Junio C Hamano
@ 2010-01-29 22:00                   ` Sverre Rabbelier
  2010-01-29 22:34                   ` Nicolas Pitre
  1 sibling, 0 replies; 111+ messages in thread
From: Sverre Rabbelier @ 2010-01-29 22:00 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Nicolas Pitre, Git List, Ron1, Jacob Helwig

Heya,

On Fri, Jan 29, 2010 at 22:58, Junio C Hamano <gitster@pobox.com> wrote:
> Sverre's explanation does not match reality.

Heh, that's the second time I messed up explaining this new feature,
maybe I should stop doing that... eh... my bad.

-- 
Cheers,

Sverre Rabbelier

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-29 21:43         ` Ron Garret
@ 2010-01-29 21:59           ` Junio C Hamano
  2010-01-29 22:18             ` Ron Garret
  0 siblings, 1 reply; 111+ messages in thread
From: Junio C Hamano @ 2010-01-29 21:59 UTC (permalink / raw)
  To: Ron Garret; +Cc: git

Ron Garret <ron1@flownet.com> writes:

> Of course it's possible.  It git can complain and do something (which is 
> what it does now) then it can just as easily complain and do nothing.

It is not complaining.  It is telling you that you might have triggered an
advanced feature you may not be prepared to use yet.

So forbidding the advanced feature from everybody won't be a solution.

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  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-30  8:59                 ` Jeff King
  1 sibling, 2 replies; 111+ messages in thread
From: Junio C Hamano @ 2010-01-29 21:58 UTC (permalink / raw)
  To: Nicolas Pitre; +Cc: Sverre Rabbelier, Git List, Ron1, Jacob Helwig

Nicolas Pitre <nico@fluxnic.net> writes:

> What purpose does this "feature" serve?  Making sure people remain 
> stupid and get even more confused when the special dwimery doesn't work 
> because they don't know the difference between a local branch and a 
> remote tracking branch?
>
> And now people will be left wondering why after a fetch they don't get 
> the latest stuff when they do "git checkout topic" again.  Is this any 
> better?

Sverre's explanation does not match reality.

We used to just say "topic is not a rev nor path" and failed when the user
said "git checkout topic".  And the magic kicks in when there is only one
"remotes/*/topic".

Because this cannot be any request other than to check out a local branch
"topic", and because there is no place more sensible than the "topic"
taken from the "origin" (as that is the sole place that has "topic"), it
dwims as a shorthand for "checkout -b topic origin/topic" and tells you
that it did so.

So people _has_ to still know that local branches are the only thing they
can check out (iow, "checkout topic" is not a request to check out a
remote tracking branch).

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  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
  1 sibling, 1 reply; 111+ messages in thread
From: Junio C Hamano @ 2010-01-29 21:54 UTC (permalink / raw)
  To: Sverre Rabbelier; +Cc: Ron Garret, git

Sverre Rabbelier <srabbelier@gmail.com> writes:

> On Fri, Jan 29, 2010 at 22:24, Ron Garret <ron1@flownet.com> wrote:
>> Yes, I read that.  But what I'm trying to do is not just *look* at the
>> history, I want to restore my working tree to a previous version.  The
>> "Exploring History" section of the docs doesn't say how to do that.
>
> Do you want to restore your working tree only, or also throw away the
> history? If the former, you could look at 'git revert',...

I think he wanted to check paths out of a commit and the set of paths
happened to be "everything".

IOW, "checkout $commit ."

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-29 21:32             ` Sverre Rabbelier
@ 2010-01-29 21:51               ` Nicolas Pitre
  2010-01-29 21:58                 ` Junio C Hamano
  2010-01-30  8:59                 ` Jeff King
  2010-01-29 23:16               ` A Large Angry SCM
  1 sibling, 2 replies; 111+ messages in thread
From: Nicolas Pitre @ 2010-01-29 21:51 UTC (permalink / raw)
  To: Sverre Rabbelier; +Cc: Junio C Hamano, Git List, Ron1, Jacob Helwig

On Fri, 29 Jan 2010, Sverre Rabbelier wrote:

> Heya,
> 
> On Fri, Jan 29, 2010 at 22:29, Nicolas Pitre <nico@fluxnic.net> wrote:
> > Then who was arguing about making Git more user friendly rather
> > then less?
> 
> Using a detached head is a more advanced feature than wanting to
> checkout a remote branch locally, creating a local tracking branch. As
> such, 'git checkout origin/topic' now means the same as 'git checkout
> -t origin/topic', and you can get the old behavior back by doing 'git
> checkout origin/topic^0'.

What purpose does this "feature" serve?  Making sure people remain 
stupid and get even more confused when the special dwimery doesn't work 
because they don't know the difference between a local branch and a 
remote tracking branch?

And now people will be left wondering why after a fetch they don't get 
the latest stuff when they do "git checkout topic" again.  Is this any 
better?

> I don't see what the problem is, if you're
> using a detached head you're an advanced enough git user that you can
> remember that you can use '^0' to detach your head.

I don't agree with the assertion that a detached HEAD is for advanced 
users only.

> It's not all that uncommon to do 'git checkout HEAD^0' to detach your 
> head to the current branch, no?

Certainly way more uncommon than 'git checkout origin/foo', and way less 
intuitive.


Nicolas

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-29 21:20       ` Nicolas Pitre
  2010-01-29 21:21         ` Sverre Rabbelier
@ 2010-01-29 21:49         ` Junio C Hamano
  2010-01-30  2:13         ` Johannes Schindelin
  2 siblings, 0 replies; 111+ messages in thread
From: Junio C Hamano @ 2010-01-29 21:49 UTC (permalink / raw)
  To: Nicolas Pitre; +Cc: Sverre Rabbelier, Git List, Ron1, Jacob Helwig

Nicolas Pitre <nico@fluxnic.net> writes:

>> These days, you can say "git checkout topic" to automagically create a
>> local "topic" branch that forks from "origin/topic" remote tracking branch
>> when you have one, thanks to Dscho's UI improvement ideas (one less
>> reason you may end up on a detached HEAD state without wanting to).
>
> If this is the case then I'm really disappointed.
>
> With all due respects, I don't share Dscho's sentiment about Git's 
> alleged non user-friendliness.  And I always praised Git's ability to 
> use a detached head to check out a remote branch, and never had any 
> problem teaching this concept to people.  So the above is not a UI 
> improvement at all to me.

Just in case you misunderstood...

This is "git checkout topic", not "git checkout origin/topic".  The rule
kicks in when you do not have local branch "topic" and there is a unique
"refs/remotes/*/topic".  Existing ways to explicitly ask for detaching are
unaffected, so "checkout origin/topic" or "checkout origin/topic^0" do
what you expect.

We used to just say "topic is not a rev nor path" and failed when the user
sayd "git checkout topic".

Because this cannot be any request other than to check out a local branch
"topic", and because there is no place more sensible than the "topic"
taken from the "origin" (as that is the sole place that has "topic"), it
dwims as a shorthand for "checkout -b topic origin/topic" and tells you
that it did so.

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-29 21:25       ` Jacob Helwig
@ 2010-01-29 21:43         ` Ron Garret
  2010-01-29 21:59           ` Junio C Hamano
  0 siblings, 1 reply; 111+ messages in thread
From: Ron Garret @ 2010-01-29 21:43 UTC (permalink / raw)
  To: git

In article <8c9a061001291325i4b8898b9m46054040c69f8fc6@mail.gmail.com>,
 Jacob Helwig <jacob.helwig@gmail.com> wrote:

> On Fri, Jan 29, 2010 at 13:16, Ron1 <ron1@flownet.com> wrote:
> > I know that master^ is a commit and not a branch.  I thought I was
> > invoking the third variant of git-checkout (as given on the git-checkout
> > man page) and checking out a commit (which the man page calls a
> > tree-ish).
> >
> > In any case, since my question seems to have sparked some discussion,
> > I'd like to offer two observations:
> >
> > 1.  Saying "isn't a local branch" is mightily confusing, because it is
> > ambiguous whether the problem is that it isn't a branch or if it isn't
> > local.
> >
> > 2.  If I pass something to git checkout (or any other command for that
> > matter) that it expects to be a branch but isn't a branch it would be
> > much better if it just gave an error and did nothing rather than give a
> > (confusing) warning and try to extrapolate the user's intentions.
> > Whatever a user could possibly mean by 'git checkout master^' it is
> > almost certainly not what that command actually does at the moment.
> >
> 
> I don't think that #2 would be possible.

Of course it's possible.  It git can complain and do something (which is 
what it does now) then it can just as easily complain and do nothing.

> My understanding is that
> branches are basically just there as convenient "names" for arbitrary
> commits.  In other words (in my understanding): There is no place that
> expects a "branch" where a commit (SHA-1) would not work (and be a
> perfectly valid use).

No, that's not true.  Branches have names that are recorded separately 
from non-branch commits.  It's not a big difference, but it is a 
difference.

rg

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-29 21:28     ` Sverre Rabbelier
@ 2010-01-29 21:40       ` Ron Garret
  2010-01-29 21:54       ` Junio C Hamano
  1 sibling, 0 replies; 111+ messages in thread
From: Ron Garret @ 2010-01-29 21:40 UTC (permalink / raw)
  To: git

In article 
<fabb9a1e1001291328s1df443d6jdf0501cda17072de@mail.gmail.com>,
 Sverre Rabbelier <srabbelier@gmail.com> wrote:

> Heya,
> 
> On Fri, Jan 29, 2010 at 22:24, Ron Garret <ron1@flownet.com> wrote:
> > Yes, I read that.  But what I'm trying to do is not just *look* at the
> > history, I want to restore my working tree to a previous version.  The
> > "Exploring History" section of the docs doesn't say how to do that.
> 
> Do you want to restore your working tree only,

Yes.

> or also throw away the history?

No.

> If the former, you could look at 'git revert'

If that's the right answer then the docs needs serious revision.  The 
docs for "git revert" say that what it does is:

"Given one existing commit, revert the change the patch introduces, and 
record a new commit that records it."

which does not sound at all like what I'm trying to do.

All I want to do is copy an old commit to my working tree, nothing else.  
I don't want to move my head pointer.  I don't want to muck with my 
index.  I don't want to commit any changes or undo any history.  It's a 
very simple thing.  It ought to be simple to do, but it doesn't seem to 
be.

rg

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-29 20:56       ` Sverre Rabbelier
@ 2010-01-29 21:35         ` Junio C Hamano
  0 siblings, 0 replies; 111+ messages in thread
From: Junio C Hamano @ 2010-01-29 21:35 UTC (permalink / raw)
  To: Sverre Rabbelier; +Cc: Git List, Ron1, Jacob Helwig

Sverre Rabbelier <srabbelier@gmail.com> writes:

> On Fri, Jan 29, 2010 at 21:48, Junio C Hamano <gitster@pobox.com> wrote:
>> I think "not a branch" is a good suggestion, whether the target of
>> checkout is "master^" or "origin/topic".
>
> Mhhh, for added clarity, do we want to change it to "branch name"? Since ...
>
> $ git grep "branch name" Documentation/ | wc -l
> 58
>
> ... suggests that we use that in other places as well?

I think the confusion is twofold:

    $ git checkout master^
    Note: moving to 'master^' which isn't a local branch
    If you want to create a new branch from this checkout, you may do so
    ...

The notice tells us:

 - We are moving to 'master^', but it doesn't say what that really means;

 - That 'master^' isn't a local branch, but it doesn't say why it matters
   if it is a local branch (name) or not.

But what it really should tell new people are:

 - The user is no longer on any branch;

 - What the implications of not being on any branch are;

Your "branch _name_" suggestion deals with another issue that is of lessor
importance compared to the above two:

 - The _reason_ we are detaching HEAD is because 'master^' did not spell a
   name of a local branch.

 - and perhaps how to be on a branch instead of detaching the head like so.

Compare the current output from "git checkout $commit" with output from
"git checkout topic" when you don't have a local branch "topic" but have a
unique remote tracking branch with the same name from a remote, namely
"origin" (that's the UI improvement from Dscho I mentioned in the previous
message):

    $ git checkout topic
    Branch topic set up to track remote branch topic from origin.
    Switched to a new branch 'topic'

which very clearly explains what is going on.

The current advisory message tells you what to do to create a new branch,
but doesn't explain why you might want to do so (or what is the downside
of not doing so) in the first place.  That adds to frustration for new
people.

So how about this strawman?

    $ git checkout origin/topic
    Note: checking out commit 'origin/topic'.
    You are no longer on any branch. You can look around, make changes and
    record them in new commits, but any new commit you make from now on will
    be lost when you check out another branch. If you want to create a new
    branch from this state to keep them, you may do so (now or later) by
    using -b with the checkout command again. Example:

      git checkout -b new_branch_name

    HEAD is now at f423ef5... tests: allow user to specify trash direc...

and hide the lines from "Note: checking out..." to the blank line before
"HEAD is now at" inside advice.detachedHEAD, so that people who know what
detached head is and want to take advantage of it to experiment without
having to worry about cleaning up will have to see only:

    $ git checkout origin/topic
    HEAD is now at f423ef5... tests: allow user to specify trash direc...



diff --git a/advice.c b/advice.c
index 936d98b..0be4b5f 100644
--- a/advice.c
+++ b/advice.c
@@ -5,6 +5,7 @@ int advice_status_hints = 1;
 int advice_commit_before_merge = 1;
 int advice_resolve_conflict = 1;
 int advice_implicit_identity = 1;
+int advice_detached_head = 1;
 
 static struct {
 	const char *name;
@@ -15,6 +16,7 @@ static struct {
 	{ "commitbeforemerge", &advice_commit_before_merge },
 	{ "resolveconflict", &advice_resolve_conflict },
 	{ "implicitidentity", &advice_implicit_identity },
+	{ "detachedhead", &advice_detached_head },
 };
 
 int git_default_advice_config(const char *var, const char *value)
diff --git a/advice.h b/advice.h
index 9b7a3ad..3244ebb 100644
--- a/advice.h
+++ b/advice.h
@@ -8,6 +8,7 @@ extern int advice_status_hints;
 extern int advice_commit_before_merge;
 extern int advice_resolve_conflict;
 extern int advice_implicit_identity;
+extern int advice_detached_head;
 
 int git_default_advice_config(const char *var, const char *value);
 
diff --git a/builtin-checkout.c b/builtin-checkout.c
index 5277817..0719e54 100644
--- a/builtin-checkout.c
+++ b/builtin-checkout.c
@@ -522,8 +522,16 @@ static void update_refs_for_switch(struct checkout_opts *opts,
 		update_ref(msg.buf, "HEAD", new->commit->object.sha1, NULL,
 			   REF_NODEREF, DIE_ON_ERR);
 		if (!opts->quiet) {
-			if (old->path)
-				fprintf(stderr, "Note: moving to '%s' which isn't a local branch\nIf you want to create a new branch from this checkout, you may do so\n(now or later) by using -b with the checkout command again. Example:\n  git checkout -b <new_branch_name>\n", new->name);
+			if (old->path && advice_detached_head)
+				fprintf(stderr, 
+"Note: checking out commit '%s'.\n"
+"You are no longer on any branch. You can look around, make changes and\n"
+"record them in new commits, but any new commit you make from now on will\n"
+"be lost when you check out another branch. If you want to create a new\n"
+"branch from this state to keep them, you may do so (now or later) by\n"
+"using -b with the checkout command again. Example:\n\n"
+"  git checkout -b new_branch_name\n\n",
+					new->name);
 			describe_detached_head("HEAD is now at", new->commit);
 		}
 	}

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-29 20:32 ` Octavio Alvarez
@ 2010-01-29 21:34   ` Ron Garret
  2010-01-29 22:32     ` Octavio Alvarez
  0 siblings, 1 reply; 111+ messages in thread
From: Ron Garret @ 2010-01-29 21:34 UTC (permalink / raw)
  To: git

In article <op.u7a909hf4oyyg1@alvarezp-ws>,
 "Octavio Alvarez" <alvarezp@alvarezp.ods.org> wrote:

> On Fri, 29 Jan 2010 12:20:46 -0800, Ron1 <ron1@flownet.com> wrote:
> 
> > [ron@mickey]$ git checkout master
> > Already on 'master'
> > [ron@mickey]$ git checkout master^
> > Note: moving to 'master^' which isn't a local branch
> > If you want to create a new branch from this checkout, you may do so
> > (now or later) by using -b with the checkout command again. Example:
> >   git checkout -b <new_branch_name>
> > HEAD is now at 7be05e0... test
> > [ron@mickey]$ git branch
> > * (no branch)
> >   master
> > [ron@mickey]$
> >
> > Huh?!?
> >
> > This is a test repository which has never been pulled from nor pushed to
> > anywhere.  So how is it possible that I have a non-local branch?
> 
> "Is a non-local branch" is not the same as "is not a local branch".
> 
> Think "branches" as tags that advance when you commit over them.
> 
> If you do gitk --all, only those commits with a green tag are
> "branches".
> 
> It means that if you switch to master^ and commit, your commit will
> be applied but not tracked (since there is not any branch to advance).
> 
> You would need to do git checkout -b 'new_branch', and then commit.
> Now, new_branch will advance with your new commit.

OK, I think I understand that.

Here's the thing: I can do this:

git checkout commit-id filename

and restore a particular revision of a particular file to my working 
tree without affecting my HEAD pointer.  I would expect then that

git checkout commit-id

with no filename would do the same thing, except restore the entire tree 
from that commit (including deleting files that didnt' exist then).  And 
indeed it does that (or at least appears to -- I haven't explored this 
in depth), except that it DOES move my HEAD pointer to this weird 
non-branch thing.

Here's what I think would be the correct behavior:



[ron@mickey]$ git checkout master^

"WARNING: master^ is not a branch.  It is a commit on the master branch.
Since the the commit you are asking for is on the same branch as your
current HEAD pointer, here's what I'm going to do:

1.  Copy the master^ commit to your working tree
2.  Leave your HEAD pointer where is was (i.e. pointing to the head
of the master branch).

If this is not what you wanted, you can undo it by typing "git checkout 
HEAD".  Also, in the future, you can avoid this warning by typing ...
instead.



Or something like that.

rg

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-29 21:29           ` Nicolas Pitre
@ 2010-01-29 21:32             ` Sverre Rabbelier
  2010-01-29 21:51               ` Nicolas Pitre
  2010-01-29 23:16               ` A Large Angry SCM
  0 siblings, 2 replies; 111+ messages in thread
From: Sverre Rabbelier @ 2010-01-29 21:32 UTC (permalink / raw)
  To: Nicolas Pitre; +Cc: Junio C Hamano, Git List, Ron1, Jacob Helwig

Heya,

On Fri, Jan 29, 2010 at 22:29, Nicolas Pitre <nico@fluxnic.net> wrote:
> Then who was arguing about making Git more user friendly rather
> then less?

Using a detached head is a more advanced feature than wanting to
checkout a remote branch locally, creating a local tracking branch. As
such, 'git checkout origin/topic' now means the same as 'git checkout
-t origin/topic', and you can get the old behavior back by doing 'git
checkout origin/topic^0'. I don't see what the problem is, if you're
using a detached head you're an advanced enough git user that you can
remember that you can use '^0' to detach your head. It's not all that
uncommon to do 'git checkout HEAD^0' to detach your head to the
current branch, no?

-- 
Cheers,

Sverre Rabbelier

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-29 21:21         ` Sverre Rabbelier
@ 2010-01-29 21:29           ` Nicolas Pitre
  2010-01-29 21:32             ` Sverre Rabbelier
  0 siblings, 1 reply; 111+ messages in thread
From: Nicolas Pitre @ 2010-01-29 21:29 UTC (permalink / raw)
  To: Sverre Rabbelier; +Cc: Junio C Hamano, Git List, Ron1, Jacob Helwig

[-- Attachment #1: Type: TEXT/PLAIN, Size: 592 bytes --]

On Fri, 29 Jan 2010, Sverre Rabbelier wrote:

> Heya,
> 
> On Fri, Jan 29, 2010 at 22:20, Nicolas Pitre <nico@fluxnic.net> wrote:
> > With all due respects, I don't share Dscho's sentiment about Git's
> > alleged non user-friendliness.  And I always praised Git's ability to
> > use a detached head to check out a remote branch, and never had any
> > problem teaching this concept to people.  So the above is not a UI
> > improvement at all to me.
> 
> I think 'git checkout origin/master^0' still works?

Then who was arguing about making Git more user friendly rather 
then less?


Nicolas

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  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
  0 siblings, 2 replies; 111+ messages in thread
From: Sverre Rabbelier @ 2010-01-29 21:28 UTC (permalink / raw)
  To: Ron Garret; +Cc: git

Heya,

On Fri, Jan 29, 2010 at 22:24, Ron Garret <ron1@flownet.com> wrote:
> Yes, I read that.  But what I'm trying to do is not just *look* at the
> history, I want to restore my working tree to a previous version.  The
> "Exploring History" section of the docs doesn't say how to do that.

Do you want to restore your working tree only, or also throw away the
history? If the former, you could look at 'git revert', if the latter,
'git reset --hard' could be what you need (warning: the latter is a
destructive command that will let you _throw away history_).

-- 
Cheers,

Sverre Rabbelier

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-29 21:16     ` Ron1
@ 2010-01-29 21:25       ` Jacob Helwig
  2010-01-29 21:43         ` Ron Garret
  0 siblings, 1 reply; 111+ messages in thread
From: Jacob Helwig @ 2010-01-29 21:25 UTC (permalink / raw)
  To: Ron1; +Cc: git

On Fri, Jan 29, 2010 at 13:16, Ron1 <ron1@flownet.com> wrote:
> I know that master^ is a commit and not a branch.  I thought I was
> invoking the third variant of git-checkout (as given on the git-checkout
> man page) and checking out a commit (which the man page calls a
> tree-ish).
>
> In any case, since my question seems to have sparked some discussion,
> I'd like to offer two observations:
>
> 1.  Saying "isn't a local branch" is mightily confusing, because it is
> ambiguous whether the problem is that it isn't a branch or if it isn't
> local.
>
> 2.  If I pass something to git checkout (or any other command for that
> matter) that it expects to be a branch but isn't a branch it would be
> much better if it just gave an error and did nothing rather than give a
> (confusing) warning and try to extrapolate the user's intentions.
> Whatever a user could possibly mean by 'git checkout master^' it is
> almost certainly not what that command actually does at the moment.
>

I don't think that #2 would be possible.  My understanding is that
branches are basically just there as convenient "names" for arbitrary
commits.  In other words (in my understanding): There is no place that
expects a "branch" where a commit (SHA-1) would not work (and be a
perfectly valid use).

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-29 20:36 ` Scott R. Godin
@ 2010-01-29 21:24   ` Ron Garret
  2010-01-29 21:28     ` Sverre Rabbelier
  0 siblings, 1 reply; 111+ messages in thread
From: Ron Garret @ 2010-01-29 21:24 UTC (permalink / raw)
  To: git

In article <hjvgs1$rep$1@ger.gmane.org>,
 "Scott R. Godin" <scottg.wp-hackers@mhg2.com> wrote:

> On 01/29/2010 03:20 PM, Ron1 wrote:
> > [ron@mickey]$ git checkout master
> > Already on 'master'
> > [ron@mickey]$ git checkout master^
> > Note: moving to 'master^' which isn't a local branch
> > If you want to create a new branch from this checkout, you may do so
> > (now or later) by using -b with the checkout command again. Example:
> >    git checkout -b<new_branch_name>
> > HEAD is now at 7be05e0... test
> > [ron@mickey]$ git branch
> > * (no branch)
> >    master
> > [ron@mickey]$
> >
> > Huh?!?
> >
> > This is a test repository which has never been pulled from nor pushed to
> > anywhere.  So how is it possible that I have a non-local branch?
> >
> > Thanks,
> > rg
> >
> 
> I believe what you're seeing is known as a detached head (see 
> <http://www.kernel.org/pub/software/scm/git/docs/git-checkout.html> 
> though I could be wrong about this.)
> 
> I think you may have intended to do git checkout HEAD^ or something 
> similar?

Yes, in fact that is exactly what I am trying to do.  But that has the 
same result.

> basically what you did was (I think) checkout (or attempt to 
> checkout) the parent commit on master.

Yes.  I posted it that way simply because 'git commit HEAD' depends on 
what HEAD is.  If HEAD is the head of master (which it was) then the 
result is the same.

> 
> this may offer some additional food for thought: 
> <http://www.kernel.org/pub/software/scm/git/docs/gittutorial.html#_exploring_h
> istory>

Yes, I read that.  But what I'm trying to do is not just *look* at the 
history, I want to restore my working tree to a previous version.  The 
"Exploring History" section of the docs doesn't say how to do that.

rg

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  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:49         ` Junio C Hamano
  2010-01-30  2:13         ` Johannes Schindelin
  2 siblings, 1 reply; 111+ messages in thread
From: Sverre Rabbelier @ 2010-01-29 21:21 UTC (permalink / raw)
  To: Nicolas Pitre; +Cc: Junio C Hamano, Git List, Ron1, Jacob Helwig

Heya,

On Fri, Jan 29, 2010 at 22:20, Nicolas Pitre <nico@fluxnic.net> wrote:
> With all due respects, I don't share Dscho's sentiment about Git's
> alleged non user-friendliness.  And I always praised Git's ability to
> use a detached head to check out a remote branch, and never had any
> problem teaching this concept to people.  So the above is not a UI
> improvement at all to me.

I think 'git checkout origin/master^0' still works?

-- 
Cheers,

Sverre Rabbelier

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-29 20:48     ` Junio C Hamano
  2010-01-29 20:56       ` Sverre Rabbelier
@ 2010-01-29 21:20       ` Nicolas Pitre
  2010-01-29 21:21         ` Sverre Rabbelier
                           ` (2 more replies)
  1 sibling, 3 replies; 111+ messages in thread
From: Nicolas Pitre @ 2010-01-29 21:20 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Sverre Rabbelier, Git List, Ron1, Jacob Helwig

On Fri, 29 Jan 2010, Junio C Hamano wrote:

> Sverre Rabbelier <srabbelier@gmail.com> writes:
> 
> >> master^ is a commit (the first parent of master), not a branch (local
> >> or otherwise).
> >
> > Perhaps we should change the message to say "not a branch" if it's not
> > a reference to a remote branch? Or simply changing the text to "not a
> > (local) branch"?
> 
> I think "not a branch" is a good suggestion, whether the target of
> checkout is "master^" or "origin/topic".
> 
> These days, you can say "git checkout topic" to automagically create a
> local "topic" branch that forks from "origin/topic" remote tracking branch
> when you have one, thanks to Dscho's UI improvement ideas (one less
> reason you may end up on a detached HEAD state without wanting to).

If this is the case then I'm really disappointed.

With all due respects, I don't share Dscho's sentiment about Git's 
alleged non user-friendliness.  And I always praised Git's ability to 
use a detached head to check out a remote branch, and never had any 
problem teaching this concept to people.  So the above is not a UI 
improvement at all to me.


Nicolas

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-29 20:35   ` Johannes Schindelin
@ 2010-01-29 21:16     ` Ron1
  2010-01-29 21:25       ` Jacob Helwig
  2010-01-31  7:32     ` Junio C Hamano
  1 sibling, 1 reply; 111+ messages in thread
From: Ron1 @ 2010-01-29 21:16 UTC (permalink / raw)
  To: git

In article <alpine.DEB.1.00.1001292131330.3749@intel-tinevez-2-302>,
 Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:

> Hi,
> 
> On Fri, 29 Jan 2010, Jacob Helwig wrote:
> 
> > On Fri, Jan 29, 2010 at 12:20, Ron1 <ron1@flownet.com> wrote:
> > > [ron@mickey]$ git checkout master
> > > Already on 'master'
> > > [ron@mickey]$ git checkout master^
> > > Note: moving to 'master^' which isn't a local branch
> > > If you want to create a new branch from this checkout, you may do so
> > > (now or later) by using -b with the checkout command again. Example:
> > >  git checkout -b <new_branch_name>
> > > HEAD is now at 7be05e0... test
> > > [ron@mickey]$ git branch
> > > * (no branch)
> > >  master
> > > [ron@mickey]$
> > >
> > > Huh?!?
> > >
> > > This is a test repository which has never been pulled from nor pushed to
> > > anywhere.  So how is it possible that I have a non-local branch?
> > 
> > master^ is a commit (the first parent of master), not a branch (local
> > or otherwise).
> 
> Indeed.  Maybe you (Ron1) need to get a bit more acquainted to Git before 
> complaining.


Chill, dude.  I'm not complaining.  I'm just confused.

I know that master^ is a commit and not a branch.  I thought I was 
invoking the third variant of git-checkout (as given on the git-checkout 
man page) and checking out a commit (which the man page calls a 
tree-ish).

In any case, since my question seems to have sparked some discussion, 
I'd like to offer two observations:

1.  Saying "isn't a local branch" is mightily confusing, because it is 
ambiguous whether the problem is that it isn't a branch or if it isn't 
local.

2.  If I pass something to git checkout (or any other command for that 
matter) that it expects to be a branch but isn't a branch it would be 
much better if it just gave an error and did nothing rather than give a 
(confusing) warning and try to extrapolate the user's intentions.  
Whatever a user could possibly mean by 'git checkout master^' it is 
almost certainly not what that command actually does at the moment.

rg

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-29 20:48     ` Junio C Hamano
@ 2010-01-29 20:56       ` Sverre Rabbelier
  2010-01-29 21:35         ` Junio C Hamano
  2010-01-29 21:20       ` Nicolas Pitre
  1 sibling, 1 reply; 111+ messages in thread
From: Sverre Rabbelier @ 2010-01-29 20:56 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Git List, Ron1, Jacob Helwig

Heya,

On Fri, Jan 29, 2010 at 21:48, Junio C Hamano <gitster@pobox.com> wrote:
> I think "not a branch" is a good suggestion, whether the target of
> checkout is "master^" or "origin/topic".

Mhhh, for added clarity, do we want to change it to "branch name"? Since ...

$ git grep "branch name" Documentation/ | wc -l
58

... suggests that we use that in other places as well?

-- 
Cheers,

Sverre Rabbelier

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  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:20       ` Nicolas Pitre
  1 sibling, 2 replies; 111+ messages in thread
From: Junio C Hamano @ 2010-01-29 20:48 UTC (permalink / raw)
  To: Sverre Rabbelier; +Cc: Git List, Ron1, Jacob Helwig

Sverre Rabbelier <srabbelier@gmail.com> writes:

>> master^ is a commit (the first parent of master), not a branch (local
>> or otherwise).
>
> Perhaps we should change the message to say "not a branch" if it's not
> a reference to a remote branch? Or simply changing the text to "not a
> (local) branch"?

I think "not a branch" is a good suggestion, whether the target of
checkout is "master^" or "origin/topic".

These days, you can say "git checkout topic" to automagically create a
local "topic" branch that forks from "origin/topic" remote tracking branch
when you have one, thanks to Dscho's UI improvement ideas (one less
reason you may end up on a detached HEAD state without wanting to).

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-29 20:35   ` Sverre Rabbelier
@ 2010-01-29 20:38     ` Jacob Helwig
  2010-01-29 20:48     ` Junio C Hamano
  1 sibling, 0 replies; 111+ messages in thread
From: Jacob Helwig @ 2010-01-29 20:38 UTC (permalink / raw)
  To: Sverre Rabbelier; +Cc: Git List, Ron1

On Fri, Jan 29, 2010 at 12:35, Sverre Rabbelier <srabbelier@gmail.com> wrote:
> Heya,
>
> On Fri, Jan 29, 2010 at 21:27, Jacob Helwig <jacob.helwig@gmail.com> wrote:
>> On Fri, Jan 29, 2010 at 12:20, Ron1 <ron1@flownet.com> wrote:
>>> This is a test repository which has never been pulled from nor pushed to
>>> anywhere.  So how is it possible that I have a non-local branch?
>>
>> master^ is a commit (the first parent of master), not a branch (local
>> or otherwise).
>
> Perhaps we should change the message to say "not a branch" if it's not
> a reference to a remote branch? Or simply changing the text to "not a
> (local) branch"?
>

I think "not a branch" would be better than "not a (local) branch".
In my mind, the latter reads almost exactly the same as the current
message.

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-29 20:20 Ron1
  2010-01-29 20:27 ` Jacob Helwig
  2010-01-29 20:32 ` Octavio Alvarez
@ 2010-01-29 20:36 ` Scott R. Godin
  2010-01-29 21:24   ` Ron Garret
  2 siblings, 1 reply; 111+ messages in thread
From: Scott R. Godin @ 2010-01-29 20:36 UTC (permalink / raw)
  To: git

On 01/29/2010 03:20 PM, Ron1 wrote:
> [ron@mickey]$ git checkout master
> Already on 'master'
> [ron@mickey]$ git checkout master^
> Note: moving to 'master^' which isn't a local branch
> If you want to create a new branch from this checkout, you may do so
> (now or later) by using -b with the checkout command again. Example:
>    git checkout -b<new_branch_name>
> HEAD is now at 7be05e0... test
> [ron@mickey]$ git branch
> * (no branch)
>    master
> [ron@mickey]$
>
> Huh?!?
>
> This is a test repository which has never been pulled from nor pushed to
> anywhere.  So how is it possible that I have a non-local branch?
>
> Thanks,
> rg
>

I believe what you're seeing is known as a detached head (see 
<http://www.kernel.org/pub/software/scm/git/docs/git-checkout.html> 
though I could be wrong about this.)

I think you may have intended to do git checkout HEAD^ or something 
similar? basically what you did was (I think) checkout (or attempt to 
checkout) the parent commit on master.

this may offer some additional food for thought: 
<http://www.kernel.org/pub/software/scm/git/docs/gittutorial.html#_exploring_history>

-- 
(please respond to the list as opposed to my email box directly,
unless you are supplying private information you don't want public
on the list)

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-29 20:27 ` Jacob Helwig
  2010-01-29 20:35   ` Sverre Rabbelier
@ 2010-01-29 20:35   ` Johannes Schindelin
  2010-01-29 21:16     ` Ron1
  2010-01-31  7:32     ` Junio C Hamano
  1 sibling, 2 replies; 111+ messages in thread
From: Johannes Schindelin @ 2010-01-29 20:35 UTC (permalink / raw)
  To: Jacob Helwig; +Cc: Ron1, git

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1517 bytes --]

Hi,

On Fri, 29 Jan 2010, Jacob Helwig wrote:

> On Fri, Jan 29, 2010 at 12:20, Ron1 <ron1@flownet.com> wrote:
> > [ron@mickey]$ git checkout master
> > Already on 'master'
> > [ron@mickey]$ git checkout master^
> > Note: moving to 'master^' which isn't a local branch
> > If you want to create a new branch from this checkout, you may do so
> > (now or later) by using -b with the checkout command again. Example:
> >  git checkout -b <new_branch_name>
> > HEAD is now at 7be05e0... test
> > [ron@mickey]$ git branch
> > * (no branch)
> >  master
> > [ron@mickey]$
> >
> > Huh?!?
> >
> > This is a test repository which has never been pulled from nor pushed to
> > anywhere.  So how is it possible that I have a non-local branch?
> 
> master^ is a commit (the first parent of master), not a branch (local
> or otherwise).

Indeed.  Maybe you (Ron1) need to get a bit more acquainted to Git before 
complaining.

Git is not user-friendly (much to my chagrin, and I tried to change it, 
but it is not going to happen), so the only way out is to really read up 
on good tutorials/manuals before you complain about something that is not 
working as you expect it.

Just as a general hint, I think the best documentation about Git was 
written by J. Bruce Fields (the user manual) and Scott Chacon (everything 
that has GitHub written on it, and Git Pro, and much, much more).  If you 
happen to speak Japanese, Junio's book might help you understand the ideas 
behind the current Git user interface, too.

Hth,
Dscho

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  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:35   ` Johannes Schindelin
  1 sibling, 2 replies; 111+ messages in thread
From: Sverre Rabbelier @ 2010-01-29 20:35 UTC (permalink / raw)
  To: Git List; +Cc: Ron1, Jacob Helwig

Heya,

On Fri, Jan 29, 2010 at 21:27, Jacob Helwig <jacob.helwig@gmail.com> wrote:
> On Fri, Jan 29, 2010 at 12:20, Ron1 <ron1@flownet.com> wrote:
>> This is a test repository which has never been pulled from nor pushed to
>> anywhere.  So how is it possible that I have a non-local branch?
>
> master^ is a commit (the first parent of master), not a branch (local
> or otherwise).

Perhaps we should change the message to say "not a branch" if it's not
a reference to a remote branch? Or simply changing the text to "not a
(local) branch"?

-- 
Cheers,

Sverre Rabbelier

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-29 20:20 Ron1
  2010-01-29 20:27 ` Jacob Helwig
@ 2010-01-29 20:32 ` Octavio Alvarez
  2010-01-29 21:34   ` Ron Garret
  2010-01-29 20:36 ` Scott R. Godin
  2 siblings, 1 reply; 111+ messages in thread
From: Octavio Alvarez @ 2010-01-29 20:32 UTC (permalink / raw)
  To: Ron1, git

On Fri, 29 Jan 2010 12:20:46 -0800, Ron1 <ron1@flownet.com> wrote:

> [ron@mickey]$ git checkout master
> Already on 'master'
> [ron@mickey]$ git checkout master^
> Note: moving to 'master^' which isn't a local branch
> If you want to create a new branch from this checkout, you may do so
> (now or later) by using -b with the checkout command again. Example:
>   git checkout -b <new_branch_name>
> HEAD is now at 7be05e0... test
> [ron@mickey]$ git branch
> * (no branch)
>   master
> [ron@mickey]$
>
> Huh?!?
>
> This is a test repository which has never been pulled from nor pushed to
> anywhere.  So how is it possible that I have a non-local branch?

"Is a non-local branch" is not the same as "is not a local branch".

Think "branches" as tags that advance when you commit over them.

If you do gitk --all, only those commits with a green tag are
"branches".

It means that if you switch to master^ and commit, your commit will
be applied but not tracked (since there is not any branch to advance).

You would need to do git checkout -b 'new_branch', and then commit.
Now, new_branch will advance with your new commit.

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: master^ is not a local branch -- huh?!?
  2010-01-29 20:20 Ron1
@ 2010-01-29 20:27 ` Jacob Helwig
  2010-01-29 20:35   ` Sverre Rabbelier
  2010-01-29 20:35   ` Johannes Schindelin
  2010-01-29 20:32 ` Octavio Alvarez
  2010-01-29 20:36 ` Scott R. Godin
  2 siblings, 2 replies; 111+ messages in thread
From: Jacob Helwig @ 2010-01-29 20:27 UTC (permalink / raw)
  To: Ron1; +Cc: git

On Fri, Jan 29, 2010 at 12:20, Ron1 <ron1@flownet.com> wrote:
> [ron@mickey]$ git checkout master
> Already on 'master'
> [ron@mickey]$ git checkout master^
> Note: moving to 'master^' which isn't a local branch
> If you want to create a new branch from this checkout, you may do so
> (now or later) by using -b with the checkout command again. Example:
>  git checkout -b <new_branch_name>
> HEAD is now at 7be05e0... test
> [ron@mickey]$ git branch
> * (no branch)
>  master
> [ron@mickey]$
>
> Huh?!?
>
> This is a test repository which has never been pulled from nor pushed to
> anywhere.  So how is it possible that I have a non-local branch?
>
> Thanks,
> rg
>

master^ is a commit (the first parent of master), not a branch (local
or otherwise).

^ permalink raw reply	[flat|nested] 111+ messages in thread

* master^ is not a local branch -- huh?!?
@ 2010-01-29 20:20 Ron1
  2010-01-29 20:27 ` Jacob Helwig
                   ` (2 more replies)
  0 siblings, 3 replies; 111+ messages in thread
From: Ron1 @ 2010-01-29 20:20 UTC (permalink / raw)
  To: git

[ron@mickey]$ git checkout master
Already on 'master'
[ron@mickey]$ git checkout master^
Note: moving to 'master^' which isn't a local branch
If you want to create a new branch from this checkout, you may do so
(now or later) by using -b with the checkout command again. Example:
  git checkout -b <new_branch_name>
HEAD is now at 7be05e0... test
[ron@mickey]$ git branch
* (no branch)
  master
[ron@mickey]$

Huh?!?

This is a test repository which has never been pulled from nor pushed to 
anywhere.  So how is it possible that I have a non-local branch?

Thanks,
rg

^ permalink raw reply	[flat|nested] 111+ messages in thread

end of thread, other threads:[~2010-02-03 18:27 UTC | newest]

Thread overview: 111+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-02-01 11:52 master^ is not a local branch -- huh?!? 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
  -- strict thread matches above, loose matches on Subject: below --
2010-01-29 20:20 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:35         ` 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
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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.