diff options
author | Junio C Hamano <gitster@pobox.com> | 2014-12-05 11:41:33 -0800 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2014-12-05 11:41:33 -0800 |
commit | c21df07886bb07a893609ff242e29b1493da1fd8 (patch) | |
tree | 7f76a3cc617ee737aac3dbd1e0fc7ad3c3347b68 | |
parent | 09d60d785c68c8fa65094ecbe46fbc2a38d0fc1f (diff) | |
parent | c5326bd62b7e168ba1339dacb7ee812d0fe98c7c (diff) | |
download | git-c21df07886bb07a893609ff242e29b1493da1fd8.tar.gz |
Merge branch 'jk/checkout-from-tree'
"git checkout $treeish $path", when $path in the index and the
working tree already matched what is in $treeish at the $path,
still overwrote the $path unnecessarily.
* jk/checkout-from-tree:
checkout $tree: do not throw away unchanged index entries
-rw-r--r-- | builtin/checkout.c | 18 | ||||
-rwxr-xr-x | t/t2022-checkout-paths.sh | 17 |
2 files changed, 35 insertions, 0 deletions
diff --git a/builtin/checkout.c b/builtin/checkout.c index 5410dacea0..5a78758036 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -67,6 +67,7 @@ static int update_some(const unsigned char *sha1, const char *base, int baselen, { int len; struct cache_entry *ce; + int pos; if (S_ISDIR(mode)) return READ_TREE_RECURSIVE; @@ -79,6 +80,23 @@ static int update_some(const unsigned char *sha1, const char *base, int baselen, ce->ce_flags = create_ce_flags(0) | CE_UPDATE; ce->ce_namelen = len; ce->ce_mode = create_ce_mode(mode); + + /* + * If the entry is the same as the current index, we can leave the old + * entry in place. Whether it is UPTODATE or not, checkout_entry will + * do the right thing. + */ + pos = cache_name_pos(ce->name, ce->ce_namelen); + if (pos >= 0) { + struct cache_entry *old = active_cache[pos]; + if (ce->ce_mode == old->ce_mode && + !hashcmp(ce->sha1, old->sha1)) { + old->ce_flags |= CE_UPDATE; + free(ce); + return 0; + } + } + add_cache_entry(ce, ADD_CACHE_OK_TO_ADD | ADD_CACHE_OK_TO_REPLACE); return 0; } diff --git a/t/t2022-checkout-paths.sh b/t/t2022-checkout-paths.sh index 8e3545d868..f46d0499bc 100755 --- a/t/t2022-checkout-paths.sh +++ b/t/t2022-checkout-paths.sh @@ -61,4 +61,21 @@ test_expect_success 'do not touch unmerged entries matching $path but not in $tr test_cmp expect.next0 actual.next0 ' +test_expect_success 'do not touch files that are already up-to-date' ' + git reset --hard && + echo one >file1 && + echo two >file2 && + git add file1 file2 && + git commit -m base && + echo modified >file1 && + test-chmtime =1000000000 file2 && + git update-index -q --refresh && + git checkout HEAD -- file1 file2 && + echo one >expect && + test_cmp expect file1 && + echo "1000000000 file2" >expect && + test-chmtime -v +0 file2 >actual && + test_cmp expect actual +' + test_done |