Skip to content
/ git Public
forked from git/git

Commit c21df07

Browse files
committed
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
2 parents 09d60d7 + c5326bd commit c21df07

File tree

2 files changed

+35
-0
lines changed

2 files changed

+35
-0
lines changed

builtin/checkout.c

+18
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ static int update_some(const unsigned char *sha1, const char *base, int baselen,
6767
{
6868
int len;
6969
struct cache_entry *ce;
70+
int pos;
7071

7172
if (S_ISDIR(mode))
7273
return READ_TREE_RECURSIVE;
@@ -79,6 +80,23 @@ static int update_some(const unsigned char *sha1, const char *base, int baselen,
7980
ce->ce_flags = create_ce_flags(0) | CE_UPDATE;
8081
ce->ce_namelen = len;
8182
ce->ce_mode = create_ce_mode(mode);
83+
84+
/*
85+
* If the entry is the same as the current index, we can leave the old
86+
* entry in place. Whether it is UPTODATE or not, checkout_entry will
87+
* do the right thing.
88+
*/
89+
pos = cache_name_pos(ce->name, ce->ce_namelen);
90+
if (pos >= 0) {
91+
struct cache_entry *old = active_cache[pos];
92+
if (ce->ce_mode == old->ce_mode &&
93+
!hashcmp(ce->sha1, old->sha1)) {
94+
old->ce_flags |= CE_UPDATE;
95+
free(ce);
96+
return 0;
97+
}
98+
}
99+
82100
add_cache_entry(ce, ADD_CACHE_OK_TO_ADD | ADD_CACHE_OK_TO_REPLACE);
83101
return 0;
84102
}

t/t2022-checkout-paths.sh

+17
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,21 @@ test_expect_success 'do not touch unmerged entries matching $path but not in $tr
6161
test_cmp expect.next0 actual.next0
6262
'
6363

64+
test_expect_success 'do not touch files that are already up-to-date' '
65+
git reset --hard &&
66+
echo one >file1 &&
67+
echo two >file2 &&
68+
git add file1 file2 &&
69+
git commit -m base &&
70+
echo modified >file1 &&
71+
test-chmtime =1000000000 file2 &&
72+
git update-index -q --refresh &&
73+
git checkout HEAD -- file1 file2 &&
74+
echo one >expect &&
75+
test_cmp expect file1 &&
76+
echo "1000000000 file2" >expect &&
77+
test-chmtime -v +0 file2 >actual &&
78+
test_cmp expect actual
79+
'
80+
6481
test_done

0 commit comments

Comments
 (0)