如何确保Mercurial存储库克隆(或任何DVCS)中没有未保存的工作

时间:2012-07-21 02:57:42

标签: mercurial dvcs bazaar

简要说明:

如何确保任何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”项目主仓库?

嗯......我想如果涉及推送和克隆魔杖登记的回购记录在某处,我可以猜测一下正确的项目大师可能是什么。

2 个答案:

答案 0 :(得分:1)

以下是您可以做的事情:

  1. 确定服务器上可能的中央存储库。

  2. 迭代客户端上的存储库,使其与中央存储库相匹配。

  3. 针对您找到的中央存储库运行hg outgoing

  4. 更详细一点:

    1. 我认为你的存储库有一个中心位置,否则你的问题就没有实际意义了。现在,可以通过根变更集 来识别存储库。此变更集将为零版本,您可以像这样获得完整的变更集:

      $ hg log -r 0 --template "{node}"
      

      在服务器上运行脚本,将(node, URL)对列表转储到客户端可访问的文件中。这些网址将成为推送目标。

    2. 在首先从服务器下载(node, URL)列表的客户端上运行脚本,然后识别服务器上的所有本地存储库和相应的推送URL。

    3. 使用您在上一步中找到的网址运行hg outgoing URL。您可以(并且应该!)使用hg outgoing的完整URL,以避免依赖客户端上执行的任何本地配置。这样您就可以避免处理defaultdefault-push路径,并且由于网址指向服务器,因此您知道它是一个可以与之比较的好网址。

      如果服务器具有相同存储库的多个克隆,则会有几个不同的URL可供选择。然后,您可以尝试全部并使用具有最少的传出更改集的报告,或者您可以通过组合服务器端的克隆(通过将所有克隆中的更改集拉入单个存储库)来解决问题,然后与此组合存储库进行比较。

    4. 当您在客户端上运行脚本时,您可能拥有一些本地存储库,并且不存在于服务器上。您的脚本应该处理这些:它应该发送给开发人员的电子邮件,要求他在服务器上创建存储库。

      最后,存储库可能有多个根变更集。以上仍然可以很好地工作:所有克隆以正常方式完成将在服务器和客户端上保持修订版零相同。因此,该脚本将正确匹配客户端仓库与服务器仓库,即使有多个根。

      只有当开发人员运行hg clone -r the-other-root ...之类的内容时,上述内容才会失败,因为另一个根现在变为零版本。因此,存储库将被视为本地存储库。无论如何,你的脚本应该处理它,所以它没什么大不了的。

答案 1 :(得分:0)

如果您关心的是数据丢失并且您正在使用git,那么只需创建一个存储库。将所有创建的存储库添加为此存储库并运行

git fetch --all

这样可以有效地备份所有存储库中的所有数据。它还备份了所有引用的当前快照。