Git - 在冲突时自动创建不同版本的文件

10
当Git在合并过程中检测到冲突时,默认行为是用<<< >>> === 标记填充文件。
大多数情况下这样做没问题,但有时我想以不同的方式解决冲突,只希望Git创建不同的文件:
- 原始版本, - 更改后的版本A, - 更改后的版本B。
如何实现?
如果没有一条简单的命令可以一次性创建这些文件(这有点令人惊讶),也许有一种方法可以扩展Git,使其可以执行此操作?一个自定义的mergetool或其他什么东西?这只是一个想法。

解决方案:

我采用了@Karl Bielefeldt的答案的变体:

savefiles.sh

#!bash
BASE=$1
LOCAL=$2
REMOTE=$3
MERGED=$4

cp "$BASE" "$MERGED.git_BASE"
cp "$LOCAL" "$MERGED.git_LOCAL"
cp "$REMOTE" "$MERGED.git_REMOTE"

# never mark the conflict as merged
exit 1 

配置

mergetool.savefiles.cmd=/path/to/savefiles.sh $BASE $LOCAL $REMOTE $MERGED
mergetool.savefiles.trustexitcode=true

您可以查看以下答案以了解示例工作流程:https://dev59.com/J3VC5IYBdhLWcg3w21Iq#3407920 - plaes
我以前见过,谢谢! - Kos
3个回答

6
创建一个名为savefiles.sh的文件,并将以下内容复制到该文件中:
#!/usr/bin/bash

cp $1 /path/to/BASE
cp $2 /path/to/LOCAL
cp $3 /path/to/REMOTE

在您的代码库内执行以下命令:
git config mergetool.savefiles.cmd "/path/to/savefiles.sh \$BASE \$LOCAL \$REMOTE"

如果您想更改除此存储库之外的内容,请添加--global。然后运行此自定义合并工具,使用以下命令:
git mergetool --tool=savefiles

谢谢!这差不多是我想要的——我稍微修改了一下,让它根据 $MERGE git 变量的内容自动选择输出文件名。 - Kos

5
如果您想不使用合并工具,仅显示或保存您提到的文件状态,则索引会保存冲突文件的不同状态。您可以使用以下命令显示(如果需要,可以重定向到文件):
$ git show :1:file.txt  # the file in a common ancestor of both branches
$ git show :2:file.txt  # the version from HEAD.
$ git show :3:file.txt  # the version from MERGE_HEAD.

然而,使用图形化合并工具可以向您展示冲突文件的三个面板视图。这通常是人们所做的,因此只需选择您喜欢的工具并查看如何将其与git mergetool调用链接即可。


1
另外,git mergetool 无论如何都会在您的编辑器中打开三个版本。 - Josh Lee
实际上,我之所以问这个问题,就是为了能够在我最喜欢的合并工具(即Eclipse)中打开这些文件。 :) 而且我不认为我可以通过命令行自动在Eclipse中打开三向补丁编辑器。 - Kos
这个解决方案很麻烦,特别是当有多个具有长路径的文件时。也许可以发明一个自定义的“合并工具”,可以自动为我完成这个任务? - Kos
我可以手动打开视图,但我希望文件能自动创建。 - Kos
@CharlesB @Josh Lee,我因为mergetool的原因来到这里,它使用了一个标志打开了我的编辑器(kdiff3),导致它自动(且不正确地)解决了冲突,而没有任何交互。所以这是除了@Kos之外另一个生成文件的用例。请查看我的答案获取更多信息。 - JMM
显示剩余3条评论

1

摘要

git mergetool -y -t bogus <file>

这对我来说可行,使用git 1.7.9.5 / Ubuntu 12.04和msysgit 1.9.4 / Windows 7 x64。

解释

我只希望Git创建不同的文件

我也在寻找同样的东西。例如: 当调用git mergetool -t kdiff3时,Git 显然试图通过硬编码的 --auto 标志调用kdiff3,这指示kdiff3自动解决冲突并退出,而不向我显示GUI或允许我参与该过程( 参见)。当发生这种情况并且kdiff3错误地解决了冲突时,我开始寻找这个。

当我这样调用mergetool时(其中bogus是一个不是有效合并工具标识符的字符串[例如,如果您的git版本没有git mergetool --tool-help的输出中]),会发生以下情况:
  • It reports "Unknown merge tool bogus"

  • The index and file are untouched

  • The following files are generated (where {num} is an integer that is the same in all files created by this invocation):

    file.BACKUP.{num}
    file.BASE.{num}
    file.LOCAL.{num}
    file.REMOTE.{num}
    

file.BACKUP.{num}file相同。

注释

如果mergetool.prompt设置为false,我认为-y应该是不必要的。而且,根据文档,在较新版本的git中,-t似乎意味着-y

-t部分可以进一步缩短,例如-t x-t 0

如果您有多个未合并的文件,则似乎没有任何方法可以同时生成这些版本。例如,如果您有未合并的文件files/file1files/file2,则以下任何一个仍将仅为file1生成这些版本(备份、基本、本地、远程):

git mergetool -y -t x
git mergetool -y -t x files
git mergetool -y -t x files/file1 files/file2

然而,如果您解决了file1中的冲突并再次运行git mergetool,它将继续到下一个文件。

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