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]

Reply via email to