Subject: Re: [PATCH] Documentation/git-checkout: Move `--detach` flag in synopsis to correct command

From: Junio C Hamano <[email-masked]>
Date: Wed, 11 Sep 2013 10:05:17 -0700

Benjamin Bergman <[email-masked]> writes:

> From a33659535cb0eac92bed42d5e494dbb8f5d9ab20 Mon Sep 17 00:00:00 2001
> From: Benjamin Bergman <[email-masked]>
> Date: Tue, 10 Sep 2013 16:00:29 -0500
> Subject: [PATCH] Documentation/git-checkout: Move `--detach` flag in synopsis
>  to correct command

These (except the first one that is a separator in the format-patch output)
go to your e-mail headers, not to the body of the message.

>
> Detailed description of `--detach` states that it is default for
> `<commit>` but needs to be specified for `<branch>`. The old man page
> synopsis showed the reverse.
> ---

Please sign-off your patch.

> -'git checkout' [-q] [-f] [-m] [<branch>]
> -'git checkout' [-q] [-f] [-m] [--detach] [<commit>]
> +'git checkout' [-q] [-f] [-m] [--detach] [<branch>]
> +'git checkout' [-q] [-f] [-m] [<commit>]

I am actually on the fence on this change.

The original shows two operations that do different things (one goes
to a named branch, the other goes to the state in which the HEAD is
detached at the named commit).

With the updated synopsis, even with the first form, if the user
uses --detach, the end result is like the second one. I personally
find the synopsis with the patch a bit more confusing, not less.

Can we update the second form (without touching the one that shows
"how to check out a named branch" at all) in a different way to
clarify?  E.g.

        'git checkout' [-q] [-f] [-m] [<commit> | --detach <branch>]

might be one way.  If you want to detach at a named commit, you can
directly give the commit object name; a branch name usually can be
used as a commit object name, but that use conflicts with the more
usual "check out that branch" usage, so you need to give --detach
explicitly if you use a branch name to name that commit you want to
detach at.  One drawback this has is that it does not capture that
you could say --detach (even though you do not have to) when using a
form that is _not_ a branch name to name your commit, e.g.

	git checkout --detach master^0

... thinks a bit more ...

Or we can split the "detaching" usage into two, which is how the
DESCRIPTION section does.  I.e.

    'git checkout' [-q] [-f] [-m] [<branch>]
   -'git checkout' [-q] [-f] [-m] --detach [<commit>]
   +'git checkout' [-q] [-f] [-m] --detach [<branch>]
   +'git checkout' [-q] [-f] [-m] <commit>
    'git checkout' [-q] [-f] [-m] [[-b|-B|--orphan] <new_branch>] [<st...

This would tell the reader that:

    - You can give "--detach" and no branch name---you would detach
      at the tip of your current branch;

    - You can give "--detach" and a branch name;

    - You can give a commit object name.

We could also throw in "[--detach]" in front of the <commit> to say
that it is accepted (even though it is not necessary.

>  'git checkout' [-q] [-f] [-m] [[-b|-B|--orphan] <new_branch>] [<start_point>]
>  'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>]
> [<tree-ish>] [--] <paths>...

Your MUA or editor line-wrapped the patch; please do not let them.

>  'git checkout' [-p|--patch] [<tree-ish>] [--] [<paths>...]

How about doing it this way?

-- >8 --
Subject: checkout: update synopsys and documentation on detaching HEAD

In the synopsis, the second form to detach HEAD at the named commit
labelled the argument as '<commit>'.  While this is technically more
correct, because the feature to detach is not limited to the tip of
a named branch, it was found confusing and did not express the fact
that you have to give `--detach` if you are naming the commit you
want to detach HEAD at with a branch name.

Separate this case into two syntactical forms, mimicking the way how
the DESCRIPTION section shows this usage.  Also update the text that
explains the syntax to name the commit to detach HEAD at to clarify.

Suggested-by: Benjamin Bergman <[email-masked]>
Signed-off-by: Junio C Hamano <[email-masked]>
---
 Documentation/git-checkout.txt | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt
index ca118ac..01d9b85 100644
--- a/Documentation/git-checkout.txt
+++ b/Documentation/git-checkout.txt
@@ -9,7 +9,8 @@ SYNOPSIS
 --------
 [verse]
 'git checkout' [-q] [-f] [-m] [<branch>]
-'git checkout' [-q] [-f] [-m] [--detach] [<commit>]
+'git checkout' [-q] [-f] [-m] --detach [<branch>]
+'git checkout' [-q] [-f] [-m] [--detach] <commit>
 'git checkout' [-q] [-f] [-m] [[-b|-B|--orphan] <new_branch>] [<start_point>]
 'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <paths>...
 'git checkout' [-p|--patch] [<tree-ish>] [--] [<paths>...]
@@ -62,7 +63,7 @@ that is to say, the branch is not reset/created unless "git checkout" is
 successful.
 
 'git checkout' --detach [<branch>]::
-'git checkout' <commit>::
+'git checkout' [--detach] <commit>::
 
 	Prepare to work on top of <commit>, by detaching HEAD at it
 	(see "DETACHED HEAD" section), and updating the index and the
@@ -71,10 +72,13 @@ successful.
 	tree will be the state recorded in the commit plus the local
 	modifications.
 +
-Passing `--detach` forces this behavior in the case of a <branch> (without
-the option, giving a branch name to the command would check out the branch,
-instead of detaching HEAD at it), or the current commit,
-if no <branch> is specified.
+Even though a branch name can be used to name a commit, you have to
+explicitly say `git checkout --detach <branch>` when you want to
+detach HEAD at the tip of the branch (`git checkout <branch>` will
+check out that branch without detaching HEAD).  Omitting <branch>,
+i.e. `git checkout --detach` detaches HEAD at the tip of the current
+branch.  When naming the commit in a form other than just a branch
+name, e.g. `master^0`, `HEAD~4`, `c2f3bf071e`, you can omit --detach.
 
 'git checkout' [-p|--patch] [<tree-ish>] [--] <pathspec>...::