简要说明:
如何确保任何DVCS的分布式存储库克隆中没有未保存的工作?
我正在考虑专门针对Mercurial,但它也适用于git,bzr等。
DETAIL:
回到过去的糟糕时光,我过去常常运行可能与伪代码相当的cron作业,因为我可能不记得CVS命令:
find all checked out CVS trees
do a cvs status command (which I think is something like cvs update -n?)
| grep '^M' to find all modified files not yet committed to the central repo
(这些日子很糟糕(1)因为我们使用的是CVS,而且(2)因为我不时是那个负责起诉的人,没有什么可以丢失。好吧,最后一点也不是那么糟糕,但是溃烂。)
问:我如何为像Mercurial这样的现代DVCS系统做同样的事情。我觉得这很容易,但经过仔细检查,有些东西丢失了:我开始做类似
的事情find all ...path/.hg directories, and then look at ...path
do hg status - look at the output // this is easy enough
do hg outgoing // this is where it gets interesting
你可能认为做一个hg传出就足够了。但不一定。
考虑:
cd workspace-area
hg clone master repo1
hg clone repo1 repo2
rm -rf repo1
hg clone repo2 repo1
现在repo1的默认路径是repo2,反之亦然。
当然,如果您拥有合适的工作流程,这将不会发生。如果你只是从你上游的东西克隆,永远不会从同伴那里克隆。但是......轻量级克隆是顶级做DVCS的部分原因。而且,它已经发生在我身上了。
为了解决这个问题,我通常在某个地方有一个hg路径,在我的〜/ .hgrc中设置,设置为某个项目主URL。这项工作正常 - 对于那个项目。如果你有很多很多项目,那就太好了。即使你将它们称为project1-master project2-master等,也只会有很多。更糟糕的是,由于希望在项目之间共享的库,子目录正在激增。
此外,这必须在用户的.hgrc中。或者网站.hgrc。对于那些可能没有.hgrc设置的人来说不太好 - 就像一个管理员不知道他的系统上几十(或几百)个项目中每个项目的来龙去脉 - 但仍然希望做他的用户寻找陈旧工作的好处。 (他们可能已经开始期待它了。)或者,如果您只想提供有关如何执行此操作的标准说明。
我已经考虑将项目(或列表)的某个标准主仓库的名称放入文本文件中,然后检入仓库。说repo / .hg_master_repos。这看起来可能有用,虽然它有一些问题(你可能只看到全局项目主数据,而不是另外一个本地项目主数据。我不想解释更多。)。
但是......在我这样做之前,有没有标准的方法呢?
顺便说一下,到目前为止,这就是我所拥有的:
#!/usr/bin/perl
use strict;
# check to see if there is any unsaved stuff in the hg repo(s) on the command line
# -> hg status, looking for Ms, etc.
# for now, just send it all to stdout, let the user sort it out
# -> hg outgoing
# issue: who to check outgoing wrt to?
# generic
# a) hg outgoing
# but note that I often make default-push disabled
# also, may not point anywhere useful, e.g
# hg clone master r1
# hg clone r1 r2
# rm -rf r1
# hg clone r2 r1`
# plus, repos that are not clones, masters...
# b) hg outgoing default-push
# c) hg outgoing default
# various repos specific to me or my company
foreach my $a ( @ARGV ) {
print "********** $a\n";
$a =~ s|/\.hg$||;
if( ! -e "$a/.hg" ) {
print STDERR "Warning: $a/.hg dos not exist, probably not a Mercurial repository\n";
}
else {
foreach my $cmd (
"hg status",
# generic
"hg outgoing",
"hg outgoing default-push",
"hg outgoing default",
# specific
"hg outgoing PROJECT1-MASTER",
"hg outgoing MY-LOCAL-PROJECT1-MASTER",
"hg outgoing PROJECT2-MASTER",
# maybe go through all paths?
# maybe have a file that contains some sort of reference master?
)
{
my $cmd_args = "$cmd -R $a";
print "======= $cmd_args\n";
system($cmd_args);
}
}
}
正如你所看到的,我没有用任何东西来装饰它来解析它得到的东西 - 只是让用户,我,眼球。
但只是做着
find ~ -name '*.hg' | xargs ~/bin/hg-any-unsaved-stuff.pl
发现了许多我不知道的可疑未保存的东西。
hg状态报告的旧未保存更改非常可疑。外向报道的未完成的工作是可疑的,但对于认为克隆是分支的人来说可能并不那么糟糕。但是,我不希望永远存在一个不同的克隆,而是将它们放到分支上,以便有人可以通过从一个地方克隆来查看所有历史记录。
BOTTOM LINE:
是否有一种标准方法可以找到未保存的工作,未经检入和/或未经检查,这些方法不容易受到我上面提到的各种周期的影响?
是否有某些约定用于在某个文件中记录“true”项目主仓库?
嗯......我想如果涉及推送和克隆魔杖登记的回购记录在某处,我可以猜测一下正确的项目大师可能是什么。
答案 0 :(得分:1)
以下是您可以做的事情:
确定服务器上可能的中央存储库。
迭代客户端上的存储库,使其与中央存储库相匹配。
针对您找到的中央存储库运行hg outgoing
。
更详细一点:
我认为你的存储库有一个中心位置,否则你的问题就没有实际意义了。现在,可以通过根变更集 来识别存储库。此变更集将为零版本,您可以像这样获得完整的变更集:
$ hg log -r 0 --template "{node}"
在服务器上运行脚本,将(node, URL)
对列表转储到客户端可访问的文件中。这些网址将成为推送目标。
在首先从服务器下载(node, URL)
列表的客户端上运行脚本,然后识别服务器上的所有本地存储库和相应的推送URL。
使用您在上一步中找到的网址运行hg outgoing URL
。您可以(并且应该!)使用hg outgoing
的完整URL,以避免依赖客户端上执行的任何本地配置。这样您就可以避免处理default
和default-push
路径,并且由于网址指向服务器,因此您知道它是一个可以与之比较的好网址。
如果服务器具有相同存储库的多个克隆,则会有几个不同的URL可供选择。然后,您可以尝试全部并使用具有最少的传出更改集的报告,或者您可以通过组合服务器端的克隆(通过将所有克隆中的更改集拉入单个存储库)来解决问题,然后与此组合存储库进行比较。
当您在客户端上运行脚本时,您可能拥有一些本地存储库,并且不存在于服务器上。您的脚本应该处理这些:它应该发送给开发人员的电子邮件,要求他在服务器上创建存储库。
最后,存储库可能有多个根变更集。以上仍然可以很好地工作:所有克隆以正常方式完成将在服务器和客户端上保持修订版零相同。因此,该脚本将正确匹配客户端仓库与服务器仓库,即使有多个根。
只有当开发人员运行hg clone -r the-other-root ...
之类的内容时,上述内容才会失败,因为另一个根现在变为零版本。因此,存储库将被视为本地存储库。无论如何,你的脚本应该处理它,所以它没什么大不了的。
答案 1 :(得分:0)
如果您关心的是数据丢失并且您正在使用git,那么只需创建一个存储库。将所有创建的存储库添加为此存储库并运行
git fetch --all
这样可以有效地备份所有存储库中的所有数据。它还备份了所有引用的当前快照。