【问题标题】:Git: how to request "interactive merge" always?Git:如何始终请求“交互式合并”?
【发布时间】:2012-04-01 18:18:29
【问题描述】:

我有一个项目,其中有一些文件很脆弱,即使整个程序似乎可以正常工作,轻微的错误也可能导致安全问题。因此,我希望 git 在合并期间始终验证任何自动修改的结果。

如果我理解正确的话,自定义合并驱动程序就是我想要的。我想出的最好的方法是在自定义合并驱动程序中使用 git-merge-file 来获得正常的合并结果,然后退出 1 以将结果始终标记为冲突。这样 git 将在合并期间停止,我可以在完成合并之前检查合并结果。

但是,对该文件的预期更改非常小,最好的方法是能够运行类似于“git add -i”并选择“patch”并一次应用一个大块的内容。

是否有一种简单的方法可以编写一个合并驱动程序,该驱动程序的行为类似于“git add -i”,用于对该文件的所有合并(其中可能应用的块是自动合并的结果)?

另外,如果我理解正确的话,合并驱动程序只会在文件级冲突时被调用。是否可以为特殊标记的文件请求类似的手动验证?我正在考虑在进行合并之前在 gitattributes 中将新文件标记为“脆弱”,然后一些 git merge 魔法(或过滤魔法)会要​​求我验证新的特殊文件是否适用于合并的分支。

【问题讨论】:

  • 您为什么不简单地查看合并的差异?
  • 我希望在发生此类合并时自动提醒。通常可以通过自动化测试和/或构建来测试合并结果,但对于易碎的东西,需要进行额外的审查来确定。我想在任何团队成员合并任何涉及任何此类特殊文件的内容时强制进行此类审查。

标签: git merge interactive


【解决方案1】:

我在这里添加我当前的解决方案,因为这总比没有好,但与我正在寻找的交互式解决方案相比仍然很短。解决方案由三部分组成:

  1. 使用以下内容创建文件bin/merge-and-verify

    #!/bin/bash
    # git merge driver that does normal merge but marks the result as conflicting
    
    # make a copy of original version
    cp "${1}" "${1}.tmp"
    ORIG_HASH=$(git hash-object "${1}")
    WORKFILE=$(git ls-tree -r HEAD | fgrep "$ORIG_HASH" | cut -b54-)
    git merge-file -L "My version (working directory)" -L "Base (common ancestor)" -L "Merge head (remote change)" "${1}" "${2}" "${3}"
    # display changes made
    echo "-----------------------------------------------------"
    echo "Making following changes automatically:"
    echo "(Confirm changes with 'git add $WORKFILE')"
    echo "-----------------------------------------------------"
    diff -u --label "Original" "${1}.tmp" --label "Automatically modified" "${1}"
    echo "-------------------------------------------------"
    # remove our extra copy
    rm -f "${1}.tmp"
    exit 1
    
  2. 创建/修改文件`.gitattributes如下:

    [attr]FRAGILE merge=merge-and-verify
    
    relative/path/to/fragile.file FRAGILE
    
  3. 运行以下命令激活工作目录中的驱动程序

    git config merge.merge-and-verify.driver "./bin/merge-and-verify %A %O %B"
    

现在对标记为FRAGILE 的任何文件的任何修改都将导致通常的自动合并,其中自动合并的结果将显示在控制台中,并提示如何确认更改(git add relative/path/to/fragile.file)如果更改看起来很正常。如果您不需要在合并期间将详细输出输出到控制台,则只需要驱动程序中的git merge-fileexit 1

缺失部分:由于 git 内部行为,如果文件历史记录中没有冲突,则不会调用合并驱动程序。例如,如果一个新的 FRAGILE 文件已添加到另一个分支中,该文件合并到 master 中,则不会调用合并驱动程序,因为不需要合并任何文件(据 git 所知,在这种情况下合并分支只是添加了一个不与任何内容冲突的新文件,因此不需要合并驱动程序)。

【讨论】:

猜你喜欢
  • 2012-06-11
  • 1970-01-01
  • 2010-12-16
  • 1970-01-01
  • 2019-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-02
相关资源
最近更新 更多