Created
November 19, 2020 22:19
-
-
Save rsc/f2817625d6d2ad7ca6e84474251d8932 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
help="usage: git-generate | |
git-generate regenerates a commit from a script kept in the commit message. | |
Specifically, the topmost commit in the current git repo should have a script | |
preceded by [git-generate] on a line by itself. The script continues until the | |
end of the message or a Change-Id: line. The script starts execution in the | |
root of the git repo. | |
For example, a commit message might say: | |
We are moving from Old to New. | |
[git-generate] | |
cd some/dir | |
sed -i '' 's/Old/New/g' * | |
To regenerate the commit, git-generate resets the working file state to before | |
the commit and then runs the script. The script runs using 'bash -e', so any | |
single command failing will abort the generation. | |
" | |
if [ "$1" = "-help" -o "$1" = "-h" ]; then | |
echo "$help" | |
exit 0 | |
fi | |
if [ $# != 0 ]; then | |
echo >&2 'usage: git-generate' | |
echo >&2 ' git-generate -help' | |
exit 2 | |
fi | |
if ! git log -n1 >/dev/null; then | |
echo >&2 'git-generate: cannot find git repo' | |
exit 2 | |
fi | |
set -e | |
gitdir=$(git rev-parse --show-toplevel) | |
what=HEAD | |
if [ -e $gitdir/.git/rebase-merge/stopped-sha ]; then | |
what=$(cat $gitdir/.git/rebase-merge/stopped-sha) | |
short=$(echo $what | cut -c 1-8) | |
echo >&2 "git-generate: using $short to resolve merge conflict" | |
fi | |
msg=$(mktemp /tmp/replayXXXXXX) | |
git log -n1 $what | sed -n 's/^ //p' | sed -n '/^ *\[git-generate\]$/,$p' | sed '1d; /Change-Id:/d' | grep -v Change-Id: >$msg | |
ls -l $msg | |
if ! [ -s $msg ]; then | |
echo >&2 'git-generate: no script found in commit' | |
exit 2 | |
fi | |
now=$(git rev-parse HEAD) | |
# Reset files to HEAD^ but keep branch itself at HEAD. | |
# For a brief moment HEAD is pointing at HEAD^, which is unfortunate. | |
# It would be very nice if there were some single command to do this pair. | |
if [ what = HEAD ]; then | |
git reset -q --hard 'HEAD^' | |
git reset -q $now | |
else | |
# Resolving merge conflict, HEAD is parent before changes, | |
# which is exactly what we want. | |
git reset -q --hard HEAD | |
fi | |
cd $(git rev-parse --show-toplevel) | |
bash -e $msg | |
rm -f $msg |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment