git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC/PATCH] git checkout $tree path
@ 2011-09-29 22:46 Junio C Hamano
  2011-09-30  1:02 ` John Szakmeister
  2011-10-03 10:26 ` Jeff King
  0 siblings, 2 replies; 8+ messages in thread
From: Junio C Hamano @ 2011-09-29 22:46 UTC (permalink / raw)
  To: git

Suppose you have two branches, "master" with dir/file1 and file2, and
"next" with dir/file3 and file4. You are currently on "next" branch.

    $ rm dir/file3
    $ git status -suno
     D dir/file3

Now, what should "git checkout master dir" do?

Checking paths out of a tree is (currently) defined to:

 - Grab the paths from the named tree that match the given pathspec,
   and add them to the index; and then

 - Check out the contents from the index for paths that match the
   pathspec to the working tree;

 - While at it, if the given pathspec did not match anything, suspect
   a typo from the command line and error out without updating the index
   nor the working tree.

According to that definition, because "master" has dir/file1, and the
index is unchanged since "next", we would add dir/file1 to the index, and
then check dir/file1 and dir/file3 out of the index. Hence, we end up
resurrecting dir/file3 out of the index, even though "master" does not
have that path.

This is somewhat surprising.

It may make sense to tweak the semantics a little bit. We can grab the
paths out of the named tree ("master" in this case), update the index, and
update the working tree with only with these paths we grabbed from the
named tree. By doing so, we will keep the local modification to dir/file3
(in this case, the modification is to "delete", but the above observation
hold equally true if dir/file3 were modified).

An alternative semantics could be to first remove paths that match the
given pathspec from the index, then update the index with paths taken from
the named tree, and update the working tree. "git checkout master dir"
would then mean "replace anything currently in dir with whatever is in dir
in master". It is more dangerous, and it can easily emulated by doing:

    $ git rm -rf dir
    $ git checkout master dir

so I did not go that far with this patch.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---

 * This is a behaviour change, but it may qualify as a bugfix. I dunno.

 builtin/checkout.c |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/builtin/checkout.c b/builtin/checkout.c
index 5e356a6..75dbe76 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -71,7 +71,7 @@ static int update_some(const unsigned char *sha1, const char *base, int baselen,
 	hashcpy(ce->sha1, sha1);
 	memcpy(ce->name, base, baselen);
 	memcpy(ce->name + baselen, pathname, len - baselen);
-	ce->ce_flags = create_ce_flags(len, 0);
+	ce->ce_flags = create_ce_flags(len, 0) | CE_UPDATE;
 	ce->ce_mode = create_ce_mode(mode);
 	add_cache_entry(ce, ADD_CACHE_OK_TO_ADD | ADD_CACHE_OK_TO_REPLACE);
 	return 0;
@@ -228,6 +228,8 @@ static int checkout_paths(struct tree *source_tree, const char **pathspec,
 
 	for (pos = 0; pos < active_nr; pos++) {
 		struct cache_entry *ce = active_cache[pos];
+		if (source_tree && !(ce->ce_flags & CE_UPDATE))
+			continue;
 		match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, ps_matched);
 	}
 
@@ -266,6 +268,8 @@ static int checkout_paths(struct tree *source_tree, const char **pathspec,
 	state.refresh_cache = 1;
 	for (pos = 0; pos < active_nr; pos++) {
 		struct cache_entry *ce = active_cache[pos];
+		if (source_tree && !(ce->ce_flags & CE_UPDATE))
+			continue;
 		if (match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, NULL)) {
 			if (!ce_stage(ce)) {
 				errs |= checkout_entry(ce, &state, NULL);

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

end of thread, other threads:[~2011-10-05  2:07 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-09-29 22:46 [RFC/PATCH] git checkout $tree path Junio C Hamano
2011-09-30  1:02 ` John Szakmeister
2011-10-03 10:26 ` Jeff King
2011-10-03 16:08   ` Junio C Hamano
2011-10-04  7:42     ` Jeff King
2011-10-04 15:20       ` Junio C Hamano
2011-10-04 15:05   ` Jay Soffian
2011-10-05  2:07     ` Junio C Hamano

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