使用git filter-branch编辑旧的提交消息

4

如果我想完全编辑特定的提交,我使用以下命令:

git filter-branch --env-filter \
"if test \$GIT_COMMIT = '5b740c488f0e4251a6e534cab79da8b05de7a195'
then
    export GIT_AUTHOR_NAME='John Doe'
    export GIT_COMMITTER_NAME='John Doe'
    export GIT_AUTHOR_EMAIL='john.doe@gmail.com'
    export GIT_COMMITTER_EMAIL='john.doe@gmail.com'
    export GIT_AUTHOR_DATE='1493100264'
    export GIT_COMMITTER_DATE='1493100264'
fi"

是否有一种方法可以编辑提交信息?

我知道我可以使用 --msg-filtersed 混合使用,但如果多个提交具有相同的提交消息,那可能会有问题。

我想要的是一种方法告诉Git:“对于这个SHA,请将提交消息设置为X”,类似于我编辑作者和提交日期的方式。

非常感谢!

2个回答

2

你已经知道如何在--env-filter中进行测试。那么你需要意识到的是,--msg-filter--env-filter在同一个地方使用:1

    eval "$filter_env" < /dev/null ||
            die "env filter failed: $filter_env"
    ...
    {
            while IFS='' read -r header_line && test -n "$header_line"
            do
                    # skip header lines...
                    :;
            done
            # and output the actual commit message
            cat
    } <../commit |
            eval "$filter_msg" > ../message ||
                    die "msg filter failed: $filter_msg"
$filter_env的默认值为空,但会被--env-filter参数替换。 $filter_msg的默认值为cat,同样会被--msg-filter参数替换。

两者都直接进行eval,在此过程中$GIT_COMMIT$GIT_AUTHOR_EMAIL等环境变量都已设置好。由于filter_msg在管道的右侧进行eval,因此对环境变量的更改会丢失(所以必须在另一个过滤器中进行任何所需的更改),但仍然可以检查它们。由于$filter_env先运行,因此您必须考虑到您在那里做出的任何更改在运行$filter_msg时已生效。

因此:

我想要一种告诉“对于这个SHA,将提交消息设置为X”的方法,类似于我编辑作者和提交日期的方式。

翻译为:

--msg-filter 'if test $GIT_COMMIT = 5b740c488f0e4251a6e534cab79da8b05de7a195;
     then cat >/dev/null && cat $HOME/tmp/prepared-msg; else cat; fi'

或类似方式(cat >/dev/null 的作用是为了避免损坏的管道错误而将标准输入丢弃。如果使用 sed 编辑消息,请不要丢弃标准输入流。)


1我不确定为什么 git-filter-branch.sh 代码使用 { while ... } 循环来移除提交中的头信息,当使用 sed -e '1,/^$/d' 就足够了... 啊,我记得为什么了:一些 sed 要求消息以最后一个换行符结束。是的,这就是为什么:请参见 df0620108b9710a06d5a2d9c125d43b97590cce6 提交记录


非常好的答案,非常完整!非常感谢。 - Boris K
你为什么使用 cat $HOME/tmp/prepared-msg?使用 echo 也可以很好地工作。 - Boris K
这让你可以写一条长信息。单行提交消息很少是非常好的。 - torek
谢谢!特别是来自Git源代码的片段非常有说明性! - Jules Kerssemakers

1

所以,如果有人正在寻找一个有效的命令,这是我使用的命令:

git filter-branch --msg-filter \
"if test \$GIT_COMMIT = '5b740c488f0e4251a6e534cab79da8b05de7a195'
then 
    echo 'New commit message!\nOn multiple lines'; else cat
fi"

1
小提示:我不得不使用 echo -e 才能使 '\n' 正常工作。 这是在 GNU bash 版本 4.2.46(2)-release 中。 - Jules Kerssemakers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接