diff options
author | Junio C Hamano <gitster@pobox.com> | 2011-10-17 21:37:09 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2011-10-17 21:37:09 -0700 |
commit | 66d2c22f416cda652f08e8db5820abf3e87592e5 (patch) | |
tree | ad4e5e2e38eec22aa6cb769e5d2d1dd896b19629 | |
parent | Merge branch 'js/bisect-no-checkout' (diff) | |
parent | checkout $tree $path: do not clobber local changes in $path not in $tree (diff) | |
download | tgif-66d2c22f416cda652f08e8db5820abf3e87592e5.tar.xz |
Merge branch 'jc/checkout-from-tree-keep-local-changes'
* jc/checkout-from-tree-keep-local-changes:
checkout $tree $path: do not clobber local changes in $path not in $tree
-rw-r--r-- | builtin/checkout.c | 6 | ||||
-rwxr-xr-x | t/t2022-checkout-paths.sh | 42 |
2 files changed, 47 insertions, 1 deletions
diff --git a/builtin/checkout.c b/builtin/checkout.c index 49a547a0d5..2a80772425 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -72,7 +72,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; @@ -229,6 +229,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); } @@ -267,6 +269,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); diff --git a/t/t2022-checkout-paths.sh b/t/t2022-checkout-paths.sh new file mode 100755 index 0000000000..56090d2eba --- /dev/null +++ b/t/t2022-checkout-paths.sh @@ -0,0 +1,42 @@ +#!/bin/sh + +test_description='checkout $tree -- $paths' +. ./test-lib.sh + +test_expect_success setup ' + mkdir dir && + >dir/master && + echo common >dir/common && + git add dir/master dir/common && + test_tick && git commit -m "master has dir/master" && + git checkout -b next && + git mv dir/master dir/next0 && + echo next >dir/next1 && + git add dir && + test_tick && git commit -m "next has dir/next but not dir/master" +' + +test_expect_success 'checking out paths out of a tree does not clobber unrelated paths' ' + git checkout next && + git reset --hard && + rm dir/next0 && + cat dir/common >expect.common && + echo modified >expect.next1 && + cat expect.next1 >dir/next1 && + echo untracked >expect.next2 && + cat expect.next2 >dir/next2 && + + git checkout master dir && + + test_cmp expect.common dir/common && + test_path_is_file dir/master && + git diff --exit-code master dir/master && + + test_path_is_missing dir/next0 && + test_cmp expect.next1 dir/next1 && + test_path_is_file dir/next2 && + test_must_fail git ls-files --error-unmatch dir/next2 && + test_cmp expect.next2 dir/next2 +' + +test_done |