合并时,我们保留Maven pom.xml文件的本地版本:
git merge origin/remote_branch
git checkout --ours **/pom.xml pom.xml
git add **/pom.xml pom.xml
git commit -m "Merge"
除非本地分支中的pom.xml文件已被删除,否则这将非常有效。运行上面的命令#2后,我们得到一个错误:
d:\code>git checkout --ours **/pom.xml pom.xml
error: path 'blah/pom.xml' does not have our version
...在这个错误之后,下一个命令#3 git add **/pom.xml pom.xml
有效地添加了远程pom.xml文件--这正是我们不想要的。
我们如何更新我们的脚本来处理这个问题?
2条答案
按热度按时间3gtaxfhh1#
运行
git checkout --ours **/some_file2.xml some_file2.xml
命令后出现错误error: path 'some/file' does not have our version
的解决方法1.A.作为人类,以下是步骤
作为一个人,你必须做到以下几点。让我们假设您运行了以下代码,正如我在Who is "us"/"ours" and "them"/"theirs" according to Git?中所解释和推荐的:
......但没有成功!它什么都没做。相反,它会输出以下错误:
问题是这些是
our
端的 deleted 文件,所以我们必须从我们的工作树(工作文件系统)手动git rm
它们中的每一个,手动强制我们的工作树匹配这些文件的our
端:现在,重新运行
checkout --ours
命令,它将正常工作!:很好!搞定。
1.B.编写上述流程的脚本有点困难,但具体方法如下
让我们把上面的东西写下来。毫无疑问,有很多方法可以做到这一点,但这里是我能找到的最简单的方法:
当然,你也可以将第一次尝试的输出存储到一个文件中,如果第一次尝试失败,只运行第二次尝试(这意味着输出不是空字符串),但我将把它留给你。
**示例输出:**通过
git rm
ing您删除的文件,您将看到以下输出(这里的第一行包含$
char之后的实际命令):git checkout --ours -- path/to/some/dir |& gawk '{ print $3 }' | xargs git rm
的说明:git checkout --ours -- path/to/some/dir
接受来自--ours
端的所有合并冲突(在我的回答中阅读更多内容:根据Git,谁是“我们”,谁是“他们”?).|&
管道 *stderr
输出 * 以及 *stdout
输出,因为git命令可能打印出的错误消息是stderr
,这就是我们需要管道的。gawk '{ print $3 }'
只打印每行的第三个空格分隔字段,这意味着它捕获error: path 'path/to/some/dir/file1.cpp' does not have our version
的'path/to/some/dir/file1.cpp'
部分。| xargs git rm
会将所有这些文件通过管道传输到git rm
,然后用git删除它们。2.整理
现在,您可以添加这些自动修复的文件并继续此过程:
参考资料:
1.对于awk/gawk:
git-diffn.sh
"git diff with line numbers" script(我从来不记得awk语法,所以我只看以前的例子,包括我自己的)。1.官方GNU AWK用户指南
1.使用
| xargs git rm
:Git rm多个文件?1.使用
|&
管道传输 * stdout * 和 * stderr:在bash中同时连接stdout和stderr?1.为什么使用'git rm'而不是'rm'来删除文件?
5q4ezhmt2#
第一:
如果没有合并冲突,应该读
git merge --no-commit
来确保Git不会提交这些更改,否则接下来的步骤就没有意义了。请注意,如果--theirs
提交更改了一些pom.xml
文件,而您没有更改它们,或者如果Git认为它成功地合并了您的更改和他们的更改,则根本不会发生合并冲突。(如果您想在其中一种情况下使用他们的版本,这也有点棘手,但您似乎总是想使用--ours
版本。下一页:
这依赖于您的shell(可能是
bash
或类似的)以您想要的方式扩展**
;你可能想引用星号,并让Git做glob扩展。这可能会影响到你的具体情况,我不确定Git在合并冲突中是如何处理的,所以在你做任何类似的事情之前,你应该仔细实验。除非本地分支中的pom.xml文件已被删除,否则这将非常有效。运行上面的命令#2后,我们得到一个错误:
右图:在这种情况下,如果你想保留已删除的文件,你需要覆盖Git的默认操作,选择在索引和工作树中保留它们的版本。
让我们跳到所有这些中特定于Git的部分,index。记住,Git的索引是你构建下一个提交的地方。在合并过程中,它也是解决冲突的地方。
合并时索引中的条目
在正常(非合并)情况下,索引对每个被跟踪的文件都有一个条目。如果文件 F 在当前(HEAD)提交和工作树中,则索引具有针对 F 的条目。最初这个索引条目版本匹配HEAD版本。你修改工作树中的文件,然后
git add
工作树版本将其复制到索引中代替HEAD版本;然后下一个git commit
将保存索引版本。在冲突合并期间,文件 F 有冲突,索引有 * 最多三个**条目,而不是通常的一个。这些条目分别放在插槽1、2和3中。(插槽0是为正常的、不冲突的条目保留的。)插槽1用于 merge base 版本。插槽2用于
--ours
,插槽3用于--theirs
,您可以将这些名称用于2和3,但插槽1没有名称。在以下情况下会发生合并冲突:
对于修改/修改冲突,填充所有三个插槽。对于其他三种类型的冲突,一个插槽是空的:合并基槽为空(创建/创建),或
--ours
为空(删除/X),或--theirs
为空(X/删除)。当
--ours
插槽为空时,git checkout --ours
步骤失败。当--ours
插槽非空时成功:它将X1 M15 N1 X版本提取到工作树中。Git对任何delete/X或X/delete冲突的默认操作是在工作树中保留幸存的版本。也就是说,如果插槽3(他们的)为空,则工作树文件匹配插槽2条目,但是如果插槽2(我们的)为空,则工作树文件匹配插槽3条目。
在这种情况下,您可以选择通过扫描空的“slot 2“s并
git rm
文件来处理此问题:如果您将其编写为Python程序,请使用
git ls-files -z --stage
使其易于机器解析。您甚至可以完全停止使用git checkout --ours
,停止依赖shell或Git globbing,并完全在脚本中编写解析pom.xml
文件的规则。本质上,您可以通读整个索引,查找其基本名称(最后一个
/
之后的所有内容)与pom.xml
匹配的文件:HEAD
提交中的hash ID进行比较,因为Git可能根本没有正确解析文件;在这种情况下,用来自HEAD
提交的一个替换索引blob散列。详情请参见thegit update-index
documentation。您应该能够使用--cacheinfo
,尽管我还没有用未合并的索引条目测试过它。git update-index
。如果没有第二阶段的条目,使用git update-index
来删除这些条目(使用0
来删除模式,以及任何内容,包括全零哈希值;如果模式为0,则散列是不相关的)。对所有
pom.xml
路径执行此操作后,任何剩余的非零stage索引条目都表示应该将合并冲突传递回用户。否则,你可能已经准备好了。(快速浏览一下http://gitpython.readthedocs.io/en/stable/reference.html#module-git.index.base,就会发现在GitPython中可以很容易地做到这一点,但我没有使用它的经验。
最后警告:我完全没有使用Maven的经验,但我认为
pom.xml
文件是控制各种事情的XML文件,Git合并得很差(最后一种情况几乎适用于所有XML文件)。不过,我一点也不清楚,仅仅使用“我们的”版本是正确的。