mirror of
https://github.com/tj/git-extras.git
synced 2026-09-10 07:26:17 -04:00
64 lines
1.8 KiB
Bash
Executable file
64 lines
1.8 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
|
|
# Warn on a dirty work tree.
|
|
git rev-parse --verify HEAD >/dev/null || exit 1
|
|
git update-index -q --ignore-submodules --refresh
|
|
if ! git diff-files --quiet --ignore-submodules
|
|
then
|
|
echo "WARNING (dirty work tree): The patch will only be checked against actual commits."
|
|
fi
|
|
|
|
# Warn on a dirty index.
|
|
if ! git diff-index --cached --quiet --ignore-submodules HEAD --
|
|
then
|
|
echo "WARNING (dirty index): The patch will only be checked against actual commits."
|
|
fi
|
|
|
|
# Use a temporary index.
|
|
index="/tmp/$(basename $0).$$.tmp"
|
|
cleanup() {
|
|
rm $index
|
|
exit 2
|
|
}
|
|
trap cleanup 2
|
|
|
|
# Go back in history while parent commits are available.
|
|
echo "Trying to find a commit the patch applies to..."
|
|
rev=$(git rev-parse HEAD)
|
|
while [ $? = 0 ]
|
|
do
|
|
GIT_INDEX_FILE=$index git read-tree $rev
|
|
|
|
# Try to apply the patch.
|
|
GIT_INDEX_FILE=$index git apply --cached $1 >/dev/null 2>&1
|
|
patch_failed=$?
|
|
|
|
# Do it again, but show the error, if the problem is the patch itself.
|
|
if [ $patch_failed = 128 ]
|
|
then
|
|
GIT_INDEX_FILE=$index git apply --index --check $1
|
|
exit $patch_failed
|
|
fi
|
|
|
|
# The patch applied. Commit and rebase.
|
|
if [ $patch_failed = 0 ]
|
|
then
|
|
# Manufacture a commit.
|
|
tree=$(GIT_INDEX_FILE=$index git write-tree)
|
|
commit=$(git commit-tree $tree -p $rev -m "$1")
|
|
rm $index
|
|
|
|
echo "Patch applied to $(git rev-parse --short $rev) as $(git rev-parse --short $commit)"
|
|
|
|
git cherry-pick $commit
|
|
exit $?
|
|
fi
|
|
|
|
rev=$(git rev-parse --verify -q $rev^)
|
|
done
|
|
|
|
# No compatible commit found. Restore.
|
|
echo "Failed to find a commit the patch applies to."
|
|
rm $index
|
|
exit 1
|