来自失败的git commit-msg挂钩的丢失的提交消息

时间:2018-10-24 17:44:54

标签: python git githooks

我正在使用git的一个钩子commit-msg来验证特定格式和内容的提交消息。

但是,每当提交消息失败时,我有时会丢失消息中的一段或更多文本。

我一直在尝试将其保存在某个地方,但是当用户尝试修复失败的提交消息时,我不知道如何将其还原给用户,只会显示最后一条正确的提交消息。

以前有人处理过吗?您是如何解决的?

信息:我正在使用python脚本进行验证。

2 个答案:

答案 0 :(得分:2)

提交消息存储在.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

答案 1 :(得分:0)

背景

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