我在两台不同的计算机上有两个目录 - 机器 A (Windows) 和机器 B (OSX) - 我想通过 Mercurial 保持这两个目录同步。 [*]
限制是两台机器不能通过LAN/WAN连接; 在它们之间移动数据的唯一方法是通过电子邮件。所以我认为通过电子邮件发送 Mercurial bundle 作为增量可以解决这个问题。
我当前的工作流程大致是这样的(使用本地标签lcb
作为最新的更改包):
假设我在机器A上工作。归根结底,我会:
hg commit -A -m "changes 123" hg bundle --base lcb bundle_123.hg hg tag --local -f lcb --rev tip
最后,我将该 bundle 通过电子邮件发送到机器 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 上。如此循环下去......
但是,我担心这个系统不够强大:
中间更改:创建 bundle (步骤 1)之后和远程应用它之前(步骤 1)之前会发生什么情况2) 远程机器B上发生更改?我遇到过这样的情况:它只是用新包覆盖了更改,没有冲突警告或 merge 建议。
双重应用 bundle :如果意外地应用 bundle 两次,会发生什么情况?是否需要用本地标签以某种方式记录应用的 bundle ?
或者还有其他更好的工作流程来通过电子邮件传输 Mercurial 增量吗?
[*] 来自 answer to a superuser question我认为 Mercurial 可能是最可行的方法。
最佳答案
- In-between changes: What happens when after creating a bundle (Step 1) and before applying it remotely (Step 2) a changes occurs on the remote machine B? I had a case where it just overwrote the changes with the new bundle without conflict warning or merge suggestion.
如果在计算机 B 上进行更改,则此更改将与您从计算机 A 捆绑的更改并行进行。更改是否在之前或之前进行并不重要创建 bundle (时间方面)后,唯一重要的是机器 B 上的更改不以机器 A 的头部作为其祖先。
换句话说,当两台机器同步时,世界看起来像这样:
A: ... [a]
B: ... [a]
然后您在机器 A 上创建一些新的提交:
A: ... [a] --- [b] --- [c]
B: ... [a]
您使用 [a]
作为基础进行捆绑,因此您将获得包含 [b]
和 [c]
的 bundle 。现在让我们假设有人(也许是你自己)在机器 B 上进行了提交:
A: ... [a] --- [b] --- [c]
( bundled )
B: ... [a] --- [x]
到目前为止,两个存储库之间尚未交换任何内容,因此这只是人们并行工作的正常情况。这是分布式版本控制系统中的常态——人们并行工作就产生了 merge 提交的需求。
此时,两个存储库中 merge 的需求并不明显,它们都有线性历史。但是,当您在机器 B 上解绑时,您会看到差异:
A: ... [a] --- [b] --- [c]
( bundled )
B: ... [a] --- [x]
\
[b] --- [c]
( unbundled )
认识到 hg unbundle
与 hg pull
完全相同是有帮助的,只不过它可以离线完成。也就是说,如果两个存储库之间有在线连接,则存储在 bundle 中的数据实际上只是 hg pull
会传输的数据。
现在,您将 merge 两个头 [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 中:
bundle: (a) --- [x] --- [y]
/
(c)
这里我使用 (a)
和 (c)
来表示 bundle 所需的基础。仅当您的存储库中同时存在 [a]
和 [c]
时,您才能取消捆绑此 bundle 。如果省略第二个碱基(仅使用 [a]
),您还将捆绑 [b]
和 [c]
:
bundle: (a) --- [x] --- [y]
\ /
[b] --- [c]
这里您将除 [a]
之外的所有内容都包含在 bundle 中。捆绑太多没关系,我们接下来会看到。
- Double-applying of bundle: What happens when by accident a bundle is applied twice? Would be needed to record the applied bundles somehow with local tags?
应用 bundle 两次与运行 hg pull
两次完全相同:第二次没有任何反应。解除捆绑时,Mercurial 会在 bundle 中查找并导入缺少的变更集。所以如果你解绑两次,第二次就没什么可做的了。
关于email - 通过电子邮件将 Mercurial 存储库与 bundle 同步的工作流程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23122883/