执行此特定合并会删除公共提交而不是重新应用它们吗?

Will doing this particular merge delete the common commits instead of re-applying them?

我一直在阅读这里的一篇文章:https://medium.com/anitab-org-open-source/how-i-managed-to-not-mess-up-my-git-history-thanks-to-git-pull-rebase-fed452c661f0

根据我的理解,她有以下结构(请原谅粗略):

她陈述了以下问题:

What if X approved task 2 and merged it first then review task1 and merged it after? Remember that task 1 has no additional codes that task 2 has since it was the preceding task. To make more sense, think of it with task 2 as the Register functionality and task 1 as the basic setup. Basic setup branch won’t have the Register files since I didn’t write that functionality on task 1. If this task 1 branch is to be merged after task 2, wouldn’t it cancell out (delete) the register folder/file that got merged by task 2 from the first merge? How can we prevent this?

这是令我困惑的一句话:

"If this task 1 branch is to be merged after task 2, wouldn’t it cancell out (delete) the register folder/file that got merged by task 2 from the first merge?"

AFAIK,如果 task2 合并到 master,它将占用连接它的整个路径直到 master 并将所有路径合并到 master.

task1 将只有 2 个未与 master 合并的提交(将这些斜线视为提交 ID)。如果我们之后合并task1,它应该不会有任何问题。

或者,如果 task#1 没有任何额外的提交,那么合并 task#1 不会导致任何问题,不是吗?

如果我们合并 task1,提交将不会被“取消”或“删除”。正确吗?

让我们逐一解答您的问题。

AFAIK, if task2 is merged to master, it'll take that entire path that connects it until master and merge all that to master.

正确。生成的历史记录如下所示:

o---o--------------M (master)
    \             /
     o---o---o---o (task2)
              \
               o---o (task1)

task1 would only have 2 commits that aren't merged with master. If we merge task1 afterwards, it shouldn't have any problems whatsoever.

也正确。根据 task1 中的更改,可能存在一些合并冲突,但没有什么异常。生成的历史记录如下所示:

o---o--------------M---N (master)
    \             /   /
     o---o---o---o   / (task2)
              \     /
               o---o (task1)

Or, if task1 didn't have any extra commits then merging task1 wouldn't lead to any problems, wouldn't it?

没有。 Git 会从字面上告诉你 Already up-to-date. 然后就此结束。

It's not like commits will be "canceled out" or "deleted" if we merge task1. Correct?

你是对的,提交永远不会被合并删除。但是,文件可能。这取决于它们是否被正在合并的提交之一主动从索引中删除。

你看,你引用这篇文章的说法的根本问题是:

If this task1 branch is to be merged after task2, wouldn’t it cancel out (delete) the register folder/file that got merged by task2 from the first merge? How can we prevent this?

当您进行合并时,Git 将与您正在合并的提交相关联的树与它们的第一个共同祖先(称为 merge base)进行比较。如果在合并一侧的提交之一中删除了共同祖先中存在的文件,那么是的,该文件将在生成的合并中删除。

回到我们的例子:

o---o--------------M-----N (master)
    \             /     /
     o---o---o---o     / (task2)
         ^    \       /         
      foo.txt  o---o (task1)
                   ^
            deletes foo.txt
                    

如果 foo.txt 存在于 task2task1 之间的共同父级中,并且 task1 删除了它,那么 foo.txt 将在合并中删除提交 N。值得注意的是,如果 task2task1 的分叉点之后修改了 foo.txt,那么您将遇到合并冲突。

现在,如果 task2 创建了 foo.txt,合并 task1 不会在 master 中删除它,因为 foo.txttask1 中不存在:

o---o--------------M--------N (master)
    \             /        /
     o---o---o---o        / (task2)
              \  ^       /
               \ creates foo.txt
                \      /         
                 o---o (task1)

在这种情况下,foo.txt 将存在于合并提交中 N

如果您想知道合并两个分支后生成的树会是什么样子,可以使用 merge-tree 命令。例如:

git merge-tree $(git merge-base master task2) master task2

这将打印出合并 mastertask2 后生成的树中包含的文件的路径。