Skip to content

Commit 348d4f2

Browse files
peffgitster
authored andcommitted
filter-branch: skip index read/write when possible
If the user specifies an index filter but not a tree filter, filter-branch cleverly avoids checking out the tree entirely. But we don't do the next level of optimization: if you have no index or tree filter, we do not need to read the index at all. This can greatly speed up cases where we are only changing the commit objects (e.g., cementing a graft into place). Here are numbers from the newly-added perf test: Test HEAD^ HEAD --------------------------------------------------------------- 7000.2: noop filter 13.81(4.95+0.83) 5.43(0.42+0.43) -60.7% Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent f34be46 commit 348d4f2

File tree

2 files changed

+40
-2
lines changed

2 files changed

+40
-2
lines changed

git-filter-branch.sh

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,14 +306,26 @@ then
306306
start_timestamp=$(date '+%s')
307307
fi
308308

309+
if test -n "$filter_index" ||
310+
test -n "$filter_tree" ||
311+
test -n "$filter_subdir"
312+
then
313+
need_index=t
314+
else
315+
need_index=
316+
fi
317+
309318
while read commit parents; do
310319
git_filter_branch__commit_count=$(($git_filter_branch__commit_count+1))
311320

312321
report_progress
313322

314323
case "$filter_subdir" in
315324
"")
316-
GIT_ALLOW_NULL_SHA1=1 git read-tree -i -m $commit
325+
if test -n "$need_index"
326+
then
327+
GIT_ALLOW_NULL_SHA1=1 git read-tree -i -m $commit
328+
fi
317329
;;
318330
*)
319331
# The commit may not have the subdirectory at all
@@ -387,8 +399,15 @@ while read commit parents; do
387399
} <../commit |
388400
eval "$filter_msg" > ../message ||
389401
die "msg filter failed: $filter_msg"
402+
403+
if test -n "$need_index"
404+
then
405+
tree=$(git write-tree)
406+
else
407+
tree="$commit^{tree}"
408+
fi
390409
workdir=$workdir @SHELL_PATH@ -c "$filter_commit" "git commit-tree" \
391-
$(git write-tree) $parentstr < ../message > ../map/$commit ||
410+
"$tree" $parentstr < ../message > ../map/$commit ||
392411
die "could not write rewritten commit"
393412
done <../revs
394413

t/perf/p7000-filter-branch.sh

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/bin/sh
2+
3+
test_description='performance of filter-branch'
4+
. ./perf-lib.sh
5+
6+
test_perf_default_repo
7+
test_checkout_worktree
8+
9+
test_expect_success 'mark bases for tests' '
10+
git tag -f tip &&
11+
git tag -f base HEAD~100
12+
'
13+
14+
test_perf 'noop filter' '
15+
git checkout --detach tip &&
16+
git filter-branch -f base..HEAD
17+
'
18+
19+
test_done

0 commit comments

Comments
 (0)