【发布时间】:2018-10-24 17:44:53
【问题描述】:
我正在使用 git 的一个钩子 commit-msg 来验证特定格式和内容的提交消息。
但是,每当提交消息失败时,我有时会丢失消息中的一段或更多文本。
我曾尝试将其保存在某个地方,但我不确定如何在用户尝试修复失败的提交消息时将其恢复给用户,只显示最后一条好的提交消息。
以前有没有其他人处理过这个问题?你是怎么解决的?
信息:我正在使用 python 脚本进行验证。
【问题讨论】:
我正在使用 git 的一个钩子 commit-msg 来验证特定格式和内容的提交消息。
但是,每当提交消息失败时,我有时会丢失消息中的一段或更多文本。
我曾尝试将其保存在某个地方,但我不确定如何在用户尝试修复失败的提交消息时将其恢复给用户,只显示最后一条好的提交消息。
以前有没有其他人处理过这个问题?你是怎么解决的?
信息:我正在使用 python 脚本进行验证。
【问题讨论】:
提交消息存储在.git/COMMIT_EDITMSG。在“失败”的提交尝试之后,您可以运行:
git commit --edit --file=.git/COMMIT_EDITMSG
或更短,例如:
git commit -eF .git/COMMIT_EDITMSG
它将在您的$EDITOR(或您在 Git 配置中设置的编辑器)中加载错误的提交消息,以便您可以尝试修复提交消息。您还可以为上述设置一个别名:
git config --global alias.fix-commit 'commit --edit --file=.git/COMMIT_EDITMSG'
然后改用git fix-commit。
【讨论】:
As stated,当运行git commit时,git启动你的编辑器指向
$GIT_DIR/COMMIT_EDITMSG 文件。除非有问题的 commit-msg 钩子
移动/删除/损坏文件,消息应该仍然存在。
我认为重用消息不是默认行为,因为它可能
干扰prepare-commit-msg 钩子。理想情况下,会有一个切换
可用于默认启用重用,以避免数据丢失。这
下一个最好的事情是override a git sub-command with a git alias,
但不幸的是,目前这是不可能的,那就是
unlikely to change。所以我们要为它创建一个自定义别名。
我使用了一个类似于已接受答案中的别名:
git config alias.recommit \
'!git commit -F "$(git rev-parse --git-dir)/COMMIT_EDITMSG" --edit'
然后,在运行git recommit 时,被拒绝的提交消息的内容应该
出现在编辑器中。
请注意,对于存储库中的第一次提交,两个别名都会失败,因为
COMMIT_EDITMSG 文件尚未创建。为了使它也适用于
这种情况下,看起来有点复杂:
git config alias.recommit \
'!test -f "$(git rev-parse --git-dir)/COMMIT_EDITMSG" &&
git commit -F "$(git rev-parse --git-dir)/COMMIT_EDITMSG" --edit ||
git commit'
可以简写为:
git config alias.recommit \
'!cm="$(git rev-parse --git-dir)/COMMIT_EDITMSG" &&
test -f "$cm" && git commit -F "$cm" --edit || git commit'
无论哪种方式,考虑到增加的安全性,对于交互式使用,您甚至可以
默认使用上述别名之一,而不是 git commit。
您也可以 make a wrapper for git itself 并根据
关于论点(即:关于子命令),尽管这需要确保
对git 的所有后续调用都引用原始二进制文件,以免它们
导致无限递归:
git () {
cm="$(git rev-parse --git-dir)/COMMIT_EDITMSG"
case "$1" in
commit)
shift
test -f "$cm" && command git commit -F "$cm" --edit "$@" ||
command git commit "$@"
;;
*)
command git "$@";;
esac
}
请注意,如果将以上内容添加到您的 rc 文件中(例如:~/.bashrc),那么每个
调用其中的git 将引用包装器,除非您将它们放在前面
还有command。
最后,我刚刚得知aliasing to a wrapper file with a different name 是一个选项:
PATH="$HOME/bin:$PATH"
export PATH
alias git='my-git'
所以包装器(例如:~/bin/my-git)可以简单得多:
#!/bin/sh
cm="$(git rev-parse --git-dir)/COMMIT_EDITMSG"
case "$1" in
commit)
shift
test -f "$cm" && git commit -F "$cm" --edit "$@" ||
git commit "$@"
;;
*)
git "$@";;
esac
同时也避免干扰,如aliases are not expanded when used in external scripts。
【讨论】: