Git合并: "deleted by us"

38
我正在进行一次大的合并操作。 在我的分支中已经从仓库中删除了很多文件,我想在合并时保留这些文件的删除更改。 还有一些文件需要显式地合并,我打算使用git mergetool来合并它们。
我希望保留所有已删除文件的“deleted by us”更改(即这些文件应该保持删除状态)。对于其他合并冲突,我想自己解决。
是否有一种方法告诉git保留已删除的文件?

4
如果正在进行合并操作,使用git rm命令可以解决问题。 - Amber
本地删除了多少个文件,但在远程上没有删除? - Tim Biegeleisen
1
@Amber:git rm 对每个文件都会输出“(文件名):需要合并”的信息。 - kris
@TimBiegeleisen: 1082个文件。 - kris
@user1290746 我猜测 git rm 已经完成了你想要的操作,你只需要提交结果即可。 - Amber
显示剩余4条评论
6个回答

21

以下是部分解决方案:

  1. 手动解决所有未删除的合并冲突,这是必须做的。

  2. 键入 git diff --name-only --diff-filter=U 以获取所有剩余文件冲突的列表。这些文件必须是您想要删除的文件。将已删除文件的列表保存为 filesToRemove.txt

  3. 然后执行 cat filesToRemove.txt | xargs git rm 删除所有文件。


6
如果你确信 git diff 命令的列表是正确的,你可以跳过临时文件,直接运行 git diff --name-only --diff-filter=U | xargs git rm - Ryan Pavlik

18

一行代码解决:

git diff --name-only --diff-filter=U | xargs git rm

解释:

首先解决冲突的修改文件并将它们添加到暂存区,然后使用diff-filter命令删除剩余未合并的文件。这里有文档(man git-diff):

   --diff-filter=[(A|C|D|M|R|T|U|X|B)...[*]]

Select only files that are Added (A), Copied (C), Deleted (D), Modified (M), Renamed (R), have their type (i.e. regular file, symlink, submodule, ...) changed (T), are Unmerged (U), are Unknown (X), or have had their pairing Broken (B). Any combination of the filter characters (including none) can be used. When * (All-or-none) is added to the combination, all paths are selected if there is any file that matches other criteria in the comparison; if there is no file that matches other criteria, nothing is selected.

Also, these upper-case letters can be downcased to exclude. E.g. --diff-filter=ad excludes added and deleted paths.

Note that not all diffs can feature all types. For instance, diffs from the index to the working tree can never have Added entries (because the set of paths included in the diff is limited by what is in the index). Similarly, copied and renamed entries cannot appear if detection for those types is disabled.


3
每当您需要多次按相同的键时,您可以将yes d的输出导入到git rm中。 - Gunchars
2
这是不正确的,因为它将删除所有冲突的文件 - 不仅是由我们删除的,还包括修改过的等。 - Ders
理想情况下,在删除差异文件之前,您应该先解决冲突。这有助于捕捉错误并查看所需内容。您可以随时阅读手册并根据需要进行修改:--diff-filter=[(A|C|D|M|R|T|U|X|B)...[*]]:仅选择已添加(A),已复制(C),已删除(D),已修改(M),已重命名(R),其类型(即常规文件,符号链接,子模块等)已更改(T),未合并(U),未知(X)或已破坏其配对关系(B)的文件。可以使用任何过滤字符的组合(包括无)。 - Shubham Chaudhary

9
您可以通过将编辑后的文件重新添加回来,并再次提交它们来解决此问题:
git add .

或者
git add -A

提交更改

git commit

如果您想通过删除文件来解决冲突,您需要运行git rm而不是git add
参见:从命令行解决合并冲突

3
首先,发起合并以进入冲突状态。
然后尝试这样做:
git status | grep 'deleted by us' | sed 's/deleted by us: //' | xargs git rm

如果你想知道它是如何工作的,你可以事先按命令构建它:
git status
git status | grep 'deleted by us'
git status | grep 'deleted by us' | sed 's/deleted by us: //'

请参阅 git statusgrepsedxargs 的手册页。

1

我会留下这个问题,因为我相信一定有一个好的答案,同时我也做了以下操作:

  1. 执行 git status 命令,查看被删除的文件列表 (1082) 和那些产生合并冲突的文件数量 (3)
  2. 使用文本编辑器手动编辑那三个出现合并冲突的文件,并执行 git add
  3. 创建一个文本文件,每行只包含字母 "d",没有其他内容,对应那 1082 个被删除的文件 (d.txt)
  4. 执行命令 git mergetool < d.txt

虽然不够优雅,但比按下 "d" 键并回车 1082 次更快


1
我现在正在与完全不同的事情苦苦挣扎,当我意识到你在写这个答案之前计算了按下回车键的次数时,我笑了。如果这是在 Reddit 上,我会给你一个金牌。 - Irfan Harun

0

我也注意到了

abc.txt:需要合并

在尝试时

git rm abc.txt

在挑选樱桃并看到文件处于“已被我们删除”的状态后。

我最终通过以下方式解决了删除的问题:

git add abc.txt
rm abc.txt
git add abc.txt

这将abc.txt添加到暂存区(实际上是重新创建了“被我们删除”的文件。(解决了冲突状态)

然后从文件系统中删除文件

然后将文件已经不存在的事实添加到暂存区。

可能有一些shell技巧可以在你的1000多个文件集上运行这3个命令而不会有太多麻烦。

可能有更好的处理方法,但由于git rm abc.txt对我们的情况没有按预期工作,我想分享一组替代命令,似乎可以在不使用合并工具的情况下工作。


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