Git合并不合并所有文件

Rob*_*bin 1 git

我在使用git时遇到了困难。

我有一个分支A和一个分支B。我想将branch合并A为branch B。我目前在分支机构,B并且使用了以下命令:

git merge A

现在,当我运行时git status,我看到我先进行了两次提交,当我查看在git mergeI 期间被更改的文件时,我注意到只有两个文件被更改了。但是,我知道分支A中至少有十几个文件被更改了,这些文件在期间没有被获取git merge

为什么git merge仅在显然还有其他文件需要合并时才合并这两个文件?

tor*_*rek 5

比较两个分支技巧的提交是错误的事情,因为那不是git merge事实。

要查看每个人更改了哪些文件,必须首先找到分支AB最近共享的提交

             o--o   <-- branch-B
            /
...--o--o--*
            \
             o--o--o   <-- branch-A
Run Code Online (Sandbox Code Playgroud)

(其中每个回合o代表一次提交,随着时间的推移,人们在提交链中添加的次数)。

我在这里标记的通用提交*就是Git称为两个分支的合并基础。当您坐在两个分支(例如B)之一的顶端并运行时,Git会自动自动找到该提交git merge A

然后,Git将比较,而不是Bvs AAvs B,而是:

git diff hash-of-* hash-of-tip-of-B    # what did *we* change?
Run Code Online (Sandbox Code Playgroud)

和:

git diff hash-of-* hash-of-tip-of-A    # what did *they* change?
Run Code Online (Sandbox Code Playgroud)

的目标git merge是找到并提取commit *,从两个分支应用所有更改,并将其作为当前分支()上的新合并提交(带有两个父提交)进行提交,使其成为合并提交,以便Git知道要执行的操作。下次也用作合并基础。B

如果要查看commit的哈希ID *,可以运行git merge-base

git merge-base --all A B
Run Code Online (Sandbox Code Playgroud)

然后git diff,您可以运行,为其提供用于合并基础的哈希ID,以及A用于选择分支尖端A以查看其更改的名称。您可以运行第二个分开的,git diff,给它,对于合并基础,而名称相同的哈希ID B选择分支的末端B,看看有什么改变(你可能还记得你改变什么,但它是一个好主意,看看Git的同意你的记忆,因为Git是要使用什么认为,你不记得什么!)。

有一个速记可以git merge-base为您运行,仅适用于git diff

git diff A...B   # note the three dots
Run Code Online (Sandbox Code Playgroud)

会将和的合并基础AB标识的提交进行比较B,以查找所做的更改。后续:

git diff B...A   # note the three dots again
Run Code Online (Sandbox Code Playgroud)

将比较的合并基础BA1对提交的鉴定A,找到什么他们改变。

(你可以添加选项--name-status--name-onlygit diff影响如何git diff显示其计算更改/发现。需要注意的是,每当有涉及重命名,合并使用相当于git diff -M50找到了重命名。现代Git的,因为2.9,使在重命名检测git diff作为默认情况下很好。)


1 “合并基数”是对称图操作,因此,根据定义,“ A和B的合并基数”等于“ B和A的合并基数”。

  • 这没有提供如何使两个分支合并所有文件的解决方案。它只是告诉我 git 有时是一个令人费解且不直观的混乱。 (11认同)
  • 假设您将分支 A(主线)恢复到其第一个提交,并且您希望将分支 B(newMainline)中的所有内容都作为分支 A 上的下一个新提交。常识表明“git merge”应该是第一个尝试的工具,但是那不是应该使用的吗?对于这种情况,什么是正确的工具? (2认同)