我在两台不同的计算机上有两个目录 - 机器 A (Windows)和机器 B (OSX) - 我希望通过Mercurial同步保存这两个目录。 [*]
限制是两台机器没有通过LAN / WAN连接; 在他们之间移动数据的唯一方法是通过电子邮件。所以我想通过电子邮件发送 Mercurial捆绑,因为增量可以解决问题。
我当前的工作流程大致如此(使用本地标记lcb
作为最新的更改包):
说我在机器上工作 A 。在一天结束时,我做了:
hg commit -A -m "changes 123"
hg bundle --base lcb bundle_123.hg
hg tag --local -f lcb --rev tip
最后,我将该捆绑包发送到机器 B 。
然后坐在机器 B 我做
hg unbundle bundle_123.hg
hg merge
hg commit -A -m "remote changes 123"
hg tag --local -f lcb --rev tip
现在我正在使用机器 B ,并且在一天结束时我会执行1.中列出的内容,但是在机器上 B < / strong>即可。循环继续......
但是,我担心这个系统不够健壮:
中间更改:在创建捆绑包(步骤1)和之前远程应用时会发生什么情况(步骤2)远程计算机上发生了更改 B ?我有一个案例,它只是用新捆绑包覆盖了更改而没有冲突警告或合并建议。
捆绑双重打印:意外捆绑被施加两次会发生什么?是否需要以某种方式使用本地标签记录应用的捆绑包?
或者是否有其他更好的工作流程通过电子邮件传输Mercurial增量?
[*]从answer to a superuser question开始,我认为Mercurial可能是最可行的方式。
答案 0 :(得分:1)
初始状态
A>hg log --template "{rev}:{node|short} \"{desc}\" - files: {files}\n"
2:415231dbafb8 "Added C" - files: C.txt
1:6d9709a42687 "Added B" - files: B.txt
0:e26d1e14507e "Initial data" - files: .hgignore A.txt
B>hg log --template "{rev}:{node|short} \"{desc}\" - files: {files}\n"
1:72ef13990d0d "Edited A" - files: A.txt
0:e26d1e14507e "Initial data" - files: .hgignore A.txt
即:
相同的回购在两侧修订版1分歧:出现了独立的变化
测试案例1 - 并行更改
B中的72ef13990d0d不会干扰A中的6d9709a42687:415231dbafb8
A>hg bundle --base e26d1e14507e ..\bundle1-2.hg
2 changesets found
B>hg pull ..\bundle1-2.hg
pulling from ..\bundle1-2.hg
searching for changes
adding changesets
adding manifests
adding file changes
added 2 changesets with 2 changes to 2 files (+1 heads)
(run 'hg heads' to see heads, 'hg merge' to merge)
因为B有自己的孩子e26d1e14507e,从捆绑中添加额外的头部(以及来自A的变更集的匿名分支)
B>hg glog --template "{rev}:{node|short} \"{desc}\" - files: {files}\n"
o 3:415231dbafb8 "Added C" - files: C.txt
|
o 2:6d9709a42687 "Added B" - files: B.txt
|
| @ 1:72ef13990d0d "Edited A" - files: A.txt
|/
o 0:e26d1e14507e "Initial data" - files: .hgignore A.txt
测试案例2 - 应用捆绑两次
我知道apriori,repo changesets中存在的将不再被拉(并且更喜欢来自bundle而不是hg pull
的{{1}}的统一样式),但是显示它< / p>
hg unbundle
拉动行为带来的额外好处 - 您可以不用担心移动基础变更集以及总是使用一个最旧的分歧点 - 它会(略微)增加捆绑的大小(稍微 - 因为默认情况下bundle是bzip2压缩存档),但它也会保证所有子变更集都包含在bundle中,并且在目标存储库中删除所有缺少的(以及仅缺少的)变更集
而且,无论如何,即使两次捆绑相同的捆绑也不会有任何逆火。
同一个回购B中的同一个捆绑包,试图解开捆绑已经捆绑的
B>hg pull ..\bundle1-2.hg
pulling from ..\bundle1-2.hg
searching for changes
no changes found
答案 1 :(得分:1)
- 中间更改:在创建捆绑包(步骤1)之后和远程应用之前(步骤2),远程计算机B上发生了哪些更改?我有一个案例,它只是用新捆绑包覆盖了更改而没有冲突警告或合并建议。
如果在机器B上进行了更改,那么将使用从机器A捆绑的更改在 parallel 中进行此更改。如果进行了更改,这并不重要在创建捆绑包之前或之后(按时间),只有机器B上的更改不会将机器A的头部作为其祖先。
换句话说,当两台机器同步时,世界看起来像这样:
A: ... [a]
B: ... [a]
然后在机器A上创建一些新的提交:
A: ... [a] --- [b] --- [c]
B: ... [a]
您使用[a]
作为基础捆绑,因此您获得了[b]
和[c]
的捆绑包。现在让我们说某人(也许是你自己)在机器B上提交:
A: ... [a] --- [b] --- [c]
( bundled )
B: ... [a] --- [x]
到目前为止,两个存储库之间没有任何交换,所以这只是人们并行工作的正常情况。这是分布式版本控制系统中的标准 - 并行工作的人创建了对合并提交的需求。
在这两个存储库中,合并的需求并不明显,它们都有线性历史。但是,当您在机器B上解开捆绑时,您会看到分歧:
A: ... [a] --- [b] --- [c]
( bundled )
B: ... [a] --- [x]
\
[b] --- [c]
( unbundled )
有必要认识到hg unbundle
与hg pull
完全相同,只不过它可以离线完成。也就是说,存储在一个包中的数据实际上只是hg pull
如果你在两个存储库之间有一个在线连接就会传输的数据。
现在,您将合并两个标题[x]
和[c]
以在计算机B上创建[y]
:
A: ... [a] --- [b] --- [c]
B: ... [a] --- [x] --- [y]
\ /
[b] --- [c]
机器B上的您的最后一个包是以[a]
为基础创建的。但是,您也知道机器A已提交[c]
,因此您可以根据需要将其指定为附加基础:
$ hg bundle --base a --base c stuff-from-machine-b.hg
这会将[x]
和[y]
放入捆绑包中:
bundle: (a) --- [x] --- [y]
/
(c)
在这里,我使用(a)
和(c)
来表示捆绑所需的基础。如果您的存储库中同时包含[a]
和[c]
,则只能解开此捆绑包。如果您遗漏第二个基地(仅使用[a]
),您还会捆绑[b]
和[c]
:
bundle: (a) --- [x] --- [y]
\ /
[b] --- [c]
此处您包含了捆绑中除[a]
之外的所有内容。捆绑太多是好的,我们将在下面看到。
- 捆绑的双重应用:意外捆绑两次应用会发生什么?是否需要以某种方式使用本地标签记录应用的捆绑包?
两次应用捆绑包就像两次运行hg pull
一样:第二次没有任何反应。在分拆时,Mercurial会查看捆绑包并导入缺少的变更集。因此,如果你分拆两次,第二次就没什么可做的了。