Version control 为什么mercurial中的这些命令会创建一个新的头部?
作为一项任务,我被要求找出以下哪一行导致了磁头数量的变化,现在我检查并看到第16行和第20行将新磁头添加到了它们的存储库中,但我不太清楚原因。。我知道当发生冲突时,号码会改变,但这里有点不清楚 有人能帮我理解吗?:) 谢谢Version control 为什么mercurial中的这些命令会创建一个新的头部?,version-control,mercurial,Version Control,Mercurial,作为一项任务,我被要求找出以下哪一行导致了磁头数量的变化,现在我检查并看到第16行和第20行将新磁头添加到了它们的存储库中,但我不太清楚原因。。我知道当发生冲突时,号码会改变,但这里有点不清楚 有人能帮我理解吗?:) 谢谢 1: /home/user> hg clone http://remoteserver/mainrepository first 2: /home/user> cd first 3: /home/user/first> echo one > a.t
1: /home/user> hg clone http://remoteserver/mainrepository first
2: /home/user> cd first
3: /home/user/first> echo one > a.txt # Create a new file a.txt containing “one”
4: /home/user/first> hg add a.txt
5: /home/user/first> hg commit -m "Added a file"
6: /home/user/first> cd ..
7: /home/user> hg clone first second
8: /home/user> cd second
9: /home/user/second> echo two >> a.txt # Append a line to a.txt containing “two”
10: /home/user/second> hg commit -m "Modified a file"
11: /home/user/second> hg push -f http://remoteserver/mainrepository
12: /home/user/second> cd ../first
13: /home/user/first> echo more > b.txt # Create a new file b.txt containing “more”
14: /home/user/first> hg add b.txt
15: /home/user/first> hg commit -m "Added another file"
16: /home/user/first> hg pull # default pulls from where repo was cloned
17: /home/user/first> echo ‘‘even more’’ > c.txt # Create a new file c.txt
18: /home/user/first> hg add c.txt
19: /home/user/first> hg commit -m "Added yet another file"
20: /home/user/first> hg push -f
让我们一次一组地执行这些步骤,并解释会发生什么: 步骤1-2:克隆存储库,将工作文件夹更新为tip,然后输入该文件夹 步骤3-5:提交另一个变更集,创建一个新的提示(但不是另一个头部) 步骤6-8:将第一个存储库克隆到一个新的存储库中,同时更新该存储库的工作文件夹,然后输入该文件夹 步骤9-10:在第二个克隆的tip顶部提交另一个变更集 步骤11:将此新变更集推送到原始源中。这个存储库是我们从中克隆来创建
的第一个
,因此,除了我们在步骤1中克隆的那些存储库之外,现在还有一个变更集
步骤12:返回到第一个存储库
步骤13-15:在第一个变更集中提交当前变更集之上的另一个变更集
第16步:从原始源中提取,这里我们引入了我们首先在第二个克隆中添加的变更集,然后在上面的第11步中推送。这将使我们的第一个存储库现在有两个头
步骤17-19:在前一个变更集的基础上提交另一个变更集,这不会创建另一个头部,我们只是用另一个变更集“扩展”该头部
步骤20:推送到原始源,强制推送,这将推送新的变更集并在远程存储库中创建另一个头
现在,为什么会发生这种情况,这样可以吗
首先,好吗?是的,当然。嗯,有点。在本地存储库中创建其他头是可以的,建议这样做。例如,如果您发现前一段时间引入了一个bug,建议的修复方法是首先更新回引入该bug的变更集,然后在工作文件夹中修复该bug,然后在原始变更集上提交该bug修复
上述“类型”来自于这样一个事实,即在推动之前,应在局部解决额外的水头。您几乎不应该将其他磁头推入远程存储库。因此,最好不要使用-f
参数hg push
修复额外头部的正确方法是合并,这需要两个父级并将在这两个并行分支中引入的更改合并回一个头部
那么,为什么会发生这种情况?好的,了解这一点的最好方法就是阅读分布式版本控制系统是如何工作的
简而言之,如果您将存储库克隆到本地计算机,然后在本地工作,同时其他人也在工作,并将自己的新变更集推送到您克隆的存储库中,那么最终当您尝试推送时,您会被告知这会引入额外的头,这是不好的
要解决此问题,您应该在重新尝试推送之前,将您的头与被拉下的头合并(该头将包含其他人同时参与的新变更集)。步骤1-5将主存储库和第一个存储库保持在以下状态,假设r1-r3是main的原始状态:
Main: r1--r2--r3
First: r1--r2--r3--r4
步骤6-11将第一个复制到第二个,将某些内容提交到第二个,并将其推回到主目录:
Main: r1--r2--r3--r4--r5
First: r1--r2--r3--r4
Second: r1--r2--r3--r4--r5
步骤12-15返回第一步并再次提交:
Main: r1--r2--r3--r4--r5
First: r1--r2--r3--r4--r6
Second: r1--r2--r3--r4--r5
步骤16将main拉入第一个,引入缺少的r5
,但请注意r6
和r5
都具有相同的r4
父级,因此这将创建一个分支:
Main: r1--r2--r3--r4--r5
First: r1--r2--r3--r4--r6
\-----r5
Second: r1--r2--r3--r4--r5
步骤17-19首先创建另一个提交:
Main: r1--r2--r3--r4--r5
First: r1--r2--r3--r4--r6------r7
\-----r5
Second: r1--r2--r3--r4--r5
步骤20强制推回干管,并在干管处创建分支:
Main: r1--r2--r3--r4--r5
\-----r6--r7
First: r1--r2--r3--r4--r6------r7
\-----r5
Second: r1--r2--r3--r4--r5
相反,更好的做法是首先在本地进行合并,这样主存储库就不会剩下两个头。因此,在步骤19和20之间,执行hg merge
,然后执行hg push
,而不使用-f
强制。结果将是:
Main: r1--r2--r3--r4--r5----------m8
\-----r6--r7-/
First: r1--r2--r3--r4--r6------r7--m8
\-----r5-----/
Second: r1--r2--r3--r4--r5