@matheusbsbs / matheus-bagliano / commits / 5203083694
Fork 0

Teach Git to respect skip-worktree bit (writing part)

This part is mainly to remove CE_VALID shortcuts (and as a consequence, ce_uptodate() shortcuts as it may be turned on by CE_VALID) in writing code path if skip-worktree is used. Various tests are added to avoid future breakages. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nguyễn Thái Ngọc Duy committed Aug 20, 2009 at 20:46 UTC 52030836943c0d28d8be4202762ede28e921dc21
2 files changed +148 -2
t/t7012-skip-worktree-writing.sh new
+146
@@ -0,0 +1,146 @@
1 +#!/bin/sh
2 +#
3 +# Copyright (c) 2008 Nguyễn Thái Ngọc Duy
4 +#
5 +
6 +test_description='test worktree writing operations when skip-worktree is used'
7 +
8 +. ./test-lib.sh
9 +
10 +test_expect_success 'setup' '
11 + test_commit init &&
12 + echo modified >> init.t &&
13 + touch added &&
14 + git add init.t added &&
15 + git commit -m "modified and added" &&
16 + git tag top
17 +'
18 +
19 +test_expect_success 'read-tree updates worktree, absent case' '
20 + git checkout -f top &&
21 + git update-index --skip-worktree init.t &&
22 + rm init.t &&
23 + git read-tree -m -u HEAD^ &&
24 + echo init > expected &&
25 + test_cmp expected init.t
26 +'
27 +
28 +test_expect_success 'read-tree updates worktree, dirty case' '
29 + git checkout -f top &&
30 + git update-index --skip-worktree init.t &&
31 + echo dirty >> init.t &&
32 + test_must_fail git read-tree -m -u HEAD^ &&
33 + grep -q dirty init.t &&
34 + test "$(git ls-files -t init.t)" = "S init.t" &&
35 + git update-index --no-skip-worktree init.t
36 +'
37 +
38 +test_expect_success 'read-tree removes worktree, absent case' '
39 + git checkout -f top &&
40 + git update-index --skip-worktree added &&
41 + rm added &&
42 + git read-tree -m -u HEAD^ &&
43 + test ! -f added
44 +'
45 +
46 +test_expect_success 'read-tree removes worktree, dirty case' '
47 + git checkout -f top &&
48 + git update-index --skip-worktree added &&
49 + echo dirty >> added &&
50 + test_must_fail git read-tree -m -u HEAD^ &&
51 + grep -q dirty added &&
52 + test "$(git ls-files -t added)" = "S added" &&
53 + git update-index --no-skip-worktree added
54 +'
55 +
56 +NULL_SHA1=e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
57 +ZERO_SHA0=0000000000000000000000000000000000000000
58 +setup_absent() {
59 + test -f 1 && rm 1
60 + git update-index --remove 1 &&
61 + git update-index --add --cacheinfo 100644 $NULL_SHA1 1 &&
62 + git update-index --skip-worktree 1
63 +}
64 +
65 +test_absent() {
66 + echo "100644 $NULL_SHA1 0 1" > expected &&
67 + git ls-files --stage 1 > result &&
68 + test_cmp expected result &&
69 + test ! -f 1
70 +}
71 +
72 +setup_dirty() {
73 + git update-index --force-remove 1 &&
74 + echo dirty > 1 &&
75 + git update-index --add --cacheinfo 100644 $NULL_SHA1 1 &&
76 + git update-index --skip-worktree 1
77 +}
78 +
79 +test_dirty() {
80 + echo "100644 $NULL_SHA1 0 1" > expected &&
81 + git ls-files --stage 1 > result &&
82 + test_cmp expected result &&
83 + echo dirty > expected
84 + test_cmp expected 1
85 +}
86 +
87 +cat >expected <<EOF
88 +S 1
89 +H 2
90 +H init.t
91 +S sub/1
92 +H sub/2
93 +EOF
94 +
95 +test_expect_success 'index setup' '
96 + git checkout -f init &&
97 + mkdir sub &&
98 + touch ./1 ./2 sub/1 sub/2 &&
99 + git add 1 2 sub/1 sub/2 &&
100 + git update-index --skip-worktree 1 sub/1 &&
101 + git ls-files -t > result &&
102 + test_cmp expected result
103 +'
104 +
105 +test_expect_success 'git-add ignores worktree content' '
106 + setup_absent &&
107 + git add 1 &&
108 + test_absent
109 +'
110 +
111 +test_expect_success 'git-add ignores worktree content' '
112 + setup_dirty &&
113 + git add 1 &&
114 + test_dirty
115 +'
116 +
117 +test_expect_success 'git-rm fails if worktree is dirty' '
118 + setup_dirty &&
119 + test_must_fail git rm 1 &&
120 + test_dirty
121 +'
122 +
123 +cat >expected <<EOF
124 +Would remove expected
125 +Would remove result
126 +EOF
127 +test_expect_success 'git-clean, absent case' '
128 + setup_absent &&
129 + git clean -n > result &&
130 + test_cmp expected result
131 +'
132 +
133 +test_expect_success 'git-clean, dirty case' '
134 + setup_dirty &&
135 + git clean -n > result &&
136 + test_cmp expected result
137 +'
138 +
139 +test_expect_failure 'git-apply adds file' false
140 +test_expect_failure 'git-apply updates file' false
141 +test_expect_failure 'git-apply removes file' false
142 +test_expect_failure 'git-mv to skip-worktree' false
143 +test_expect_failure 'git-mv from skip-worktree' false
144 +test_expect_failure 'git-checkout' false
145 +
146 +test_done
unpack-trees.c
+2 -2
@@ -450,7 +450,7 @@ static int verify_uptodate(struct cache_entry *ce,
450 {
451 struct stat st;
452
453 - if (o->index_only || o->reset || ce_uptodate(ce))
453 + if (o->index_only || (!ce_skip_worktree(ce) && (o->reset || ce_uptodate(ce))))
454 return 0;
455
456 if (!lstat(ce->name, &st)) {
@@ -1004,7 +1004,7 @@ int oneway_merge(struct cache_entry **src, struct unpack_trees_options *o)
1004
1005 if (old && same(old, a)) {
1006 int update = 0;
1007 - if (o->reset && !ce_uptodate(old)) {
1007 + if (o->reset && !ce_uptodate(old) && !ce_skip_worktree(old)) {
1008 struct stat st;
1009 if (lstat(old->name, &st) ||
1010 ie_match_stat(o->src_index, old, &st, CE_MATCH_IGNORE_VALID))