为什么mercurial中的这些命令会创建一个新头?

时间:2015-05-27 16:06:19

标签: 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.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 

2 个答案:

答案 0 :(得分:1)

让我们一步一步地采取这些步骤并解释会发生什么:

步骤1-2:克隆存储库,并将工作文件夹更新到提示,然后输入该文件夹。

步骤3-5:提交另一个变更集,创建一个新的小费(但不是另一个头)。

步骤6-8:将第一个存储库克隆为新存储库,同时更新其中的工作文件夹,然后输入该文件夹。

步骤9-10:在第二个克隆中提示另一个变更集。

步骤11:将此新变更集推送到原始来源。因此,我们克隆来创建first的存储库现在除了在步骤1中克隆的存储库之外,还有一个变更集。

步骤12:返回第一个存储库

步骤13-15:在第一个变更集的上方提交另一个变更集。

步骤16:从原始源拉出,这里我们引入我们在第二个克隆中首先添加的变更集,然后在上面的步骤11中推送。这将使我们的first存储库现在有两个头。

步骤17-19:在前一个变更集之上提交另一个变更集,这不会创建另一个变更集,我们只是用另一个变更集“扩展”该变量集。

步骤20:推送到原始源,强制推送,这将推送新的更改集并在远程存储库中创建另一个头。

现在,为什么会发生这种情况并且确定

首先,好吗?当然是。好吧,有点。在本地存储库中创建其他头部既可以,也可以推荐。例如,如果你发现你前一段时间引入了一个bug,推荐的修复方法是首先更新回导入bug的变更集,然后将bug修复到工作文件夹中,然后在bug之上提交bug修复。原始变更。

上面的“类型”来自于在推动之前应该在本地解决额外的头部这一事实。您几乎不应该其他头部推送到远程存储库中。因此,-f hg push参数最好不要单独使用。

修复额外头部的正确方法是合并,这需要两个父项并将这两个并行分支中引入的更改合并为一个头。

那么,为什么会发生这种情况?那么,学习它的最好方法就是阅读分布式版本控制系统的工作原理。

简而言之,如果您将存储库克隆到本地计算机,然后在本地工作,同时其他人工作并将他们自己的新变更集推送到您克隆的存储库中,那么最终当您尝试推动你将被告知这会引入额外的头,这是不好的。

要解决这个问题,你应该拉动,并在你重新尝试推动之前将头部与被拉下的头部合并(头部将包含其他人在此期间贡献的新变更集)。

答案 1 :(得分:1)

步骤1-5使主存储库和第一存储库处于以下状态,假设r1-r3是main的原始状态:

Main:  r1--r2--r3

First: r1--r2--r3--r4

步骤6-11将第一个复制到第二个,将某个东西提交到第二个,然后将其推回到main:

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步从主要内容拉到第一个,引入了丢失的r5,但请注意r6r5具有相同的父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,并在那里创建一个分支:

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