Git何时能成功合并与冲突?

Git何时能成功合并与冲突?,git,Git,如果我有一个新的clean project master,并且我添加了一个包含以下内容的新文件: Master:test.txt 现在,我正在创建一个名为MyBranch的新分支,然后更改文件的内容: MyBranch:test.txt 现在我想合并Mybranch->Master 在这种情况下,我不知道这是成功的合并还是冲突。 我看到过这样的情况:冲突和合并成功,但仍然没有找到黄金法则 问题: git何时会与成功合并产生冲突?git在同一段代码中的不同分支之间进行了两次编辑时会产生冲突 在您的

如果我有一个新的clean project master,并且我添加了一个包含以下内容的新文件:

Master:test.txt

现在,我正在创建一个名为MyBranch的新分支,然后更改文件的内容:

MyBranch:test.txt

现在我想合并Mybranch->Master

在这种情况下,我不知道这是成功的合并还是冲突。 我看到过这样的情况:冲突和合并成功,但仍然没有找到黄金法则

问题:


git何时会与成功合并产生冲突?

git在同一段代码中的不同分支之间进行了两次编辑时会产生冲突

在您的情况下,因为您在Mybranch中只进行了一次编辑,所以在合并时不会发生冲突

如果主服务器上有一个新的提交,在您尝试合并之前,我将文本更改为987并提交了该代码,那么我们将发生冲突


有用资源:

当在同一段代码中的不同分支上进行了两次编辑时,git会引发冲突

在您的情况下,因为您在Mybranch中只进行了一次编辑,所以在合并时不会发生冲突

如果主服务器上有一个新的提交,在您尝试合并之前,我将文本更改为987并提交了该代码,那么我们将发生冲突


有用资源:

一般来说,当两个分支具有某个共同祖先时,每个分支对于给定数量的行具有不同的更改集时,会发生冲突

所以。。。。如果你有一个共同的祖先a,那么分支B和C,从a到B,你从一个文件中删除了5行。。。在A和C之间,你修改了这五行中的任何一行,你会得到一个冲突。冲突有很多种。一种方式修改了5行,另一种方式修改了相同的5行。。你合并了,轰!还有其他类型的冲突,如:在一个文件上编辑5行。。。已删除另一个分支上的文件。合并:轰


如果在一个分支上有一组更改,而在另一个分支上没有更改,则不会发生冲突。

一般来说,如果有两个具有某个共同祖先的分支,则每个分支对于给定数量的行都有一组不同的更改,则会发生冲突

所以。。。。如果你有一个共同的祖先a,那么分支B和C,从a到B,你从一个文件中删除了5行。。。在A和C之间,你修改了这五行中的任何一行,你会得到一个冲突。冲突有很多种。一种方式修改了5行,另一种方式修改了相同的5行。。你合并了,轰!还有其他类型的冲突,如:在一个文件上编辑5行。。。已删除另一个分支上的文件。合并:轰

如果在一个分支上有一组更改,而在另一个分支上没有更改,则不会有冲突。

因为,尽管不是用同样的话来说,这里的技巧是合并不是有两个输入,而是有三个输入

您将您的流程描述为:

在主服务器上创建新的提交 创建新分支MyBranch 在MyBranch上创建新的提交 运行:

但发展趋势并非如此。它通常更像:创建三个分支,开始处理它们,再创建六个,处理其中一些分支,删除一些分支,创建其他分支,处理几个分支一段时间,然后最终签出一个分支并在另一个分支上运行git merge。这种更加混乱的工作流程会导致合并过程的输入更加复杂,正如我前面提到的,合并过程实际上由三个提交组成

在这三个提交中,您只能选择两个。第三个,Git自动为您选择

让我们花一点时间回顾一下使用图形创建新提交的过程。你:

git checkout somebranch
<edit various files>
git add <some edited files>
git commit
其中,每个字母代表一个实际提交哈希ID。最新提交H的父级为提交G;G的父级是F,依此类推,向后,沿着分支中包含的提交行

编辑文件时,将更改工作树副本。然后,您必须使用git添加这些内容以将这些更改复制回索引git commit使用建议提交的索引,文件处于特殊的git化冻干状态,而不是正常的日常形式的工作树文件,可供常规非git程序使用。最后一步,git commit,将所有文件的索引副本打包,不仅包括您更改的文件,还包括由于commit H而在索引中未更改的所有文件,并将它们存储到新的commit中,在新的commit中它们将一直冻结,以便将来任何时候都可以返回新的commit

让我们称这个新的提交为I。I的父级将是H:

我们不再需要图纸上的扭结了

因此,对于您的特定流程,您选择的分支是master,并且您添加了一个新的提交:

...--F--G--H--I   <-- master
现在我们还需要一件物品 r图纸。Git如何知道在这里使用哪个分支名称?答案是Git在其中一个分支名称上附加了特殊名称HEAD,所有大写字母都是这样。这就是您所在的分支,在git状态的描述中,当它在branch master或branch MyBranch上显示时。假设您创建并进入MyBranch,以便我们:

...--F--G--H--I   <-- master, MyBranch (HEAD)
                K--L   <-- master (HEAD)
               /
...--F--G--H--I
               \
                J   <-- MyBranch
请注意,头部仍附着在更新的分支上

现在可以运行git checkout master了;git merge Mybranch,但是这个合并不是很有趣。这太琐碎了。这里永远不会有任何合并冲突。事实上,默认情况下,GitMerge会注意到不需要合并,而是执行快进。您必须运行git merge-no ff来强制它进行真正的合并,这将非常顺利

首先,让我们在master上进行新的提交,而不是现在进行合并。实际上,为了使合并得到字母M,让我们对master进行两次提交,这样我们就有:

...--F--G--H--I   <-- master, MyBranch (HEAD)
                K--L   <-- master (HEAD)
               /
...--F--G--H--I
               \
                J   <-- MyBranch
比较commit I和commit J。无论这里有什么不同,它们都可以,我们在MyBranch上更改了:

合并使用的commit I不是直接记录的,而是隐含的:commit L和J的合并基数是I,并且永远都是,因为任何commit中的每一位信息都会一直冻结。事实是L的父母是K,K的父母是I,例如:这些事实是不能改变的。M的父母现在是L和J,这些不能改变。任何提交的任何部分都不能被更改:最多,我们可以进行新的、改进的和不同的提交,只是停止使用旧的提交,但我们不能更改旧的提交

当事情进展不顺利时,会出现合并冲突。例如,如果从I到J的差异表示将test.txt文件的第10行从ABC更改为XYZ,从I到L的差异表示将test.txt文件的第10行从ABC更改为AEIOU,则这些更改会发生冲突。Git将:

将索引中的所有三个输入文件保留在特殊的高编号暂存槽中,我们将不在这里介绍,然后 在工作树中保留一个混乱的、合并冲突版本的文件,您可以在其中查看和处理该文件。 合并没有结束,但也没有完成。有一个未完成合并的事实现在记录在两个地方:

在索引中,因为占用了非零暂存插槽;和 在包含commit J的散列ID的文件中,以便最终的合并使提交步骤知道将哪个散列ID包含为另一个父级。第一个父L哈希ID始终通过HEAD可用。 您的任务是:为该文件生成正确的组合,并将其写入暂存槽0处的索引中,以宣布该文件已解析。git add命令将负责第二部分,即写入索引,但您必须自己或借助合并工具提供正确的内容

解决所有冲突后,您可以运行:

git merge --continue
或:

在这种情况下,这两个命令的作用是相同的:git merge-continue确保有一个正在进行的合并可以完成,如果是这样的话,那么现在就直接运行git commit。无论如何,git for Windows的人总是将一个命令插入另一个命令,而不是运行另一个命令,因为Windows显然需要几个小时⏱ ... 好的,十分之一秒。。。将一个命令链接到另一个命令,而不是Linux上的微秒。

尽管不是用同样的话来说,这里的技巧是合并不是有两个输入,而是有三个输入

您将您的流程描述为:

在主服务器上创建新的提交 创建新分支MyBranch 在MyBranch上创建新的提交 运行:

但发展趋势并非如此。它通常更像:创建三个分支,开始处理它们,再创建六个,处理其中一些分支,删除一些分支,创建其他分支,处理几个分支一段时间,然后最终签出一个分支并在另一个分支上运行git merge。这种更加混乱的工作流程会导致合并过程的输入更加复杂,正如我前面提到的,合并过程实际上由三个提交组成

在这三个提交中,您只能选择两个。第三个,Git自动为您选择

让我们花一点时间回顾一下使用图形创建新提交的过程。你:

git checkout somebranch
<edit various files>
git add <some edited files>
git commit
其中,每个字母代表一个实际提交哈希ID。最新提交H的父级为提交G;G的父级是F,依此类推,向后,沿着分支中包含的提交行

编辑文件时,将更改工作树副本。然后,您必须使用git添加这些内容以将这些更改复制回索引git commit使用建议提交的索引,文件处于特殊的git化冻干状态,而不是正常的日常形式的工作树文件,可供常规非git程序使用。最后一步,git commit,打包了所有文件的索引副本,不仅包括您更改的文件,还包括索引中所有未更改的文件 se of commit H-并将它们存储到一个新的commit中,在那里它们一直被冻结,以便将来的任何时候您都可以返回到新的commit

让我们称这个新的提交为I。I的父级将是H:

我们不再需要图纸上的扭结了

因此,对于您的特定流程,您选择的分支是master,并且您添加了一个新的提交:

...--F--G--H--I   <-- master
现在我们需要在图纸上再添加一项。Git如何知道在这里使用哪个分支名称?答案是Git在其中一个分支名称上附加了特殊名称HEAD,所有大写字母都是这样。这就是您所在的分支,在git状态的描述中,当它在branch master或branch MyBranch上显示时。假设您创建并进入MyBranch,以便我们:

...--F--G--H--I   <-- master, MyBranch (HEAD)
                K--L   <-- master (HEAD)
               /
...--F--G--H--I
               \
                J   <-- MyBranch
请注意,头部仍附着在更新的分支上

现在可以运行git checkout master了;git merge Mybranch,但是这个合并不是很有趣。这太琐碎了。这里永远不会有任何合并冲突。事实上,默认情况下,GitMerge会注意到不需要合并,而是执行快进。您必须运行git merge-no ff来强制它进行真正的合并,这将非常顺利

首先,让我们在master上进行新的提交,而不是现在进行合并。实际上,为了使合并得到字母M,让我们对master进行两次提交,这样我们就有:

...--F--G--H--I   <-- master, MyBranch (HEAD)
                K--L   <-- master (HEAD)
               /
...--F--G--H--I
               \
                J   <-- MyBranch
比较commit I和commit J。无论这里有什么不同,它们都可以,我们在MyBranch上更改了:

合并使用的commit I不是直接记录的,而是隐含的:commit L和J的合并基数是I,并且永远都是,因为任何commit中的每一位信息都会一直冻结。事实是L的父母是K,K的父母是I,例如:这些事实是不能改变的。M的父母现在是L和J,这些不能改变。任何提交的任何部分都不能被更改:最多,我们可以进行新的、改进的和不同的提交,只是停止使用旧的提交,但我们不能更改旧的提交

当事情进展不顺利时,会出现合并冲突。例如,如果从I到J的差异表示将test.txt文件的第10行从ABC更改为XYZ,从I到L的差异表示将test.txt文件的第10行从ABC更改为AEIOU,则这些更改会发生冲突。Git将:

将索引中的所有三个输入文件保留在特殊的高编号暂存槽中,我们将不在这里介绍,然后 在工作树中保留一个混乱的、合并冲突版本的文件,您可以在其中查看和处理该文件。 合并没有结束,但也没有完成。有一个未完成合并的事实现在记录在两个地方:

在索引中,因为占用了非零暂存插槽;和 在包含commit J的散列ID的文件中,以便最终的合并使提交步骤知道将哪个散列ID包含为另一个父级。第一个父L哈希ID始终通过HEAD可用。 您的任务是:为该文件生成正确的组合,并将其写入暂存槽0处的索引中,以宣布该文件已解析。git add命令将负责第二部分,即写入索引,但您必须自己或借助合并工具提供正确的内容

解决所有冲突后,您可以运行:

git merge --continue
或:


在这种情况下,这两个命令的作用是相同的:git merge-continue确保有一个正在进行的合并可以完成,如果是这样的话,那么现在就直接运行git commit。无论如何,git for Windows的人总是将一个命令插入另一个命令,而不是运行另一个命令,因为Windows显然需要几个小时⏱ ... 好的,十分之一秒。。。将一个命令链接到另一个命令,而不是Linux上的微秒。

因此,如果目标分支中的行不是原始的,即脏的,则会发生冲突。正当如果您也将其更改为123,相同的值,但仍然脏,会引起冲突吗?这是一个很好的假设,对吗。即使您将该值更改回123,git也会查看提交的元数据,并会意识到存在一个提交更改了该行的值,即使其变脏,因此会引发冲突。等等。。。。继续你的例子,在回答中,即使你换了一行,并且没有触及123行,当我要将我的分支合并到你的时候,它还会引起冲突吗?我的意思是这是关于行已更改还是文件已更改?因此,它比这更细粒度—git将扫描并识别称为hunks的行组上的更改。如果您执行GitAdd-p,这将准确地显示git将如何识别和查找更改。我可以想象这可能是多么令人困惑,但如果您仍然感到困惑,您可能会从尝试更深入地理解合并过程的工作原理中获益。因此,我可以说,如果目标分支中的行不是原始的,即脏的,那么将发生冲突。正当
如果您也将其更改为123,相同的值,但仍然脏,会引起冲突吗?这是一个很好的假设,对吗。即使您将该值更改回123,git也会查看提交的元数据,并会意识到存在一个提交更改了该行的值,即使其变脏,因此会引发冲突。等等。。。。继续你的例子,在回答中,即使你换了一行,并且没有触及123行,当我要将我的分支合并到你的时候,它还会引起冲突吗?我的意思是这是关于行已更改还是文件已更改?因此,它比这更细粒度—git将扫描并识别称为hunks的行组上的更改。如果您执行GitAdd-p,这将准确地显示git将如何识别和查找更改。我可以想象这可能是多么令人困惑,但如果您仍然感到困惑,您可能会从尝试更深入地理解合并过程的工作原理中受益。
                K--L
               /    \
...--F--G--H--I      M   <-- master (HEAD)
               \ ___/
                J   <-- MyBranch
git merge --continue
git commit