Git 默认合并提交消息不包括冲突

Git default merge commit message not including conflicts

origin/base 分支合并到我的 feature 分支后,我必须解决文件 Parameter.java 上的一个冲突。我启动了 Git 合并工具并解决了它。解决后,我执行了 git commit 并使用默认合并提交消息打开了 Vim。

事实上,此默认提交消息包含冲突列表,但以 # 开头,因此它们将在提交消息中被忽略。

Merge remote-tracking branch 'origin/base' into feature

# Conflicts:
#       Parameter.java
#
# It looks like you may be committing a merge.
# If this is not correct, please remove the file
#       .git/MERGE_HEAD
# and try again.

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch feature
# All conflicts fixed but you are still merging.
#
# Changes to be committed:
#       modified:   Parameters.java
#       modified:   SpecialParameters.java
#       modified:   Traveller.java

是否需要添加一些配置以将这些冲突行自动放入提交消息中?因此,删除 Conflicts 部分中冲突文件的 #

您可以使用 prepare-commit-msg 挂钩。

复制.git/hooks/prepare-commit-msg.sample.git/hooks/prepare-commit-msg

里面的例子其实就是在Conflicts部分加上了#:

case "," in
  merge,)
    /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "" ;;

这个钩子很有意义,因为以前的版本默认这样做(比如 Linux git version 1.7.10.4)。

现在您要做的恰恰相反:删除冲突部分的 #。实际上,git version 2.6.2.windows.1 默认情况下会注释掉 Conflicts 部分,因此您只需将 prepare-commit-msg 中的命令更新为:

/usr/bin/perl -i.bak -ne 's/^#// if /^# Conflicts/ .. /^#\R/; print' "" ;;

您不需要自己将其添加到提交消息中。一旦你进行了合并提交,如果有冲突 git 会告诉你它们在哪里。只是 运行 一个 git show --name-only [commit sha] 提交是一个包含冲突的合并,你会看到它作为消息的一部分。

我用的是sedranges by patterns (and is based on )

用人类语言阅读:在# Conflicts:#(blank line)之间的行范围内,删除前面的#(space)## \?).

sed -i '/start/,/stop/ s/# \?//'

准备提交消息挂钩:

# prepare-commit-msg
case "," in
  merge,)
    # Uncomment Conflicts section in merge commit body
    sed -i '/^# Conflicts:/,/^#\?$/ s/# \?//' ""
    ;;
  *) ;;
esac

这导致

Conflicts:
    GIT-VERSION-GEN
    RelNotes

我找到了一种无需任何挂钩或脚本即可执行此操作的方法:使用 ---cleanup scissors:

% git commit --cleanup scissors

这导致默认提交消息:

Merge branch 'branch'

# Conflicts:
#       baz.txt
#       foo.txt
# ------------------------ >8 ------------------------
# Do not modify or remove the line above.
# Everything below it will be ignored.
#
# It looks like you may be committing a merge.
# If this is not correct, please remove the file
#       .git/MERGE_HEAD
# and try again.


# Please enter the commit message for your changes. Lines starting
# with '#' will be kept; you may remove them yourself if you want to.
# An empty message aborts the commit.
#
# On branch master
# All conflicts fixed but you are still merging.
#
# Changes to be committed:
#       modified:   bar.txt
#       modified:   baz.txt
#       modified:   foo.txt
#

如果你接受它,你会收到以下提交信息:

% git log -1
commit 64425eab687f9d4fc531da69495dcb401372104b (HEAD -> master)
Merge: efd152d 474a8f4
Author: Dave Dribin <dave@example.com>
Date:   Fri Oct 19 23:47:19 2018 -0500

    Merge branch 'branch'

    # Conflicts:
    #       baz.txt
    #       foo.txt

这不会删除 # 前缀,但会包含冲突文件列表。为什么这行得通?它将在特殊的 "scissors" 行 之后剪切所有内容,而不是注释字符串前缀。这是 git-commit(1) man page

--cleanup scissors 的文档
       --cleanup=<mode>
       This option determines how the supplied commit message should be
       cleaned up before committing. The <mode> can be strip, whitespace,
       verbatim, scissors or default.

       strip
           Strip leading and trailing empty lines, trailing whitespace,
           commentary and collapse consecutive empty lines.

       whitespace
           Same as strip except #commentary is not removed.

       verbatim
           Do not change the message at all.

       scissors
           Same as whitespace except that everything from (and including)
           the line found below is truncated, if the message is to be
           edited. "#" can be customized with core.commentChar.

               # ------------------------ >8 ------------------------

       default
           Same as strip if the message is to be edited. Otherwise
           whitespace.

       The default can be changed by the commit.cleanup configuration
       variable (see git-config(1)).