threads / patch / 6597

patchtone down the detached head warning

Subject: [PATCH] tone down the detached head warning

## tl;dr

35 messages between Jan 31, 2007 and Feb 2, 2007. Diffs are folded; open one to read it.

replies: 34people: 10as markdown or json

Nicolas Pitre· Jan 31, 2007, 19:10 UTC · lore

This is not meant to frighten people or even to suggest they might be doing something wrong, but rather to notify them of a state change and provide a likely option in the case this state was entered by mistake.

Signed-off-by: Nicolas Pitre <nico@cam.org>
---
Show changes to git-checkout.sh +3 −3
diff --git a/git-checkout.sh b/git-checkout.sh
index 8500f51..0bae86e 100755
--- a/git-checkout.sh
+++ b/git-checkout.sh
@@ -155,9 +155,9 @@ then
 	detached="$new"
 	if test -n "$oldbranch"
 	then
-		detach_warn="warning: you are not on ANY branch anymore.
-If you meant to create a new branch from this checkout, you may still do
-so (now or later) by using -b with the checkout command again.  Example:
+		detach_warn="Note: you are not on ANY branch anymore.
+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>"
 	fi
 elif test -z "$oldbranch" && test -n "$branch"
Jeff King· Jan 31, 2007, 23:19 UTC · re: Nicolas Pitre · lore

Re: [PATCH] tone down the detached head warning

On Wed, Jan 31, 2007 at 02:10:37PM -0500, Nicolas Pitre wrote:
> This is not meant to frighten people or even to suggest they might be
> doing something wrong, but rather to notify them of a state change and
> provide a likely option in the case this state was entered by mistake.

I like this much better. Though I wonder in Carl's case if we can do even better, since the user is checking out a tracking branch. Does it really make sense to say "you are not on ANY branch"? Maybe instead:

-- >8 -- git-checkout: note use of remote tracking branch when making detached warning

--- Carl, can you comment? Does this require more explanation about why it matters that you're on a remote tracking branch?

 git-checkout.sh |   10 +++++++++-
 1 files changed, 9 insertions(+), 1 deletions(-)
Show changes to git-checkout.sh +9 −1
diff --git a/git-checkout.sh b/git-checkout.sh
index ed04815..68533a1 100755
--- a/git-checkout.sh
+++ b/git-checkout.sh
@@ -14,6 +14,7 @@ force=
 branch=
 newbranch=
 newbranch_log=
+detached_remote=
 merge=
 LF='
 '
@@ -58,6 +59,9 @@ while [ "$#" != "0" ]; do
 			if git-show-ref --verify --quiet -- "refs/heads/$arg"
 			then
 				branch="$arg"
+			elif git-show-ref --verify --quiet -- "refs/remotes/$arg"
+			then
+				detached_remote="$arg"
 			fi
 		elif rev=$(git-rev-parse --verify "$arg^{tree}" 2>/dev/null)
 		then
@@ -155,7 +159,11 @@ then
 	detached="$new"
 	if test -n "$oldbranch"
 	then
-		detach_warn="Note: you are not on ANY branch anymore.
+		case "$detached_remote" in
+		  "") detach_warn="Note: you are not on ANY branch anymore." ;;
+		   *) detach_warn="Note: you are on the remote tracking branch '$detached_remote'" ;;
+		esac
+		detach_warn="$detach_warn
 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>"
-- 
1.5.0.rc2.587.gbedb-dirty
Jakub Narebski· Jan 31, 2007, 23:25 UTC · re: Jeff King · lore

Re: [PATCH] tone down the detached head warning

Jeff King wrote:
Show 12 quoted lines
> On Wed, Jan 31, 2007 at 02:10:37PM -0500, Nicolas Pitre wrote:
> 
>> This is not meant to frighten people or even to suggest they might be
>> doing something wrong, but rather to notify them of a state change and
>> provide a likely option in the case this state was entered by mistake.
> 
> I like this much better. Though I wonder in Carl's case if we can do
> even better, since the user is checking out a tracking branch. Does it
> really make sense to say "you are not on ANY branch"? Maybe instead:
> 
> -- >8 --
> git-checkout: note use of remote tracking branch when making detached warning
 
You can checkout a tag, not a remote tracking branch!
-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
Jeff King· Jan 31, 2007, 23:27 UTC · re: Jakub Narebski · lore

Re: [PATCH] tone down the detached head warning

On Thu, Feb 01, 2007 at 12:25:14AM +0100, Jakub Narebski wrote:
> > git-checkout: note use of remote tracking branch when making detached warning
> You can checkout a tag, not a remote tracking branch!
Huh?
$ git-checkout master
$ git-checkout origin/pu
Note: you are on the remote tracking branch 'origin/pu'
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>
$ git-checkout master
$ git-checkout v1.4.4.4
Note: you are not on ANY branch anymore.
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>

You _can_ check out a tracking branch (in fact, I believe that is what Carl was proposing for his users to do, but perhaps he had instead actually tagged it). And my patch leaves the traditional output for a tag (since you, are in fact, not on any branch at that point).

-Peff
Jakub Narebski· Jan 31, 2007, 23:33 UTC · re: Jeff King · lore

Re: [PATCH] tone down the detached head warning

Jeff King wrote:
Show 7 quoted lines
> On Thu, Feb 01, 2007 at 12:25:14AM +0100, Jakub Narebski wrote:
> 
>>> git-checkout: note use of remote tracking branch when making detached warning
>>
>> You can checkout a tag, not a remote tracking branch!
> 
> Huh?

Ooops, I meant not _only_ a remote tracking branch (so note about detached HEAD shouldn't talk about remote tracking branch unless we make sure that it is remote tracking branch). Sorry.

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
Carl Worth· Jan 31, 2007, 23:54 UTC · re: Jeff King · lore

Re: [PATCH] tone down the detached head warning

On Wed, 31 Jan 2007 18:19:43 -0500, Jeff King wrote:
> I like this much better. Though I wonder in Carl's case if we can do
> even better, since the user is checking out a tracking branch. Does it
> really make sense to say "you are not on ANY branch"? Maybe instead:
...
> Carl, can you comment? Does this require more explanation about why it
> matters that you're on a remote tracking branch?

Getting rid of the word "Warning" and naming the remote-tracking branch instead of saying "not on ANY branch", (my, why should git ever yell like that?), are definitely improvements.

But they're fairly incremental. The fact is that the user is doing a very simple operation here, (just checking out a state for which git already has a name), and the user is given 3 lines of text to read and try to understand, (what the heck is a "remote tracking branch" anyway?). It still looks to me like the kind of thing that promotes a "git is hard to use" conception.

But, back to the original use case that brought this up. I did botch something in the original description. The "git clone; git checkout origin/branch-name" case does trigger the detached head state with its warnings. But the other alternative I showed does not:

	git fetch git://... branch-name:branch-name
Here, of course the user can use:
	git checkout branch-name

and not ever enter the "detached HEAD" state at all. So with this usage the discussion about where and when to warn becomes moot.

But this still isn't satisfying to me as something to offer users, as I'd really like them to be able to just "git pull" to follow subsequent things I commit to the branch. But for that the user would still need a bunch of configuration setup.

So it does come around to the fact that I'd like it to be easier for a user to get all the configuration setup for a local branch that knows which remote-tracking branch its associated with, (and this whether or not the remote-tracking branch was configured as part of the original clone or not).

-Carl
Jakub Narebski· Feb 1, 2007, 00:14 UTC · re: Carl Worth · lore

Re: [PATCH] tone down the detached head warning

Carl Worth wrote:
Show 5 quoted lines
> So it does come around to the fact that I'd like it to be easier for a
> user to get all the configuration setup for a local branch that knows
> which remote-tracking branch its associated with, (and this whether or
> not the remote-tracking branch was configured as part of the original
> clone or not).
 
There is new (untested and not complete) command git-remote for that.

Although the fact that clone copies all branches and tags (I don't think there is a way to clone only subset of branches), and that fetch is multi branch might be deterrent enough (unless one use one branch per repo).

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
Andy Parkins· Feb 1, 2007, 08:44 UTC · re: Jakub Narebski · lore

Re: [PATCH] tone down the detached head warning

On Thursday 2007 February 01 00:14, Jakub Narebski wrote:
> Although the fact that clone copies all branches and tags (I don't think
> there is a way to clone only subset of branches), and that fetch is multi

There is, as long as you are willing to organise your branches in a consistent way. I keep all my branches with the prefix "ap/" then on another development machine I just have

 pull = refs/heads/ap/*:refs/heads/up/ap/*

In my config. This means I can make local branches that won't be grabbed during the fetch, but still have branches automatically exported.

This actually highlights a weakness in the globbing. There is no way, for example, to grab only unprefixed branches because the glob is blind to path dividers (as is usual). What would be even better would be a two glob symbols, one meaning "do cross separators", one meaning "don't". I think rsync solves it for it's include/exclude patterns with a double asterisk. That is:

 rsync -av --exclude "foo/*/bar" src/ dest/
Would exclude anything called "bar" two levels under "foo/"; wheras
 rsync -av --exclude "foo/**/bar" src/ dest/

Would exclude anything called "bar" anywhere deeper than two levels under "foo".

I haven't thought of a good way of applying this in git though, and I have a feeling that it could just complicate things excessively.

Andy
-- 
Dr Andy Parkins, M Eng (hons), MIEE
andyparkins@gmail.com
Matthias Lederhofer· Feb 1, 2007, 12:48 UTC · re: Andy Parkins · lore

Re: [PATCH] tone down the detached head warning

Andy Parkins <andyparkins@gmail.com> wrote:
Show 32 quoted lines
> On Thursday 2007 February 01 00:14, Jakub Narebski wrote:
> 
> > Although the fact that clone copies all branches and tags (I don't think
> > there is a way to clone only subset of branches), and that fetch is multi
> 
> There is, as long as you are willing to organise your branches in a consistent 
> way.  I keep all my branches with the prefix "ap/" then on another 
> development machine I just have
> 
>  pull = refs/heads/ap/*:refs/heads/up/ap/*
> 
> In my config.  This means I can make local branches that won't be grabbed 
> during the fetch, but still have branches automatically exported.
> 
> This actually highlights a weakness in the globbing.  There is no way, for 
> example, to grab only unprefixed branches because the glob is blind to path 
> dividers (as is usual).  What would be even better would be a two glob 
> symbols, one meaning "do cross separators", one meaning "don't".  I think 
> rsync solves it for it's include/exclude patterns with a double asterisk.  
> That is:
> 
>  rsync -av --exclude "foo/*/bar" src/ dest/
> 
> Would exclude anything called "bar" two levels under "foo/"; wheras
> 
>  rsync -av --exclude "foo/**/bar" src/ dest/
> 
> Would exclude anything called "bar" anywhere deeper than two levels 
> under "foo".
> 
> I haven't thought of a good way of applying this in git though, and I have a 
> feeling that it could just complicate things excessively.

fnmatch with FNM_PATHNAME disables * to match on / but it does not support the ** syntax afaik.

Nicolas Pitre· Feb 1, 2007, 00:11 UTC · re: Jeff King · lore

Re: [PATCH] tone down the detached head warning

On Wed, 31 Jan 2007, Jeff King wrote:
Show 10 quoted lines
> On Wed, Jan 31, 2007 at 02:10:37PM -0500, Nicolas Pitre wrote:
> 
> > This is not meant to frighten people or even to suggest they might be
> > doing something wrong, but rather to notify them of a state change and
> > provide a likely option in the case this state was entered by mistake.
> 
> I like this much better. Though I wonder in Carl's case if we can do
> even better, since the user is checking out a tracking branch. Does it
> really make sense to say "you are not on ANY branch"? Maybe instead:
> 
[...]
> +		case "$detached_remote" in
> +		  "") detach_warn="Note: you are not on ANY branch anymore." ;;
> +		   *) detach_warn="Note: you are on the remote tracking branch '$detached_remote'" ;;
> +		esac
No.  This is misleading.

You are _not_ on the remote tracking branch. You just happen to have checked out a commit that came from a tracking branch, but you are still detached from any branch at that point.

Nicolas
Jeff King· Feb 1, 2007, 03:00 UTC · re: Nicolas Pitre · lore

Re: [PATCH] tone down the detached head warning

On Wed, Jan 31, 2007 at 07:11:34PM -0500, Nicolas Pitre wrote:
Show 5 quoted lines
> No.  This is misleading.
> 
> You are _not_ on the remote tracking branch.  You just happen to have 
> checked out a commit that came from a tracking branch, but you are still 
> detached from any branch at that point.

Sure, but that is a very subtle distinction that I doubt will make sense to git newbies. Having them check out what they consider to be a branch (and which is, in fact, a line of development -- just not one that you have locally marked as a head) and responding with "you are not on ANY branch" is a little off-putting.

Is there some text we can use that makes more sense in all situations?

I think part of the "scariness" of the message is that git-checkout does not _usually_ produce output. I wonder if, when switching HEAD, it usually printed "Now on branch <foo>", and for detached printed some special variant, it would seem more natural.

-Peff
Junio C Hamano· Feb 1, 2007, 03:23 UTC · re: Jeff King · lore

Re: [PATCH] tone down the detached head warning

Jeff King <peff@peff.net> writes:
> I think part of the "scariness" of the message is that git-checkout does
> not _usually_ produce output. I wonder if, when switching HEAD, it
> usually printed "Now on branch <foo>", and for detached printed some
> special variant, it would seem more natural.

That sounds sensible. Another thing I found slightly annoying about branch switching in git-checkout is that we list the paths with local changes only when the tip of the old branch and the new branch are different. Very often I start hacking while on 'master' and later find the change forms a concrete "theme", and then say "git checkout -b that-theme" to switch a branch; in such a case I do want the list of locally modified paths.

For example:
	: gitster project/master; edit foo.c
        : gitster project/master; git checkout -b theme
	M	foo.c
	Switched to a new branch "theme"
	: gitster project/theme; edit bar.c
        : gitster project/theme; git checkout master
	M	bar.c
        M	foo.c
        Switched to branch "master"
	: gitster project/master; git checkout master^
	M	bar.c
        M	foo.c
	Detached your HEAD -- you are not on any 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>
	: gitster project; 
would feel very natural and much less scary.
Note.  I run with PS1=': \h \W$(__git_ps1 "/%s"); '.
Jeff King· Feb 1, 2007, 03:29 UTC · re: Junio C Hamano · lore

Re: [PATCH] tone down the detached head warning

On Wed, Jan 31, 2007 at 07:23:21PM -0800, Junio C Hamano wrote:
Show 12 quoted lines
>         M	foo.c
>         Switched to branch "master"
> 	: gitster project/master; git checkout master^
> 	M	bar.c
>         M	foo.c
> 	Detached your HEAD -- you are not on any 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>
> 	: gitster project; 
>
> would feel very natural and much less scary.

Much improved, IMHO. As an added bonus, I think it creates some feedback that lets a user know when they have mistakenly used 'git checkout' to switch heads when they meant to restore a file.

I still wish there was some other language for detaching to a commit specified by a remote tracking branch; it just seems wrong to say "you are not on any branch" right after the user requests to checkout a branch (admittedly not one of their local branches, but for a user merely poking through the repository, the difference is probably not important).

-Peff
Nicolas Pitre· Feb 1, 2007, 03:47 UTC · re: Jeff King · lore

Re: [PATCH] tone down the detached head warning

On Wed, 31 Jan 2007, Jeff King wrote:
Show 19 quoted lines
> On Wed, Jan 31, 2007 at 07:23:21PM -0800, Junio C Hamano wrote:
> 
> >         M	foo.c
> >         Switched to branch "master"
> > 	: gitster project/master; git checkout master^
> > 	M	bar.c
> >         M	foo.c
> > 	Detached your HEAD -- you are not on any 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>
> > 	: gitster project; 
> >
> > would feel very natural and much less scary.
> 
> 
> Much improved, IMHO. As an added bonus, I think it creates some feedback
> that lets a user know when they have mistakenly used 'git checkout' to
> switch heads when they meant to restore a file.
Indeed.
Show 6 quoted lines
> I still wish there was some other language for detaching to a commit
> specified by a remote tracking branch; it just seems wrong to say "you
> are not on any branch" right after the user requests to checkout a
> branch (admittedly not one of their local branches, but for a user
> merely poking through the repository, the difference is probably not
> important).

But this language convey the truth and users will have to get used to it at some point. We should not hide the fact that HEAD is really detached at that point, otherwise it could be presumed that a commit might update the checked out (tracking) branch which is obviously not the case.

Nicolas
Jeff King· Feb 1, 2007, 03:54 UTC · re: Nicolas Pitre · lore

Re: [PATCH] tone down the detached head warning

On Wed, Jan 31, 2007 at 10:47:31PM -0500, Nicolas Pitre wrote:
> But this language convey the truth and users will have to get used to it 
> at some point. We should not hide the fact that HEAD is really detached at
> that point, otherwise it could be presumed that a commit might update the
> checked out (tracking) branch which is obviously not the case.

OK, so let's not lie about it, then. But that doesn't mean we can't explain further. What about:

$ git checkout origin/pu Detached your HEAD (based on remote origin/pu) -- you are not on any branch ...

Except that I think the line is getting a bit long. But the point is to explain _why_ we're detached (you could even put a different note for tags). If a user already knows that 'git checkout v1.4.4.4' is going to put him in a detached state, then he doesn't really care about the message one way or the other. But if he doesn't know (and there is no clue on the command line, except for the fact that we already know v1.4.4.4 is a tag and origin/pu is a remote tracking branch), then it might make it more why it happened.

-Peff
Junio C Hamano· Feb 1, 2007, 09:08 UTC · re: Junio C Hamano · lore

[PATCH] detached HEAD -- finishing touches

This updates "git-checkout" to report which branch you are switching to. Especially for people who do not use __git_ps1 from contrib/completion/git-completion.bash this would give a friendlier feedback of what is going on, and should make the reminder message much less scary.

Here is a sample session (the prompt tells which branch I am on).
* I have some local modification and realize that the change deserves
  to be on its own new topic branch.
    [git.git (master)]$ git diff --stat
     git-checkout.sh |   10 ++++++++--
     1 files changed, 8 insertions(+), 2 deletions(-)
* So I switch to a new branch.  I get a listing of local modifications
  and assuring "Switched to a new branch" message.
    [git.git (master)]$ git checkout -b jc/checkout
    M       git-checkout.sh
    Switched to a new branch "jc/checkout"
* If I switch back to "master", I get essentially the same.
    [git.git (jc/checkout)]$ git checkout master
    M       git-checkout.sh
    Switched to branch "master"
* Detaching head would say which commit I am at and reminds me that
  I am not on any branch (not that I would detach my HEAD while keeping
  precious local changes around in any real-world workflow -- this is
  just a sample session).
    [git.git (master)]$ git checkout master^
    M       git-checkout.sh
    Note: you are not on any branch and are at commit "master^"
    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>
* Coming back to an attached state can lose the detached HEAD, so
  I get warned and stopped.
    [git.git]$ git checkout master
    You are not on any branch and switching to branch 'master'
    may lose your changes.  At this point, you can do one of two things:
     (1) Decide it is Ok and say 'git checkout -f master';
     (2) Start a new branch from the current commit, by saying
         'git checkout -b <branch-name>'.
    Leaving your HEAD detached; not switching to branch 'master'.
* Moving around while my HEAD is detached is Ok.  I still get the list
  of local modifications.
    [git.git]$ git checkout master^0
    M       git-checkout.sh
* The previous step that switched to the tip commit is an obscure but
  useful trick.  My HEAD is still detached but now it is pointed at by
  an existing ref, so I can come back safely.
    [git.git]$ git checkout master
    M       git-checkout.sh
    Switched to branch "master"
* And we are back on the "master" branch.
    [git.git (master)]$ exit
Signed-off-by: Junio C Hamano <junkio@cox.net>

--- Junio C Hamano <junkio@cox.net> writes:

Show 7 quoted lines
> That sounds sensible.  Another thing I found slightly annoying
> about branch switching in git-checkout is that we list the paths
> with local changes only when the tip of the old branch and the
> new branch are different.  Very often I start hacking while on
> 'master' and later find the change forms a concrete "theme", and
> then say "git checkout -b that-theme" to switch a branch; in
> such a case I do want the list of locally modified paths.
 git-checkout.sh |   10 ++++++++--
 1 files changed, 8 insertions(+), 2 deletions(-)
Show changes to git-checkout.sh +8 −2
diff --git a/git-checkout.sh b/git-checkout.sh
index 0bae86e..deb4795 100755
--- a/git-checkout.sh
+++ b/git-checkout.sh
@@ -155,7 +155,7 @@ then
 	detached="$new"
 	if test -n "$oldbranch"
 	then
-		detach_warn="Note: you are not on ANY branch anymore.
+		detach_warn="Note: you are not on any branch and are at commit \"$new_name\"
 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>"
@@ -228,7 +228,7 @@ else
     saved_err=$?
     if test "$saved_err" = 0
     then
-	test "$new" = "$old" || git diff-index --name-status "$new"
+	git diff-index --name-status "$new"
     fi
     (exit $saved_err)
 fi
@@ -251,6 +251,12 @@ if [ "$?" -eq 0 ]; then
 	if test -n "$branch"
 	then
 		GIT_DIR="$GIT_DIR" git-symbolic-ref HEAD "refs/heads/$branch"
+		if test -n "$newbranch"
+		then
+			echo >&2 "Switched to a new branch \"$branch\""
+		else
+			echo >&2 "Switched to branch \"$branch\""
+		fi
 	elif test -n "$detached"
 	then
 		# NEEDSWORK: we would want a command to detach the HEAD
Raimund Bauer· Feb 1, 2007, 09:46 UTC · re: Junio C Hamano · lore

RE: [PATCH] detached HEAD -- finishing touches

Show 20 quoted lines
>     [git.git (master)]$ git checkout master^
>     M       git-checkout.sh
>     Note: you are not on any branch and are at commit "master^"
>     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>
> 
> * Coming back to an attached state can lose the detached HEAD, so
>   I get warned and stopped.
> 
>     [git.git]$ git checkout master
>     You are not on any branch and switching to branch 'master'
>     may lose your changes.  At this point, you can do one of 
> two things:
>      (1) Decide it is Ok and say 'git checkout -f master';
>      (2) Start a new branch from the current commit, by saying
>          'git checkout -b <branch-name>'.
>     Leaving your HEAD detached; not switching to branch 'master'.

Here you have a detached HEAD, but you haven't build any commits on top of it. Why shouldn't you be allowed to move away?

-- 
best regards

  Ray
Alex Riesen· Feb 1, 2007, 09:53 UTC · re: Junio C Hamano · lore

Re: [PATCH] detached HEAD -- finishing touches

On 2/1/07, Junio C Hamano <junkio@cox.net> wrote:
Show 6 quoted lines
>     [git.git (master)]$ git checkout master^
>     M       git-checkout.sh
>     Note: you are not on any branch and are at commit "master^"
>     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>

How do you detach HEAD _without_ changing working tree at all? IOW, is there a "git checkout --detach"?

Alex Riesen· Feb 1, 2007, 09:54 UTC · re: Alex Riesen · lore

Re: [PATCH] detached HEAD -- finishing touches

On 2/1/07, Alex Riesen <raa.lkml@gmail.com> wrote:
Show 11 quoted lines
> On 2/1/07, Junio C Hamano <junkio@cox.net> wrote:
> >     [git.git (master)]$ git checkout master^
> >     M       git-checkout.sh
> >     Note: you are not on any branch and are at commit "master^"
> >     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>
>
> How do you detach HEAD _without_ changing working tree at all?
> IOW, is there a "git checkout --detach"?
>
Ah.. I see, the "obscure, but useful trick".
Matthias Lederhofer· Feb 1, 2007, 18:44 UTC · re: Junio C Hamano · lore

[PATCH] git-checkout: disable guides how to switch branches with ui.guide

--- Junio C Hamano <junkio@cox.net> wrote:

Show 22 quoted lines
> * Detaching head would say which commit I am at and reminds me that
>   I am not on any branch (not that I would detach my HEAD while keeping
>   precious local changes around in any real-world workflow -- this is
>   just a sample session).
> 
>     [git.git (master)]$ git checkout master^
>     M       git-checkout.sh
>     Note: you are not on any branch and are at commit "master^"
>     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>
> 
> * Coming back to an attached state can lose the detached HEAD, so
>   I get warned and stopped.
> 
>     [git.git]$ git checkout master
>     You are not on any branch and switching to branch 'master'
>     may lose your changes.  At this point, you can do one of two things:
>      (1) Decide it is Ok and say 'git checkout -f master';
>      (2) Start a new branch from the current commit, by saying
>          'git checkout -b <branch-name>'.
>     Leaving your HEAD detached; not switching to branch 'master'.

I think these two are too long, after a few times one knows exactly what to do and all this text is not necessary anymore.

Perhaps the name (ui.guide) should be different, I just did not find
any category to put this in.  The variable could become a general
variable to enable/disable very verbose explanations what to do in a
situation.
---
 git-checkout.sh |   14 ++++++++++++--
 1 files changed, 12 insertions(+), 2 deletions(-)
Show changes to git-checkout.sh +12 −2
diff --git a/git-checkout.sh b/git-checkout.sh
index deb4795..1eb8b06 100755
--- a/git-checkout.sh
+++ b/git-checkout.sh
@@ -5,6 +5,8 @@ SUBDIRECTORY_OK=Sometimes
 . git-sh-setup
 require_work_tree
 
+guide=$(git repo-config --bool --get ui.guide)
+[ -z "$guide" ] && guide=true
 old_name=HEAD
 old=$(git-rev-parse --verify $old_name 2>/dev/null)
 oldbranch=$(git-symbolic-ref $old_name 2>/dev/null)
@@ -155,10 +157,13 @@ then
 	detached="$new"
 	if test -n "$oldbranch"
 	then
-		detach_warn="Note: you are not on any branch and are at commit \"$new_name\"
+		detach_warn="Note: you are not on any branch and are at commit \"$new_name\""
+		if test "$guide" = true; then
+			detach_warn="$detach_warn
 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>"
+		fi
 	fi
 elif test -z "$oldbranch" && test -n "$branch"
 then
@@ -166,13 +171,18 @@ then
 	if test -z "$force"
 	then
 		git show-ref -d -s | grep "$old" >/dev/null || {
-			echo >&2 \
+			if test "$guide" = true; then
+				echo >&2 \
 "You are not on any branch and switching to branch '$new_name'
 may lose your changes.  At this point, you can do one of two things:
  (1) Decide it is Ok and say 'git checkout -f $new_name';
  (2) Start a new branch from the current commit, by saying
      'git checkout -b <branch-name>'.
 Leaving your HEAD detached; not switching to branch '$new_name'."
+			else
+				echo >&2 \
+"HEAD detached; use -f to switch to branch '$new_name'."
+			fi
 			exit 1;
 		}
 	fi
-- 
1.5.0.rc3.g4a88
Junio C Hamano· Feb 1, 2007, 20:42 UTC · re: Matthias Lederhofer · lore

Re: [PATCH] git-checkout: disable guides how to switch branches with ui.guide

Matthias Lederhofer <matled@gmx.net> writes:
Show 13 quoted lines
>> * Coming back to an attached state can lose the detached HEAD, so
>>   I get warned and stopped.
>> 
>>     [git.git]$ git checkout master
>>     You are not on any branch and switching to branch 'master'
>>     may lose your changes.  At this point, you can do one of two things:
>>      (1) Decide it is Ok and say 'git checkout -f master';
>>      (2) Start a new branch from the current commit, by saying
>>          'git checkout -b <branch-name>'.
>>     Leaving your HEAD detached; not switching to branch 'master'.
>
> I think these two are too long, after a few times one knows exactly
> what to do and all this text is not necessary anymore.

I doubt adding a per-repo or per-user configuration would be worth it.

The original hope was after a few times one would know to use either -f or -b depending on what he wants, and would not run plain vanilla branch switching "git checkout master".

Then one does not even have to see this message, not just the last "instruction" lines but "You are not on any branch" part.

Matthias Lederhofer· Feb 1, 2007, 20:51 UTC · re: Junio C Hamano · lore

Re: [PATCH] git-checkout: disable guides how to switch branches with ui.guide

Junio C Hamano <junkio@cox.net> wrote:
> The original hope was after a few times one would know to use
> either -f or -b depending on what he wants, and would not run
> plain vanilla branch switching "git checkout master".

What is the point in detached heads if the user should start using -b after a few times? I think detached heads are useful, so I will not use -b with it.

Junio C Hamano· Feb 1, 2007, 21:06 UTC · re: Matthias Lederhofer · lore

Re: [PATCH] git-checkout: disable guides how to switch branches with ui.guide

Matthias Lederhofer <matled@gmx.net> writes:
Show 7 quoted lines
> Junio C Hamano <junkio@cox.net> wrote:
>> The original hope was after a few times one would know to use
>> either -f or -b depending on what he wants, and would not run
>> plain vanilla branch switching "git checkout master".
> What is the point in detached heads if the user should start using -b
> after a few times?  I think detached heads are useful, so I will not
> use -b with it.

The error message you quoted is given when your head is detached and you tried the regular "checkout an existing branch" -- which will lose where your detached HEAD currently is. You either say "it's OK to lose it because I am done with it and I do not need to keep it anymore" with "-f", or you say "I am done with this detached state for now, but I know I need to revisit it later" with "-b".

So if you will not use -b with it to discard a temporary state that is detached HEAD, that is perfectly fine. Detached head is useful.

Matthias Lederhofer· Feb 1, 2007, 21:23 UTC · re: Junio C Hamano · lore

Re: [PATCH] git-checkout: disable guides how to switch branches with ui.guide

Junio C Hamano <junkio@cox.net> wrote:
> The error message you quoted [..]

Ok, I thought you were refering to the first one. Right, for the second one it is ok, one will get used to do -b or -f.

But I also quoted (and patched) the other one for switching to detached heads:

> Note: you are not on any branch and are at commit "v1.1.2"
> 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>

This one is a bit shorter but the last three lines are still a guide what to do in case you don't know what's going an.

Carl Worth· Feb 1, 2007, 21:34 UTC · re: Junio C Hamano · lore

Re: [PATCH] git-checkout: disable guides how to switch branches with ui.guide

On Thu, 01 Feb 2007 13:06:34 -0800, Junio C Hamano wrote:
> The error message you quoted is given when your head is detached
> and you tried the regular "checkout an existing branch" -- which
> will lose where your detached HEAD currently is.

I think the problem with this is that git tells the user so little information, ("may lose your changes"). What changes? Is that dirty state? Some commits? Hmm... have I committed anything? Why can't git be sure about what this operation is going to do?

I think a really useful message would be something like:
	You are not on any branch so switching to branch 'foo'
	will cause the following commits to be lost:
		ba531642 A commit headline here...
		b1189118 Another commit headline here...
	Refusing to checkout 'foo'.

Didn't a bunch of work get committed to make the reachability analysis feasible to generate a message like this?

If there are no commits that would become dangling, then the checkout should just proceed. As for the concern about losing a pointer to some "valuable" state that will still technically be reachable, but might be hard to get back, why not just print a message along the lines of:

	Leaving commit 7b1509f4 to checkout 'foo'.
(or just depend on the HEAD reflog).
-Carl

PS. If nothing else gets changed in the current message, please reconsider the current wording of:

	Leaving your HEAD detached; not switching to branch 'foo'.
Think: Wow, I had heard that git might help me shoot myself in the
foot, but I never though I might behead myself with it.
It would probably work to just reword that as:
	Not switching to branch 'foo'.
Nicolas Pitre· Feb 1, 2007, 21:59 UTC · re: Carl Worth · lore

Re: [PATCH] git-checkout: disable guides how to switch branches with ui.guide

On Thu, 1 Feb 2007, Carl Worth wrote:
Show 14 quoted lines
> I think the problem with this is that git tells the user so little
> information, ("may lose your changes"). What changes? Is that dirty
> state?  Some commits? Hmm... have I committed anything? Why can't git
> be sure about what this operation is going to do?
> 
> I think a really useful message would be something like:
> 
> 	You are not on any branch so switching to branch 'foo'
> 	will cause the following commits to be lost:
> 
> 		ba531642 A commit headline here...
> 		b1189118 Another commit headline here...
> 
> 	Refusing to checkout 'foo'.
Please just display the last commit since this list could get long.
Show 8 quoted lines
> If there are no commits that would become dangling, then the checkout
> should just proceed. As for the concern about losing a pointer to some
> "valuable" state that will still technically be reachable, but might
> be hard to get back, why not just print a message along the lines of:
> 
> 	Leaving commit 7b1509f4 to checkout 'foo'.
> 
> (or just depend on the HEAD reflog).
It is not fully available yet.
Nicolas
Carl Worth· Feb 1, 2007, 22:16 UTC · re: Nicolas Pitre · lore

Re: [PATCH] git-checkout: disable guides how to switch branches with ui.guide

On Thu, 01 Feb 2007 16:59:46 -0500 (EST), Nicolas Pitre wrote:
> Please just display the last commit since this list could get long.

In that case what might be nice would be if it printed a revision specification that could be handed to git-log or gitk for the user to inspect the situation.

And extra nice if it looked like b1189118..ba531642 when possible.
Show 5 quoted lines
> > 	Leaving commit 7b1509f4 to checkout 'foo'.
> >
> > (or just depend on the HEAD reflog).
>
> It is not fully available yet.

Right. I wasn't sure about when it is expected to come online. That's why I suggested the message above. It would be a very easy way to allow "git checkout" to work in the no-commits-to-lose case, but would still give the user the name of the commit she is leaving behind in case she wants to get back to it.

-Carl
Jakub Narebski· Feb 1, 2007, 23:18 UTC · re: Carl Worth · lore

Re: [PATCH] git-checkout: disable guides how to switch branches with ui.guide

Carl Worth wrote:
> On Thu, 01 Feb 2007 16:59:46 -0500 (EST), Nicolas Pitre wrote:
Show 7 quoted lines
>> Please just display the last commit since this list could get long.
> 
> In that case what might be nice would be if it printed a revision
> specification that could be handed to git-log or gitk for the user to
> inspect the situation.
> 
> And extra nice if it looked like b1189118..ba531642 when possible.
Nice idea. Now only to come up with detailed wording...
-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
Theodore Tso· Feb 1, 2007, 21:52 UTC · re: Junio C Hamano · lore

Re: [PATCH] detached HEAD -- finishing touches

On Thu, Feb 01, 2007 at 01:08:41AM -0800, Junio C Hamano wrote:
Show 7 quoted lines
>     [git.git]$ git checkout master
>     You are not on any branch and switching to branch 'master'
>     may lose your changes.  At this point, you can do one of two things:
>      (1) Decide it is Ok and say 'git checkout -f master';
>      (2) Start a new branch from the current commit, by saying
>          'git checkout -b <branch-name>'.
>     Leaving your HEAD detached; not switching to branch 'master'.

How hard would it be to simply simply set a flag once git has entered a detached HEAD state, and clear the flag if any git operation has modified the repository at all. If the flag is still set, then obviously the repository hasn't changed and so there are no changes that could be lost. i.e., if I've do:

<tytso@candygram> {/usr/projects/e2fsprogs/hg-to-git/test}  [master]
181% git checkout 2ab15cafae661765ecd7f256b1993b94d5534faf
warning: you are not on ANY branch anymore.
If you meant to create a new branch from this checkout, you may still do
so (now or later) by using -b with the checkout command again.  Example:
  git checkout -b <new_branch_name>
<tytso@candygram> {/usr/projects/e2fsprogs/hg-to-git/test}  
182% git checkout master
You are not on any branch and switching to branch 'master'
may lose your changes.  At this point, you can do one of two things:
 (1) Decide it is Ok and say 'git checkout -f master';
 (2) Start a new branch from the current commit, by saying
     'git checkout -b <branch-name>'.
Leaving your HEAD detached; not switching to branch 'master'.

It's really obvious there are no changes, so it makes git seem a little stupid to always be saying "may lose your changes". Can we simply let git know that there weren't any changes?

Otherwise we're just training users to just always use the -f option.
						- Ted
Junio C Hamano· Feb 2, 2007, 01:11 UTC · re: Theodore Tso · lore

Re: [PATCH] detached HEAD -- finishing touches

Theodore Tso <tytso@mit.edu> writes:
Show 14 quoted lines
> On Thu, Feb 01, 2007 at 01:08:41AM -0800, Junio C Hamano wrote:
>>     [git.git]$ git checkout master
>>     You are not on any branch and switching to branch 'master'
>>     may lose your changes.  At this point, you can do one of two things:
>>      (1) Decide it is Ok and say 'git checkout -f master';
>>      (2) Start a new branch from the current commit, by saying
>>          'git checkout -b <branch-name>'.
>>     Leaving your HEAD detached; not switching to branch 'master'.
>
> How hard would it be to simply simply set a flag once git has entered
> a detached HEAD state, and clear the flag if any git operation has
> modified the repository at all.  If the flag is still set, then
> obviously the repository hasn't changed and so there are no changes
> that could be lost.

Didn't I already point out that you can have a precious information while on the detached HEAD without making any commit, and that is the reason why we do not use the reachability crud from refs when deciding to issue the message?

Theodore Tso· Feb 2, 2007, 01:16 UTC · re: Junio C Hamano · lore

Re: [PATCH] detached HEAD -- finishing touches

On Thu, Feb 01, 2007 at 05:11:09PM -0800, Junio C Hamano wrote:
> Didn't I already point out that you can have a precious
> information while on the detached HEAD without making any
> commit, and that is the reason why we do not use the
> reachability crud from refs when deciding to issue the message?

Sorry, I must be dense. Exactly what precious information can be ever be lost in the following sequence:

git checkout HEAD~1 git checkout master

such that it want to train users to be typing
git checkout -f master
instead?
						- Ted
Carl Worth· Feb 2, 2007, 01:27 UTC · re: Junio C Hamano · lore

Re: [PATCH] detached HEAD -- finishing touches

On Thu, 01 Feb 2007 17:11:09 -0800, Junio C Hamano wrote:
> Didn't I already point out that you can have a precious
> information while on the detached HEAD without making any
> commit, and that is the reason why we do not use the
> reachability crud from refs when deciding to issue the message?

I recognize that a specification of the current commit could be precious, (as mentioned in a thread talking about the possibility of git-bisect using detached head rather than a branch).

And that's why I proposed a checkout away from detached head just printing the name of the commit that was being left.

Is there any other precious information that that solution would not address?

-Carl
Junio C Hamano· Feb 2, 2007, 01:30 UTC · re: Carl Worth · lore

Re: [PATCH] detached HEAD -- finishing touches

Carl Worth <cworth@cworth.org> writes:
Show 5 quoted lines
> And that's why I proposed a checkout away from detached head just
> printing the name of the commit that was being left.
>
> Is there any other precious information that that solution would not
> address?

I do not think of any offhand, but "did we make commit since we detached HEAD" was not a suggestion I made, so what I can think of does not matter much ;-).

Carl Worth· Feb 2, 2007, 01:46 UTC · re: Junio C Hamano · lore

Re: [PATCH] detached HEAD -- finishing touches

On Thu, 01 Feb 2007 17:30:40 -0800, Junio C Hamano wrote:
> I do not think of any offhand, but "did we make commit since we
> detached HEAD" was not a suggestion I made, so what I can think
> of does not matter much ;-).
Well, the suggestion I made was to:
1. Print the name of the commit we are leaving
2. Refuse to leave if what we are leaving would leave commits
   dangling, (and print a revision specification for those set of
   commits).
Do you have a reaction to that?
-Carl
Junio C Hamano· Feb 2, 2007, 02:38 UTC · re: Carl Worth · lore

Re: [PATCH] detached HEAD -- finishing touches

Carl Worth <cworth@cworth.org> writes:
Show 14 quoted lines
> On Thu, 01 Feb 2007 17:30:40 -0800, Junio C Hamano wrote:
>> I do not think of any offhand, but "did we make commit since we
>> detached HEAD" was not a suggestion I made, so what I can think
>> of does not matter much ;-).
>
> Well, the suggestion I made was to:
>
> 1. Print the name of the commit we are leaving
>
> 2. Refuse to leave if what we are leaving would leave commits
>    dangling, (and print a revision specification for those set of
>    commits).
>
> Do you have a reaction to that?

Not having thought things through, I am very tempted to say that we can leave things as they are, and when the reflog for HEAD materializes, just remove the check from the codepath that makes your HEAD point at an existing branch again. With the reflog on HEAD, you do not need to be reminded of which commit you are leaving so there is no need for 1 above, and you would not lose your point (either connected or disconnected) so there is no need for 2 above either.

← back to recent threads