ChatGPT解决这个技术问题 Extra ChatGPT

如何在 Git 中手动合并所有文件?

我想用 meld 或任何其他差异工具手动合并所有文件,我该如何用 Git 做到这一点?
当我运行 git mergetool 时,它会显示 no files need merging。所以我想只有当我有冲突时我才能做到。

请向我们提供一些您想要合并的内容以及您不希望自动完成的原因。
我想合并文本文件
是的,我想在某些情况下手动合并,因为在这种情况下,我知道一切都按我的意愿进行,而不是应用程序决定的
如果发生自动合并和修复问题呢?
@TomaszWysocki,因为我无法知道是否出现了“人类认为有问题的问题”。我只有一种方法可以知道是否出现了“被 git 视为有问题的问题”。 Git 会自动合并文件,我不会勾选所有 git 的自动决策结果。它可以决定做出我不喜欢的特定更改。我想在进行所有更改之前批准它们。

s
skywinder

有更简单的方法:

git merge --no-commit merge_branch

正如男人所说:

使用 --no-commit 执行合并,但假装合并失败并且不自动提交,让用户有机会在提交之前检查并进一步调整合并结果。


谢谢你。是否有一种方法可以使用 mergetool/meld 以一个不错的三向界面逐段查看和合并更改?
通过添加 --no-ff 禁用快速转发,如果没有冲突就会发生这种情况。
当然,如果有冲突,请使用 git mergetool
这仍然是一个自动合并,所以这不能回答起源问题。
N
NSjonas

我有一个场景:

git merge --no-commit merge_branch 

只是引起了快进。

如果发生这种情况,您可以使用:

git merge --no-commit --no-ff merge_branch

然后您就可以查看您的更改


可以用同样的方法拉吗?如果无法进行快进,我需要手动验证所有冲突。
@Maxim 不,但因为 pull 只是 fetchmerge 的组合,所以先调用 git fetch merge_branch 然后再调用 merge
同时使用 --no-commit --no-ff 就像在包含 * -merge 的根目录中拥有 .gitattributes 文件,但每个 merge 选择是否使用它
运行时我得到 Automatic merge went well; stopped before committing as requested。当我尝试运行 git mergetool 时,它显示 No files need merging
只是推测这种方法实际上就像从另一个源复制文件(例如,从这个存储库中克隆一个当前分支'merge_branch'并清理)。在这种情况下,我希望只有 'git difftool' 显示任何更改。
C
Community

一个类似的问题是How to prevent an automerge using git?

FractalSpace 给出了一个我认为有用的答案:

$ git checkout master
$ git difftool -t kdiff3 local-branch HEAD

这个想法是使用 difftools 而不是自动合并工具来手动选择您需要的内容并创建新文件。


我添加了一个答案,将此答案与 git merge 答案进行了比较,以帮助任何偶然进入此页面的人澄清事情。
当我尝试以这种方式与 kdiff3 或 meld 手动合并时,它会将更改保存到 /tmp 中的临时文件中,并且不会更改工作目录。但我需要将更改存储到工作目录。
历史可能会在这里迷失。这也不会像合并的分支一样显示出来。对于 git 来说,这可能看起来像是一个巨大的虚空提交。
s
stevegt

对于只需要对合并进行微观管理的任何人,请跳至下面的混合部分。

如果有人想知道 @True 使用 git difftool 的答案与使用 git merge 的其他答案之间的区别,请参阅 Git mergetool vs difftool

以下是更多详细信息:

差异工具

如果您已将 git 配置为使用现代 diff.tool,例如 kdiff3、meld 或 vimdiff,您将能够使用该 diff 工具手动合并,并且命令行可以很简单:

git difftool other_branch

...这将让您在当前分支和 other_branch(在 man git-config 中描述为 $LOCAL 和 $REMOTE)之间进行双向手动合并。

合并工具

其他答案讨论的“正确”方式是将git配置为使用例如kdiff3或vimdiff作为您的merge.tool,并使用:

git merge --no-commit --no-ff other_branch
git mergetool

...此命令可以在 $BASE、$LOCAL 和 $REMOTE 之间进行 N 路手动合并到 $MERGED。有关如何配置 git 的一个示例,请参阅 https://stackoverflow.com/a/2235841/1264797。如果您使用 git 已经知道的工具之一,那么您根本不需要配置 mergetool.*.cmd 条目。 (Meld 只能显示三个窗格,因此如果使用默认设置的 meld,您将看不到 $BASE。)

差异工具与合并工具

有人可能会站出来纠正我,但上述 difftoolmergetool 技术之间的主要区别似乎是:

如果相应配置,mergetool 可以进行 N 路合并

mergetool 在新提交中添加 other_branch 作为父级,因此历史记录可以正常工作

difftool 让您可以手动查看和选择每个更改的行,但是您失去了 mergetool 的上述两个好处

混合动力——两全其美

结合合并和差异的方法看起来像这样:

git merge --no-commit --no-ff other_branch
git mergetool
git difftool HEAD
git commit

...这会进行 N 路合并以解决冲突并使历史记录正常工作,然后向您显示完整的差异集,以便您可以在提交之前查看和调整。


当我尝试以这种方式与 kdiff3 或 meld 手动合并时,它会将更改保存到 /tmp 中的临时文件中,并且不会更改工作目录。但我需要将更改存储到工作目录。
@porton您可能需要做更多的实验,但是其中一个窗格应该是工作目录文件,或者应该是退出后自动复制到工作目录中的文件。我不记得是哪个,它可能取决于你的 git 版本和工具配置。
M
Myridium

我发现其他答案不令人满意,并且在寻找答案时感到沮丧。我终于在这里找到了这个问题的解决方案:https://stackoverflow.com/a/11593308/1351182

如果您运行这些命令,您将创建一个新的提交,它基本上采用 branchToMergeFrom 的最新提交,并允许您在其上应用补丁,我认为这就像在顶部的附加提交。

git checkout branchToMergeTo
git checkout --patch branchToMergeFrom [file]

然后将提示您(如果您没有指定 file,则逐个文件)提示您要合并哪些“大块”。通过这种方式,它会引导您完成 自动 合并过程的每个部分,而是要求手动仲裁您希望从 mergefrom 分支接受哪些点点滴滴。这是我的项目中的示例:

@@ -249,7 +251,8 @@ def draw_everything():
  
     draw_bg()
     draw_balls(ax)
-    plt.show(block=False)
+    if show:
+        plt.show(block=False)
 
 def advance(ms, accel_fun, collision_matrix_fun):
     global balls
(3/6) Apply this hunk to index and worktree [y,n,q,a,d,K,j,J,g,/,e,?]?

输入 y<Enter> 后,我看到了下一个大块,即该文件的 (4/6)。底部的这个提示让您只需用 y 接受合并“hunk”,用 n 拒绝它,甚至可以手动编辑它。以下是选项:

y - apply this hunk to index and worktree
n - do not apply this hunk to index and worktree
q - quit; do not apply this hunk or any of the remaining ones
a - apply this hunk and all later hunks in the file
d - do not apply this hunk or any of the later hunks in the file
g - select a hunk to go to
/ - search for a hunk matching the given regex
j - leave this hunk undecided, see next undecided hunk
J - leave this hunk undecided, see next hunk
K - leave this hunk undecided, see previous hunk
s - split the current hunk into smaller hunks
e - manually edit the current hunk
? - print help

我想进去手动编辑一个大块,因为我不想完全按照它的姿势接受或拒绝合并。所以我选择了 e 并获得了一个要编辑的文件。当我注意到底部甚至有关于如何正确编辑大块的说明时,我很高兴。您甚至可以使用上面的 s 选项将大块分割成更小的块。

如果你想要的是手动合并,我会推荐这个过程,你仍然尽可能地利用自动过程。不同之处在于您可以监督每个合并“大块”并随意编辑它们。我希望这对未来的读者有所帮助。

在此过程之后,您可能希望运行 git checkout branchToMergeTo && git merge branchToMergeFrom 以便将 branchToMergeFrom 的历史正式合并到 branchToMergeTo 中。


C
Community

请注意,如果您坚持手动合并(可能针对某一类文件),您仍然可以定义一个合并驱动程序
Git - how to force merge conflict and manual merge on selected file”中有一个具体示例。

这样,您的合并驱动程序脚本可以调用您想要的任何合并工具。


T
Tomasz Janicki

我选择我们的策略(它也作为 TortoiseGit 中的一个选项存在),在进行手动差异之后,您已经手动引入了您想要的更改。

来自:https://git-scm.com/docs/merge-strategies

合并机制(git merge 和 git pull 命令)允许使用 -s 选项选择后端“合并策略”。一些策略也可以采用自己的选项,可以通过将 -X 参数传递给 git merge 和/或 git pull 来传递。 ours 这解决了任意数量的头,但合并的结果树始终是当前分支头的树,有效地忽略了所有其他分支的所有更改。它旨在用于取代分支的旧开发历史。请注意,这与“递归”合并策略的 -Xours 选项不同。

然而,Bitbucket 稍后看到的内容对我来说是个谜,它将提交识别为合并但未能实际合并分支(不解决拉取请求) - 可能 Bitbucket 大师可以帮助解决这个问题,我什至不能给你任何日志/错误消息,因为我没有那种可见性 - git/TortoiseGit 一点也不抱怨。