cache-tree: Write updated cache-tree after commit
During the commit process, update the cache-tree. Write this updated cache-tree so that it's ready for subsequent commands. Add test code which demonstrates that git commit now writes the cache tree. Make all tests test the entire cache-tree, not just the root level. Signed-off-by: David Turner <dturner@twitter.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
David Turner committed
Jul 13, 2014 at 13:28 UTC
9c4d6c0297b7d6167bf330853139b0515b351b89
2 files changed
+119
-16
builtin/commit.c
+17
-1
@@ -342,6 +342,17 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,
342
343
discard_cache();
344
read_cache_from(index_lock.filename);
345
+ if (update_main_cache_tree(WRITE_TREE_SILENT) == 0) {
346
+ fd = open(index_lock.filename, O_WRONLY);
347
+ if (fd >= 0)
348
+ if (write_cache(fd, active_cache, active_nr) < 0)
349
+ die(_("unable to write index file"));
350
+ else
351
+ close_lock_file(&index_lock);
352
+ else
353
+ die(_("unable to write index file"));
354
+ } else
355
+ warning(_("Failed to update main cache tree"));
356
357
commit_style = COMMIT_NORMAL;
358
return index_lock.filename;
@@ -383,8 +394,12 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,
394
if (!only && !pathspec.nr) {
395
fd = hold_locked_index(&index_lock, 1);
396
refresh_cache_or_die(refresh_flags);
386
- if (active_cache_changed) {
397
+ if (active_cache_changed
398
+ || !cache_tree_fully_valid(active_cache_tree)) {
399
update_main_cache_tree(WRITE_TREE_SILENT);
400
+ active_cache_changed = 1;
401
+ }
402
+ if (active_cache_changed) {
403
if (write_cache(fd, active_cache, active_nr) ||
404
commit_locked_index(&index_lock))
405
die(_("unable to write new_index file"));
@@ -435,6 +450,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,
450
fd = hold_locked_index(&index_lock, 1);
451
add_remove_files(&partial);
452
refresh_cache(REFRESH_QUIET);
453
+ update_main_cache_tree(WRITE_TREE_SILENT);
454
if (write_cache(fd, active_cache, active_nr) ||
455
close_lock_file(&index_lock))
456
die(_("unable to write new_index file"));
t/t0090-cache-tree.sh
+102
-15
@@ -8,7 +8,7 @@ cache-tree extension.
8
. ./test-lib.sh
9
10
cmp_cache_tree () {
11
- test-dump-cache-tree >actual &&
11
+ test-dump-cache-tree | sed -e '/#(ref)/d' >actual &&
12
sed "s/$_x40/SHA/" <actual >filtered &&
13
test_cmp "$1" filtered
14
}
@@ -16,14 +16,38 @@ cmp_cache_tree () {
16
# We don't bother with actually checking the SHA1:
17
# test-dump-cache-tree already verifies that all existing data is
18
# correct.
19
-test_shallow_cache_tree () {
20
- printf "SHA (%d entries, 0 subtrees)\n" $(git ls-files|wc -l) >expect &&
19
+generate_expected_cache_tree_rec () {
20
+ dir="$1${1:+/}" &&
21
+ parent="$2" &&
22
+ # ls-files might have foo/bar, foo/bar/baz, and foo/bar/quux
23
+ # We want to count only foo because it's the only direct child
24
+ subtrees=$(git ls-files|grep /|cut -d / -f 1|uniq) &&
25
+ subtree_count=$(echo "$subtrees"|awk '$1 {++c} END {print c}') &&
26
+ entries=$(git ls-files|wc -l) &&
27
+ printf "SHA $dir (%d entries, %d subtrees)\n" "$entries" "$subtree_count" &&
28
+ for subtree in $subtrees
29
+ do
30
+ cd "$subtree"
31
+ generate_expected_cache_tree_rec "$dir$subtree" "$dir" || return 1
32
+ cd ..
33
+ done &&
34
+ dir=$parent
35
+}
36
+
37
+generate_expected_cache_tree () {
38
+ (
39
+ generate_expected_cache_tree_rec
40
+ )
41
+}
42
+
43
+test_cache_tree () {
44
+ generate_expected_cache_tree >expect &&
45
cmp_cache_tree expect
46
}
47
48
test_invalid_cache_tree () {
49
printf "invalid %s ()\n" "" "$@" >expect &&
26
- test-dump-cache-tree | \
50
+ test-dump-cache-tree |
51
sed -n -e "s/[0-9]* subtrees//" -e '/#(ref)/d' -e '/^invalid /p' >actual &&
52
test_cmp expect actual
53
}
@@ -33,14 +57,14 @@ test_no_cache_tree () {
57
cmp_cache_tree expect
58
}
59
36
-test_expect_failure 'initial commit has cache-tree' '
60
+test_expect_success 'initial commit has cache-tree' '
61
test_commit foo &&
38
- test_shallow_cache_tree
62
+ test_cache_tree
63
'
64
65
test_expect_success 'read-tree HEAD establishes cache-tree' '
66
git read-tree HEAD &&
43
- test_shallow_cache_tree
67
+ test_cache_tree
68
'
69
70
test_expect_success 'git-add invalidates cache-tree' '
@@ -58,6 +82,18 @@ test_expect_success 'git-add in subdir invalidates cache-tree' '
82
test_invalid_cache_tree
83
'
84
85
+cat >before <<\EOF
86
+SHA (3 entries, 2 subtrees)
87
+SHA dir1/ (1 entries, 0 subtrees)
88
+SHA dir2/ (1 entries, 0 subtrees)
89
+EOF
90
+
91
+cat >expect <<\EOF
92
+invalid (2 subtrees)
93
+invalid dir1/ (0 subtrees)
94
+SHA dir2/ (1 entries, 0 subtrees)
95
+EOF
96
+
97
test_expect_success 'git-add in subdir does not invalidate sibling cache-tree' '
98
git tag no-children &&
99
test_when_finished "git reset --hard no-children; git read-tree HEAD" &&
@@ -65,8 +101,10 @@ test_expect_success 'git-add in subdir does not invalidate sibling cache-tree' '
101
test_commit dir1/a &&
102
test_commit dir2/b &&
103
echo "I changed this file" >dir1/a &&
104
+ cmp_cache_tree before &&
105
+ echo "I changed this file" >dir1/a &&
106
git add dir1/a &&
69
- test_invalid_cache_tree dir1/
107
+ cmp_cache_tree expect
108
'
109
110
test_expect_success 'update-index invalidates cache-tree' '
@@ -79,7 +117,7 @@ test_expect_success 'update-index invalidates cache-tree' '
117
test_expect_success 'write-tree establishes cache-tree' '
118
test-scrap-cache-tree &&
119
git write-tree &&
82
- test_shallow_cache_tree
120
+ test_cache_tree
121
'
122
123
test_expect_success 'test-scrap-cache-tree works' '
@@ -90,37 +128,86 @@ test_expect_success 'test-scrap-cache-tree works' '
128
129
test_expect_success 'second commit has cache-tree' '
130
test_commit bar &&
93
- test_shallow_cache_tree
131
+ test_cache_tree
132
+'
133
+
134
+test_expect_success 'commit --interactive gives cache-tree on partial commit' '
135
+ cat <<-\EOT >foo.c &&
136
+ int foo()
137
+ {
138
+ return 42;
139
+ }
140
+ int bar()
141
+ {
142
+ return 42;
143
+ }
144
+ EOT
145
+ git add foo.c &&
146
+ test_invalid_cache_tree &&
147
+ git commit -m "add a file" &&
148
+ test_cache_tree &&
149
+ cat <<-\EOT >foo.c &&
150
+ int foo()
151
+ {
152
+ return 43;
153
+ }
154
+ int bar()
155
+ {
156
+ return 44;
157
+ }
158
+ EOT
159
+ (echo p; echo 1; echo; echo s; echo n; echo y; echo q) |
160
+ git commit --interactive -m foo &&
161
+ test_cache_tree
162
+'
163
+
164
+test_expect_success 'commit in child dir has cache-tree' '
165
+ mkdir dir &&
166
+ >dir/child.t &&
167
+ git add dir/child.t &&
168
+ git commit -m dir/child.t &&
169
+ test_cache_tree
170
'
171
172
test_expect_success 'reset --hard gives cache-tree' '
173
test-scrap-cache-tree &&
174
git reset --hard &&
99
- test_shallow_cache_tree
175
+ test_cache_tree
176
'
177
178
test_expect_success 'reset --hard without index gives cache-tree' '
179
rm -f .git/index &&
180
git reset --hard &&
105
- test_shallow_cache_tree
181
+ test_cache_tree
182
'
183
184
test_expect_success 'checkout gives cache-tree' '
185
git tag current &&
186
git checkout HEAD^ &&
111
- test_shallow_cache_tree
187
+ test_cache_tree
188
'
189
190
test_expect_success 'checkout -b gives cache-tree' '
191
git checkout current &&
192
git checkout -b prev HEAD^ &&
117
- test_shallow_cache_tree
193
+ test_cache_tree
194
'
195
196
test_expect_success 'checkout -B gives cache-tree' '
197
git checkout current &&
198
git checkout -B prev HEAD^ &&
123
- test_shallow_cache_tree
199
+ test_cache_tree
200
+'
201
+
202
+test_expect_success 'partial commit gives cache-tree' '
203
+ git checkout -b partial no-children &&
204
+ test_commit one &&
205
+ test_commit two &&
206
+ echo "some change" >one.t &&
207
+ git add one.t &&
208
+ echo "some other change" >two.t &&
209
+ git commit two.t -m partial &&
210
+ test_cache_tree
211
'
212
213
test_done