1

簡単に:

DVCSの分散リポジトリクローンに未保存の作業がないことをどのように確認しますか?

これは特にMercurialについて考えていますが、git、bzrなどにも当てはまります。

詳細:

古き良き時代には、CVSコマンドを覚えていない可能性があるため、-pseudocodeと同等の処理を実行する可能性のあるcronジョブを実行していました。

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)時々私が訴えを担当していたため、何も失われませんでした。OK、最後はそれほど悪くはありませんでしたが、潰瘍がありました。)

Q: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に設定します。これは問題なく機能します-その1つのプロジェクトでは。多くのプロジェクトがある場合は、それほど問題はありません。それらをproject1-masterproject2-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ステータスによって報告された古い未保存の変更は非常に疑わしいものです。発信によって報告されたプッシュされていない作業は疑わしいですが、クローンがブランチであると考える人にとってはおそらくそれほど悪くはありません。しかし、私は分岐したクローンを永遠に存続させるのではなく、誰かが1つの場所からクローンを作成することですべての履歴を見ることができるように、ブランチに物事を置くことを好みます。

ボトムライン:

上記の種類のサイクルに対して脆弱ではない、保存されていない作業、チェックインされていない、および/またはプッシュされていない作業を見つける標準的な方法はありますか?

「真の」プロジェクトマスターリポジトリをファイルのどこかに記録するための規則はありますか?

うーん...プッシュとクローンのワンドチェックインに関連するリポジトリがどこかに記録されていれば、適切なプロジェクトマスターが何であるかを推測できると思います。

4

2 に答える 2

1

できることは次のとおりです。

  1. サーバー上の可能な中央リポジトリを特定します。

  2. クライアント上のリポジトリを反復処理して、中央リポジトリと一致させます。

  3. hg outgoing見つけた中央リポジトリに対して実行します。

もう少し詳しく:

  1. そうしないと、質問が意味不明になるため、リポジトリの中心的な場所があると思います。これで、ルート changeset によってリポジトリを識別できるようになりました。この変更セットはリビジョン 0 になり、次のように完全な変更セットを取得できます。

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

    (node, URL)クライアントがアクセスできるファイルにペアのリストをダンプするスクリプトをサーバー上で実行します。URL がプッシュ ターゲットになります。

  2. (node, URL)最初にサーバーからリストをダウンロードし、次にサーバー上のすべてのローカル リポジトリと対応するプッシュ URL を識別するスクリプトをクライアントで実行します。

  3. hg outgoing URL前のステップで見つけた URL を使用して実行します。hg outgoingクライアントで行われたローカル構成に依存しないように、 で完全な URL を使用できます (使用する必要があります) 。こうすることでdefaultdefault-pushパスを処理する必要がなくなり、URL がサーバーを指しているため、比較するのに適した URL であることがわかります。

    サーバーに同じリポジトリの複数のクローンがある場合、選択できる URL がいくつかあります。次に、それらすべてを試して、送信変更セットが最も少ないものをレポートに使用するか、サーバー側でクローンを組み合わせて (すべてのクローンから単一のリポジトリに変更セットをプルすることにより) 問題を回避してから、この結合されたリポジトリと比較してください。

クライアントでスクリプトを実行すると、ローカルでサーバーには存在しないリポジトリがいくつかある場合があります。スクリプトはそれらを処理する必要があります。おそらく、サーバー上にリポジトリを作成するように依頼する電子メールを開発者に送信する必要があります。

最後に、リポジトリには複数のルート変更セットがある場合があります。上記はまだかなりうまくいきます: 通常の方法で行われたすべてのクローンは、サーバーとクライアントの両方でリビジョン 0 を同じに保ちます。したがって、スクリプトは、複数のルートがある場合でも、クライアント リポジトリとサーバー リポジトリを正しく一致させます。

開発者がhg clone -r the-other-root ...上記のようなものを実行した場合にのみ、他のルートがリビジョン 0 になるため失敗します。したがって、リポジトリはローカル リポジトリと見なされます。いずれにせよ、スクリプトはそれを処理する必要があるため、大したことではありません。

于 2012-07-23T02:11:03.327 に答える
0

懸念事項がデータの損失だけで、git を使用している場合は、リポジトリを作成するだけです。作成したすべてのリポジトリをリモートとしてこれに追加して実行します

git fetch --all

これにより、すべてのリポジトリのすべてのデータのバックアップが効率的に作成されます。また、すべての参照の現在のスナップショットもバックアップします。

于 2012-07-21T12:26:24.443 に答える