Save/restore the git commit message in case a git pre-commit hook fails. Also rename the APPEND var to GIT_COMMIT_MSG_SUFFIX.

This commit is contained in:
Nathan Broadbent
2018-09-26 23:04:51 +07:00
parent 1f60a87a77
commit 8233abd23f
3 changed files with 53 additions and 19 deletions

View File

@@ -35,11 +35,11 @@ if [[ "$git_keyboard_shortcuts_enabled" = "true" ]]; then
if [[ $shell == "zsh" ]]; then if [[ $shell == "zsh" ]]; then
_bind "$git_commit_all_keys" " git_commit_all""$RETURN_CHAR" _bind "$git_commit_all_keys" " git_commit_all""$RETURN_CHAR"
_bind "$git_add_and_commit_keys" " \033[1~ git_add_and_commit ""$RETURN_CHAR" _bind "$git_add_and_commit_keys" " \033[1~ git_add_and_commit ""$RETURN_CHAR"
_bind "$git_commit_all_with_ci_skip_keys" " \033[1~ APPEND='[ci skip]' git_commit_all ""$RETURN_CHAR" _bind "$git_commit_all_with_ci_skip_keys" " \033[1~ GIT_COMMIT_MSG_SUFFIX='[ci skip]' git_commit_all ""$RETURN_CHAR"
else else
_bind "$git_commit_all_keys" "\" git_commit_all$RETURN_CHAR\"" _bind "$git_commit_all_keys" "\" git_commit_all$RETURN_CHAR\""
_bind "$git_add_and_commit_keys" "\"\C-A git_add_and_commit $RETURN_CHAR\"" _bind "$git_add_and_commit_keys" "\"\C-A git_add_and_commit $RETURN_CHAR\""
_bind "$git_commit_all_with_ci_skip_keys" "\"\C-A APPEND='[ci skip]' git_commit_all $RETURN_CHAR\"" _bind "$git_commit_all_with_ci_skip_keys" "\"\C-A GIT_COMMIT_MSG_SUFFIX='[ci skip]' git_commit_all $RETURN_CHAR\""
fi fi
fi fi

View File

@@ -203,29 +203,62 @@ theirs(){ _git_resolve_merge_conflict "their" "$@"; }
# * Add escaped commit command and unescaped message to bash history. # * Add escaped commit command and unescaped message to bash history.
git_commit_prompt() { git_commit_prompt() {
local commit_msg local commit_msg
local saved_commit_msg
if [ -f "/tmp/.git_commit_message~" ]; then
saved_commit_msg="$(cat /tmp/.git_commit_message~)"
echo -e "\033[0;36mLeave blank to use saved commit message: \033[0m$saved_commit_msg"
fi
if [[ $shell == "zsh" ]]; then if [[ $shell == "zsh" ]]; then
vared -h -p "Commit Message: " commit_msg vared -h -p "Commit Message: " commit_msg
else else
read -r -e -p "Commit Message: " commit_msg read -r -e -p "Commit Message: " commit_msg
fi fi
if [ -n "$commit_msg" ]; then if [ -z "$commit_msg" ]; then
eval $@ # run any prequisite commands if [ -n "$saved_commit_msg" ]; then
# Add $APPEND to commit message, if given. (Used to append things like [ci skip] for Travis CI) commit_msg="$saved_commit_msg"
if [ -n "$APPEND" ]; then commit_msg="$commit_msg $APPEND"; fi
echo $commit_msg | git commit -F - | tail -n +2
else else
echo -e "\033[0;31mAborting commit due to empty commit message.\033[0m" echo -e "\033[0;31mAborting commit due to empty commit message.\033[0m"
return
fi
fi fi
escaped=$(echo "$commit_msg" | sed -e 's/"/\\"/g' -e 's/!/"'"'"'!'"'"'"/g')
# Add $GIT_COMMIT_MSG_SUFFIX to commit message, if given.
# (Used to append things like [ci skip] for Travis CI)
if [ -n "$GIT_COMMIT_MSG_SUFFIX" ]; then
commit_msg="$commit_msg $GIT_COMMIT_MSG_SUFFIX"
fi
# Exclamation marks are really difficult to escape properly in a bash prompt.
# They must always be enclosed with single quotes.
escaped_msg=$(echo "$commit_msg" | sed -e 's/"/\\"/g' -e "s/!/\"'!'\"/g")
# Add command to bash history, so that if a git pre-commit hook fails,
# you can just press "up" and "return" to retry the commit.
if [[ $shell == "zsh" ]]; then if [[ $shell == "zsh" ]]; then
print -s "git commit -m \"${escaped//\\/\\\\}\"" # zsh's print needs double escaping # zsh's print needs double escaping
print -s "$commit_msg" print -s "git commit -m \"${escaped_msg//\\/\\\\}\""
else else
echo "git commit -m \"$escaped\"" >> $HISTFILE history -s "git commit -m \"$escaped_msg\""
# Also add unescaped commit message, for git prompt # Need to write history to a file for tests
echo "$commit_msg" >> $HISTFILE if [ -n "$SHUNIT_VERSION" ]; then history -w $HISTFILE; fi
fi
# Also save the commit message to a temp file in case git commit fails
echo "$commit_msg" > "/tmp/.git_commit_message~"
eval $@ # run any prequisite commands
echo "$commit_msg" | git commit -F - | tail -n +2
# Fetch the pipe status (for both bash and zsh):
GIT_PIPE_STATUS=("${PIPESTATUS[@]}${pipestatus[@]}")
if [[ $shell == "zsh" ]]; then
git_exit_status="${GIT_PIPE_STATUS[2]}" # zsh array indexes start at 1
else
git_exit_status="${GIT_PIPE_STATUS[1]}"
fi
if [[ "$git_exit_status" == 0 ]]; then
# Delete saved commit message if commit was successful
rm -f "/tmp/.git_commit_message~"
fi fi
} }
@@ -234,8 +267,8 @@ git_commit_all() {
fail_if_not_git_repo || return 1 fail_if_not_git_repo || return 1
changes=$(git status --porcelain | wc -l | tr -d ' ') changes=$(git status --porcelain | wc -l | tr -d ' ')
if [ "$changes" -gt 0 ]; then if [ "$changes" -gt 0 ]; then
if [ -n "$APPEND" ]; then if [ -n "$GIT_COMMIT_MSG_SUFFIX" ]; then
local appending=" | \033[0;36mappending '\033[1;36m$APPEND\033[0;36m' to commit message.\033[0m" local appending=" | \033[0;36mappending '\033[1;36m$GIT_COMMIT_MSG_SUFFIX\033[0;36m' to commit message.\033[0m"
fi fi
echo -e "\033[0;33mCommitting all files (\033[0;31m$changes\033[0;33m)\033[0m$appending" echo -e "\033[0;33mCommitting all files (\033[0;31m$changes\033[0;33m)\033[0m$appending"
git_commit_prompt "git add --all ." git_commit_prompt "git add --all ."

View File

@@ -260,9 +260,10 @@ test_git_commit_prompt() {
if [[ $shell == "zsh" ]]; then if [[ $shell == "zsh" ]]; then
test_history="$(history)" test_history="$(history)"
else else
# Need to load history from $HISTFILE
# (Couldn't get the 'history' builtin to work during tests.)
test_history="$(cat $HISTFILE)" test_history="$(cat $HISTFILE)"
fi fi
assertIncludes "$test_history" "$commit_msg"
assertIncludes "$test_history" "git commit -m \"$dbl_escaped_msg\"" assertIncludes "$test_history" "git commit -m \"$dbl_escaped_msg\""
} }
@@ -284,7 +285,7 @@ test_git_commit_prompt_with_append() {
# Test the git commit prompt, by piping a commit message # Test the git commit prompt, by piping a commit message
# instead of user input. # instead of user input.
echo "$commit_msg" | APPEND="[ci skip]" git_commit_prompt > /dev/null echo "$commit_msg" | GIT_COMMIT_MSG_SUFFIX="[ci skip]" git_commit_prompt > /dev/null
git_show_output=$(git show --oneline --name-only) git_show_output=$(git show --oneline --name-only)
assertIncludes "$git_show_output" "$commit_msg \[ci skip\]" assertIncludes "$git_show_output" "$commit_msg \[ci skip\]"