Merge branch 'master' of git://people.freedesktop.org/~hausmann/git-p4
[gitweb.git] / git-filter-branch.sh
old mode 100644 (file)
new mode 100755 (executable)
index 22fb5bf..0d000ed
@@ -8,16 +8,32 @@
 # a new branch. You can specify a number of filters to modify the commits,
 # files and trees.
 
-set -e
-
 USAGE="git-filter-branch [-d TEMPDIR] [FILTERS] DESTBRANCH [REV-RANGE]"
 . git-sh-setup
 
+warn () {
+        echo "$*" >&2
+}
+
 map()
 {
        # if it was not rewritten, take the original
-       test -r "$workdir/../map/$1" || echo "$1"
-       cat "$workdir/../map/$1"
+       if test -r "$workdir/../map/$1"
+       then
+               cat "$workdir/../map/$1"
+       else
+               echo "$1"
+       fi
+}
+
+# override die(): this version puts in an extra line break, so that
+# the progress is still visible
+
+die()
+{
+       echo >&2
+       echo "$*" >&2
+       exit 1
 }
 
 # When piped a commit, output a script to set the ident of either
@@ -123,9 +139,10 @@ git show-ref "refs/heads/$dstbranch" 2> /dev/null &&
        die "branch $dstbranch already exists"
 
 test ! -e "$tempdir" || die "$tempdir already exists, please remove it"
-mkdir -p "$tempdir/t"
-cd "$tempdir/t"
-workdir="$(pwd)"
+mkdir -p "$tempdir/t" &&
+cd "$tempdir/t" &&
+workdir="$(pwd)" ||
+die ""
 
 case "$GIT_DIR" in
 /*)
@@ -137,12 +154,12 @@ esac
 export GIT_DIR GIT_WORK_TREE=.
 
 export GIT_INDEX_FILE="$(pwd)/../index"
-git read-tree # seed the index file
+git read-tree || die "Could not seed the index"
 
 ret=0
 
-
-mkdir ../map # map old->new commit ids for rewriting parents
+# map old->new commit ids for rewriting parents
+mkdir ../map || die "Could not create map/ directory"
 
 case "$filter_subdir" in
 "")
@@ -152,15 +169,15 @@ case "$filter_subdir" in
 *)
        git rev-list --reverse --topo-order --default HEAD \
                --parents --full-history "$@" -- "$filter_subdir"
-esac > ../revs
-commits=$(cat ../revs | wc -l | tr -d " ")
+esac > ../revs || die "Could not get the commits"
+commits=$(wc -l <../revs | tr -d " ")
 
 test $commits -eq 0 && die "Found nothing to rewrite"
 
 i=0
 while read commit parents; do
        i=$(($i+1))
-       printf "$commit ($i/$commits) "
+       printf "\rRewrite $commit ($i/$commits)"
 
        case "$filter_subdir" in
        "")
@@ -168,28 +185,36 @@ while read commit parents; do
                ;;
        *)
                git read-tree -i -m $commit:"$filter_subdir"
-       esac
+       esac || die "Could not initialize the index"
 
        export GIT_COMMIT=$commit
-       git cat-file commit "$commit" >../commit
+       git cat-file commit "$commit" >../commit ||
+               die "Cannot read commit $commit"
 
-       eval "$(set_ident AUTHOR <../commit)"
-       eval "$(set_ident COMMITTER <../commit)"
-       eval "$filter_env" < /dev/null
+       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
+               git checkout-index -f -u -a ||
+                       die "Could not checkout the index"
                # files that $commit removed are now still in the working tree;
                # remove them, else they would be added again
                git ls-files -z --others | xargs -0 rm -f
-               eval "$filter_tree" < /dev/null
+               eval "$filter_tree" < /dev/null ||
+                       die "tree filter failed: $filter_tree"
+
                git diff-index -r $commit | cut -f 2- | tr '\n' '\0' | \
                        xargs -0 git update-index --add --replace --remove
                git ls-files -z --others | \
                        xargs -0 git update-index --add --replace --remove
        fi
 
-       eval "$filter_index" < /dev/null
+       eval "$filter_index" < /dev/null ||
+               die "index filter failed: $filter_index"
 
        parentstr=
        for parent in $parents; do
@@ -198,13 +223,15 @@ while read commit parents; do
                done
        done
        if [ "$filter_parent" ]; then
-               parentstr="$(echo "$parentstr" | eval "$filter_parent")"
+               parentstr="$(echo "$parentstr" | eval "$filter_parent")" ||
+                               die "parent filter failed: $filter_parent"
        fi
 
        sed -e '1,/^$/d' <../commit | \
-               eval "$filter_msg" | \
-               sh -c "$filter_commit" "git commit-tree" $(git write-tree) $parentstr | \
-               tee ../map/$commit
+               eval "$filter_msg" > ../message ||
+                       die "msg filter failed: $filter_msg"
+       sh -c "$filter_commit" "git commit-tree" \
+               $(git write-tree) $parentstr < ../message > ../map/$commit
 done <../revs
 
 src_head=$(tail -n 1 ../revs | sed -e 's/ .*//')
@@ -214,8 +241,9 @@ case "$target_head" in
        echo Nothing rewritten
        ;;
 *)
-       git update-ref refs/heads/"$dstbranch" $target_head
-       if [ $(cat ../map/$src_head | wc -l) -gt 1 ]; then
+       git update-ref refs/heads/"$dstbranch" $target_head ||
+               die "Could not update $dstbranch with $target_head"
+       if [ $(wc -l <../map/$src_head) -gt 1 ]; then
                echo "WARNING: Your commit filter caused the head commit to expand to several rewritten commits. Only the first such commit was recorded as the current $dstbranch head but you will need to resolve the situation now (probably by manually merging the other commits). These are all the commits:" >&2
                sed 's/^/       /' ../map/$src_head >&2
                ret=1
@@ -241,7 +269,8 @@ if [ "$filter_tag_name" ]; then
                [ -f "../map/$sha1" ] || continue
                new_sha1="$(cat "../map/$sha1")"
                export GIT_COMMIT="$sha1"
-               new_ref="$(echo "$ref" | eval "$filter_tag_name")"
+               new_ref="$(echo "$ref" | eval "$filter_tag_name")" ||
+                       die "tag name filter failed: $filter_tag_name"
 
                echo "$ref -> $new_ref ($sha1 -> $new_sha1)"
 
@@ -250,12 +279,13 @@ if [ "$filter_tag_name" ]; then
                        warn "unreferencing tag object $sha1t"
                fi
 
-               git update-ref "refs/tags/$new_ref" "$new_sha1"
+               git update-ref "refs/tags/$new_ref" "$new_sha1" ||
+                       die "Could not write tag $new_ref"
        done
 fi
 
 cd ../..
 rm -rf "$tempdir"
-echo "Rewritten history saved to the $dstbranch branch"
+printf "\nRewritten history saved to the $dstbranch branch\n"
 
 exit $ret