tags 583685 + upstream
severity 583685 wishlist
quit
Frédéric Brière wrote:
> git-filter-branch always calls git-read-tree for each commit, even when
> no modifications to the index are performed. Admittedly, read-tree is
> not as costly an operation as checkout-index, but on a big repo, it is
> not free either.
How about something like this (warning: untested)?
diff --git a/git-filter-branch.sh b/git-filter-branch.sh
index 88fb0f0..3a303c7 100755
--- a/git-filter-branch.sh
+++ b/git-filter-branch.sh
@@ -287,11 +287,7 @@ test $commits -eq 0 && die "Found nothing to rewrite"
# Rewrite the commits
-git_filter_branch__commit_count=0
-while read commit parents; do
- git_filter_branch__commit_count=$(($git_filter_branch__commit_count+1))
- printf "\rRewrite $commit ($git_filter_branch__commit_count/$commits)"
-
+get_rewritten_tree () {
case "$filter_subdir" in
"")
git read-tree -i -m $commit
@@ -309,18 +305,6 @@ while read commit parents; do
}
esac || die "Could not initialize the index"
- GIT_COMMIT=$commit
- export GIT_COMMIT
- git cat-file commit "$commit" >../commit ||
- die "Cannot read commit $commit"
-
- eval "$(set_ident AUTHOR <../commit)" ||
- die "setting author failed for commit $commit"
- eval "$(set_ident COMMITTER <../commit)" ||
- die "setting committer failed for commit $commit"
- eval "$filter_env" < /dev/null ||
- die "env filter failed: $filter_env"
-
if [ "$filter_tree" ]; then
git checkout-index -f -u -a ||
die "Could not checkout the index"
@@ -341,6 +325,35 @@ while read commit parents; do
eval "$filter_index" < /dev/null ||
die "index filter failed: $filter_index"
+ tree="$(git write-tree)"
+}
+
+git_filter_branch__commit_count=0
+while read commit parents; do
+ git_filter_branch__commit_count=$(($git_filter_branch__commit_count+1))
+ printf "\rRewrite $commit ($git_filter_branch__commit_count/$commits)"
+
+ GIT_COMMIT=$commit
+ export GIT_COMMIT
+ git cat-file commit "$commit" >../commit ||
+ die "Cannot read commit $commit"
+
+ eval "$(set_ident AUTHOR <../commit)" ||
+ die "setting author failed for commit $commit"
+ eval "$(set_ident COMMITTER <../commit)" ||
+ die "setting committer failed for commit $commit"
+ eval "$filter_env" < /dev/null ||
+ die "env filter failed: $filter_env"
+
+ tree=
+ if test -z "$filter_subdir$filter_tree$filter_index"
+ then
+ tree=$(git rev-parse "$commit^{tree}") ||
+ die "cannot read tree for commit $commit"
+ else
+ get_rewritten_tree
+ fi
+
parentstr=
for parent in $parents; do
for reparent in $(map "$parent"); do
@@ -356,7 +369,7 @@ while read commit parents; do
eval "$filter_msg" > ../message ||
die "msg filter failed: $filter_msg"
@SHELL_PATH@ -c "$filter_commit" "git commit-tree" \
- $(git write-tree) $parentstr < ../message > ../map/$commit ||
+ $tree $parentstr < ../message > ../map/$commit ||
die "could not write rewritten commit"
done <../revs
--
--
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]