Skip to content

Commit dc5d40f

Browse files
vdyettaylorr
authored andcommitted
read-tree: use 'skip_cache_tree_update' option
When running 'read-tree' with a single tree and no prefix, 'prime_cache_tree()' is called after the tree is unpacked. In that situation, skip a redundant call to 'cache_tree_update()' in 'unpack_trees()' by enabling the 'skip_cache_tree_update' unpack option. Removing the redundant cache tree update provides a substantial performance improvement to 'git read-tree <tree-ish>', as shown by a test added to 'p0006-read-tree-checkout.sh': Test before after ---------------------------------------------------------------------- read-tree br_ballast_plus_1 3.94(1.80+1.57) 3.00(1.14+1.28) -23.9% Note that the 'read-tree' in 't1022-read-tree-partial-clone.sh' is updated to read two trees, rather than one. The test was first introduced in d3da223 (cache-tree: prefetch in partial clone read-tree, 2021-07-23) to exercise the 'cache_tree_update()' code path, as used in 'git merge'. Since this patch drops the call to 'cache_tree_update()' in single-tree 'git read-tree', change the test to use the two-tree variant so that 'cache_tree_update()' is called as intended. Signed-off-by: Victoria Dye <[email protected]> Signed-off-by: Taylor Blau <[email protected]>
1 parent 0e47bca commit dc5d40f

File tree

3 files changed

+13
-1
lines changed

3 files changed

+13
-1
lines changed

builtin/read-tree.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,10 @@ int cmd_read_tree(int argc, const char **argv, const char *cmd_prefix)
249249
if (opts.debug_unpack)
250250
opts.fn = debug_merge;
251251

252+
/* If we're going to prime_cache_tree later, skip cache tree update */
253+
if (nr_trees == 1 && !opts.prefix)
254+
opts.skip_cache_tree_update = 1;
255+
252256
cache_tree_free(&active_cache_tree);
253257
for (i = 0; i < nr_trees; i++) {
254258
struct tree *tree = trees[i];

t/perf/p0006-read-tree-checkout.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,14 @@ test_perf "read-tree br_base br_ballast ($nr_files)" '
4949
git read-tree -n -m br_base br_ballast
5050
'
5151

52+
test_perf "read-tree br_ballast_plus_1 ($nr_files)" '
53+
# Run read-tree 100 times for clearer performance results & comparisons
54+
for i in $(test_seq 100)
55+
do
56+
git read-tree -n -m br_ballast_plus_1 || return 1
57+
done
58+
'
59+
5260
test_perf "switch between br_base br_ballast ($nr_files)" '
5361
git checkout -q br_base &&
5462
git checkout -q br_ballast

t/t1022-read-tree-partial-clone.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ test_expect_success 'read-tree in partial clone prefetches in one batch' '
1919
git -C server config uploadpack.allowfilter 1 &&
2020
git -C server config uploadpack.allowanysha1inwant 1 &&
2121
git clone --bare --filter=blob:none "file://$(pwd)/server" client &&
22-
GIT_TRACE_PACKET="$(pwd)/trace" git -C client read-tree $TREE &&
22+
GIT_TRACE_PACKET="$(pwd)/trace" git -C client read-tree $TREE $TREE &&
2323
2424
# "done" marks the end of negotiation (once per fetch). Expect that
2525
# only one fetch occurs.

0 commit comments

Comments
 (0)