git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: git checkout branch behaves differently from what specified in man page
       [not found] <20110106154418.3348.29438.reportbug@localhost>
@ 2011-01-06 17:35 ` Jonathan Nieder
  2011-01-06 22:52   ` [PATCH/RFC] Documentation/checkout: explain behavior wrt local changes Jonathan Nieder
  0 siblings, 1 reply; 4+ messages in thread
From: Jonathan Nieder @ 2011-01-06 17:35 UTC (permalink / raw)
  To: r.ductor; +Cc: git

Hi,

r. ductor wrote[1]:

>  git checkout [<branch>], git checkout -b <new branch> [<start point>] 
>	This form switches branches by updating the index, working tree,
>	and HEAD to reflect the specified branch. "
>
> The key is the meaning of "to reflect": a normal (?) human being
> like me understands that git  checkout branch will reset the
> contents of working directory, and index exactly equal to that of
> the head of the branch.  As you might know this is not true (see
> example below).
[example with both unregistered and staged local modifications]

Yes, I agree that this could be a lot clearer.  For reference, here's
the current description section:

 Updates files in the working tree to match the version in the index
 or the specified tree. If no paths are given, git checkout will also
 update HEAD to set the specified branch as the current branch.

 git checkout [<branch>], git checkout -b|-B <new_branch> [<start point>]
	This form switches branches by updating the index, working tree,
	and HEAD to reflect the specified branch.

	If -b is given,
[... description of -b and -B ...]

 git checkout [--patch] [<tree-ish>] [--] <pathspec>...
	When <paths> or --patch are given, git checkout does not switch
	branches. It updates the named paths in the working tree from
	the index file or from a named <tree-ish> (most often a commit).
	In this case, the -b and --track options are meaningless and
	giving either of them results in an error. The <tree-ish>
	argument can be used to specify a specific tree-ish (i.e.
	commit, tag or tree) to update the index for the given paths
	before updating the working tree.

	The index may contain unmerged entries because of a previous
	failed merge.
[... more details about the unmerged entries case ...]

Proposed clearer text would be welcome, especially if in the form of
a patch to Documentation/git-checkout.txt (see Documentation/SubmittingPatches).

Currently I think the examples section explains it better.  The
details are something like this:

 - git checkout <branch> --

	tries to change the current branch to <branch>, dragging other
	state kicking and screaming along with it.

	- if a file does _not_ differ between the current commit and
	  <branch>, it does not need to be touched.  Any local changes
	  in that file will be preserved.

	- if a file that _does_ differ between the current commit and
	  <branch> has local changes, git gives up --- the operation is
	  cancelled and all state is preserved.
	  This behavior can be tweaked with the --merge option.

 - git checkout <tree> -- <path specifiers>

	keeping the current branch the same, grabs some files from <tree>
	to replace the current versions in the index and work tree

	- no matter what, the local state of the specified paths is
	  forgotten and both the index and worktree made to match <tree>

	- paths not specified are left alone.

If you just want to reset the worktree and index to match some
branch, then you can use

	git reset --hard <branch>

or

	git checkout <tree> -- .

.  The former even forgets what branch you were on (well, it is
remembered in the reflog).  The latter adopts the content of <tree>
as content registered for the next commit on the current branch.

Hope that helps,
Jonathan

[1] http://bugs.debian.org/609128

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

* [PATCH/RFC] Documentation/checkout: explain behavior wrt local changes
  2011-01-06 17:35 ` git checkout branch behaves differently from what specified in man page Jonathan Nieder
@ 2011-01-06 22:52   ` Jonathan Nieder
  2011-01-07  0:16     ` Junio C Hamano
  0 siblings, 1 reply; 4+ messages in thread
From: Jonathan Nieder @ 2011-01-06 22:52 UTC (permalink / raw)
  To: r.ductor; +Cc: git, Jeff King

Jonathan Nieder wrote:

> Proposed clearer text would be welcome, especially if in the form of
> a patch to Documentation/git-checkout.txt (see Documentation/SubmittingPatches).

Like this, maybe?

-- 8< --
Subject: Documentation/checkout: explain behavior wrt local changes

The current start of the description to "git checkout" tries to
combine an explanation of "git checkout <branch> --" with "git
checkout -- <paths>" and ends up with a muddle (as Jeff noticed).

In particular, the text does not make it obvious that the "git
checkout <branch> --" form does not clobber local changes relative
to the HEAD commit in the worktree and index.

Reported-by: r.ductor <r.ductor@gmail.com>
Helped-by: Jeff King <peff@peff.net>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
I somehow suspect that a mention of --merge would make this clearer
but good words for it aren't coming at the moment.  Improvements
welcome.

 Documentation/git-checkout.txt |   14 ++++++++------
 1 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt
index 22d3611..cfb71a8 100644
--- a/Documentation/git-checkout.txt
+++ b/Documentation/git-checkout.txt
@@ -15,16 +15,18 @@ SYNOPSIS
 
 DESCRIPTION
 -----------
-Updates files in the working tree to match the version in the index
-or the specified tree.  If no paths are given, 'git checkout' will
-also update `HEAD` to set the specified branch as the current
-branch.
+There are two different modes -- one to switch branches and one to
+make some paths in the work tree match the index or specified tree.
 
 'git checkout' [<branch>]::
 'git checkout' -b|-B <new_branch> [<start point>]::
 
-	This form switches branches by updating the index, working
-	tree, and HEAD to reflect the specified branch.
+	This form switches branches by changing `HEAD` and updating the
+	tracked files to the specified branch.  'git checkout' will
+	stop without doing anything if local changes overlap with
+	changes to the tracked files.  (Any local changes that do not
+	overlap with changes from `HEAD` to the specified branch will
+	be preserved.)
 +
 If `-b` is given, a new branch is created as if linkgit:git-branch[1]
 were called and then checked out; in this case you can
-- 
1.7.4.rc1

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

* Re: [PATCH/RFC] Documentation/checkout: explain behavior wrt local changes
  2011-01-06 22:52   ` [PATCH/RFC] Documentation/checkout: explain behavior wrt local changes Jonathan Nieder
@ 2011-01-07  0:16     ` Junio C Hamano
  2011-01-07 14:27       ` r.ductor
  0 siblings, 1 reply; 4+ messages in thread
From: Junio C Hamano @ 2011-01-07  0:16 UTC (permalink / raw)
  To: Jonathan Nieder; +Cc: r.ductor, git, Jeff King

Jonathan Nieder <jrnieder@gmail.com> writes:

>  'git checkout' [<branch>]::
>  'git checkout' -b|-B <new_branch> [<start point>]::
>  
> -	This form switches branches by updating the index, working
> -	tree, and HEAD to reflect the specified branch.
> +	This form switches branches by changing `HEAD` and updating the
> +	tracked files to the specified branch.  'git checkout' will
> +	stop without doing anything if local changes overlap with
> +	changes to the tracked files.  (Any local changes that do not
> +	overlap with changes from `HEAD` to the specified branch will
> +	be preserved.)

Even though I am fully aware that "switch" was an attempt to match the
terminology from another SCM (e.g. svn), it may help readers in the longer
term if we stop using "switch" and instead explain this as "checking out a
branch" and what this action is _for_.  I suspect that an explanation of
the purpose would clarify the reason why the command does what it does.

You check out a branch to work on that branch, namely, eventually to
commit changes to that branch (as opposed to committing them to the
current branch).  For that purpose, the local changes obviously need to be
preserved.  And that is why it refuses to act if paths with local changes
need to be updated.

Side note.  When you check out a path (or a set of paths), you don't work
on these files (git does not track individual files), hence there is no
possible interpretation other than "get a fresh unmodified copy out of
something" when the command is used with paths, i.e. "checking out paths
(either out of the index or out of a named commit)".

In any case, your rewrite is certainly an improvement compared to an
unexplained "reflect", so I think this is a step in the right direction.

Thanks.

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

* Re: [PATCH/RFC] Documentation/checkout: explain behavior wrt local changes
  2011-01-07  0:16     ` Junio C Hamano
@ 2011-01-07 14:27       ` r.ductor
  0 siblings, 0 replies; 4+ messages in thread
From: r.ductor @ 2011-01-07 14:27 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jonathan Nieder, git, Jeff King

Dear all

I'm a beginner git user trying to defend the beginners' party. Using Jonathan's explanations (and some educated guess on git behavior) I tried to concoct the man git-checkout documentation I would have liked to read, which is somewhat more explicit than Jonathan's patch. If you want to implement/improve it please double check it (and maybe warn me about my own errors). If you are happy about that I will try to send more suggestions. Thanks for your time and your work.

riccardo   

git checkout [<branch>]
git checkout -b|-B <new_branch> [<start point>]

     Tries to change the current HEAD to <branch> (or <start point>) and to safely update the working tree and the index.
     If there exist files having three distinct contents in the current commit, in the new branch and in the working tree, then the operation is canceled and all state is preserved.
     (This behavior may be changed with the option --merge.) If this is not the case, for all other files it acts as follows.  
       - Files not differing between the current commit and the new branch: their contents in the working tree (and eventually in the index) are left unchanged. 
       - Files in the current commit, unchanged or absent in the working tree, but not present in the new branch are removed from the working tree and from the index.
       - Files in the new branch but not in the current commit are added to the working tree and to the index (if they were already there they must have had the same contents by hypothesis).
       - Files in the working tree or in the index that are absent in the current commit and in the new branch are left unchanged.
    
    If -b is given, ...



On Friday 07 January 2011 01:16:25 Junio C Hamano wrote:
> Jonathan Nieder <jrnieder@gmail.com> writes:
> 
> >  'git checkout' [<branch>]::
> >  'git checkout' -b|-B <new_branch> [<start point>]::
> >  
> > -	This form switches branches by updating the index, working
> > -	tree, and HEAD to reflect the specified branch.
> > +	This form switches branches by changing `HEAD` and updating the
> > +	tracked files to the specified branch.  'git checkout' will
> > +	stop without doing anything if local changes overlap with
> > +	changes to the tracked files.  (Any local changes that do not
> > +	overlap with changes from `HEAD` to the specified branch will
> > +	be preserved.)
> 

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

end of thread, other threads:[~2011-01-07 15:26 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <20110106154418.3348.29438.reportbug@localhost>
2011-01-06 17:35 ` git checkout branch behaves differently from what specified in man page Jonathan Nieder
2011-01-06 22:52   ` [PATCH/RFC] Documentation/checkout: explain behavior wrt local changes Jonathan Nieder
2011-01-07  0:16     ` Junio C Hamano
2011-01-07 14:27       ` r.ductor

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).