зеркало из https://github.com/microsoft/git.git
filter-branch: fail gracefully when a filter fails
A common mistake is to provide a filter which fails unwantedly. For example, this will stop in the middle: git filter-branch --env-filter ' test $GIT_COMMITTER_EMAIL = xyz && export GIT_COMMITTER_EMAIL = abc' rewritten When $GIT_COMMITTER_EMAIL is not "xyz", the test fails, and consequently the whole filter has a non-zero exit status. However, as demonstrated in this example, filter-branch would just stop, and the user would be none the wiser. Also, a failing msg-filter would not have been caught, as was the case with one of the tests. This patch fixes both issues, by paying attention to the exit status of msg-filter, and by saying what failed before exiting. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Родитель
09ff69bb39
Коммит
8c1ce0f46b
|
@ -28,6 +28,16 @@ map()
|
|||
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
|
||||
# "author" or "committer
|
||||
|
||||
|
@ -181,23 +191,29 @@ while read commit parents; do
|
|||
export GIT_COMMIT=$commit
|
||||
git cat-file commit "$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
|
||||
# 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
|
||||
|
@ -206,13 +222,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 > ../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/ .*//')
|
||||
|
@ -249,7 +267,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)"
|
||||
|
||||
|
|
|
@ -107,13 +107,19 @@ test_expect_success 'use index-filter to move into a subdirectory' '
|
|||
mv \$GIT_INDEX_FILE.new \$GIT_INDEX_FILE" directorymoved &&
|
||||
test -z "$(git diff HEAD directorymoved:newsubdir)"'
|
||||
|
||||
test_expect_success 'stops when msg filter fails' '
|
||||
! git-filter-branch --msg-filter false nonono &&
|
||||
rm -rf .git-rewrite &&
|
||||
! git rev-parse nonono
|
||||
'
|
||||
|
||||
test_expect_success 'author information is preserved' '
|
||||
: > i &&
|
||||
git add i &&
|
||||
test_tick &&
|
||||
GIT_AUTHOR_NAME="B V Uips" git commit -m bvuips &&
|
||||
git-filter-branch --msg-filter "cat; \
|
||||
test \$GIT_COMMIT = $(git rev-parse master) && \
|
||||
test \$GIT_COMMIT != $(git rev-parse master) || \
|
||||
echo Hallo" \
|
||||
preserved-author &&
|
||||
test 1 = $(git rev-list --author="B V Uips" preserved-author | wc -l)
|
||||
|
|
Загрузка…
Ссылка в новой задаче