複数のgitリポジトリをどのように編成して、それらすべてが一緒にバックアップされるようにしますか?


98

SVNを使用すると、サーバー上に1つの大きなリポジトリを保持し、数台のマシンでチェックアウトしました。これは非常に優れたバックアップシステムで、どのマシンでも簡単に作業できました。特定のプロジェクトをチェックアウトしてコミットし、「マスター」プロジェクトを更新したり、すべてをチェックアウトしたりできます。

今、私はさまざまなプロジェクトのためにたくさんのgitリポジトリを持っています。そのいくつかはgithubにあります。また、git-svnコマンドでインポートした前述のSVNリポジトリも持っています。

基本的に、私はすべてのコード(プロジェクトだけでなく、ランダムなスニペットやスクリプト、私のCV、私が書いた記事、私が作成したWebサイトなど)を、リモートに簡単に複製できる1つの大きなリポジトリに置くのが好きですマシン、またはバックアップとしてのメモリースティック/ハードドライブ。

問題は、それがプライベートリポジトリであり、gitが特定のフォルダーのチェックアウトを許可していないためです(これを個別のプロジェクトとしてgithubにプッシュできますが、変更はマスターリポジトリとサブリポジトリの両方に表示されます)リポジトリ)

私はgitサブモジュールシステムを使用できましたが、それも私が望むようには動作しません(サブモジュールは他のリポジトリへのポインターであり、実際のコードが実際には含まれていないため、バックアップには役に立ちません)。

現在、git-reposのフォルダー(たとえば、〜/ code_projects / proj1 / .git /〜/ code_projects / proj2 / .git /)があり、proj1に変更を加えた後git push github、ファイルを〜/にコピーしますDocuments / code / python / projects / proj1 /そして、単一のコミットを実行します(個々のリポジトリの多数のコミットの代わりに)。次にgit push backupdrive1git push mymemorystickなど

それで、質問:あなたの個人的なコードとプロジェクトをgitリポジトリでどのようにして、それらを同期してバックアップしておくのですか?

回答:


74

私は考えを強く与えられたGitのリポジトリに無関係なデータを置くに対して助言します。新しいリポジトリを作成するオーバーヘッドは非常に低く、これは異なる系統を完全に分離しておくことを可能にする機能です。

その考えに対抗することは、不必要に絡み合った歴史に終わることを意味し、その結果、管理がより困難になり、さらに重要なのは、「考古学」ツールが結果として生じる希釈のために役に立たなくなることです。また、あなたが言ったように、Gitは「クローンの単位」がリポジトリであると想定し、その分散された性質のために実際にはそうしなければなりません。

1つの解決策は、すべてのプロジェクト/パッケージ/その他を保持することです。次のように 、祝福された階層の下で独自のベアリポジトリ(つまり、作業ツリーなし)として。

/repos/a.git
/repos/b.git
/repos/c.git

いくつかの規則が確立されたら、完全な階層に管理操作(バックアップ、パッキング、Web公開)を適用するのは簡単です。これは、「モノリシック」SVNリポジトリと完全に異なるわけではない役割を果たします。これらのリポジトリでの作業も、SVNワークフローにいくぶん似ていますが、ローカルコミットとブランチを使用できるという点が追加されてい ます。

svn checkout   --> git clone
svn update     --> git pull
svn commit     --> git push

複数のパーティ間の同期を容易にするために、各作業クローンに複数のリモートを含めることができます。

$ cd ~/dev
$ git clone /repos/foo.git       # or the one from github, ...
$ cd foo
$ git remote add github ...
$ git remote add memorystick ...

次に、「ソース」のそれぞれからフェッチ/プルし、ローカルで作業してコミットし、次のような準備ができたらこれらの各リモートにプッシュ(「バックアップ」)します(同じコミットと履歴をプッシュする方法に注意してください)。各リモコン!):

$ for remote in origin github memorystick; do git push $remote; done

既存の作業リポジトリ~/dev/foo をこのようなベアリポジトリに変える最も簡単な方法は、おそらく次のとおりです。

$ cd ~/dev
$ git clone --bare foo /repos/foo.git
$ mv foo foo.old
$ git clone /repos/foo.git

これはほとんどaと同等ですがsvn import、既存の「ローカル」履歴を破棄しません。

注:サブモジュールは、関連する 系統を共有するためのメカニズムであるため、解決しようとしている問題に適切なツールとは見なしません。


18
私はたくさんの別々のリポジトリに行き着き、それらすべてを管理するのに役立つ簡単なスクリプトを書いているという事実は、gitに何かが欠けていると感じさせます。それが何であるか、それに対して何をすべきかを正確に決定することはできません。
DonGar 2010年

さて、あなたもたくさんの別々のプロジェクトを管理していますか?プロジェクトとリポジトリの間の1対1の関係は、分散した世界では合理的に感じられますが、バックアップと管理を容易にするために、共通のディレクトリツリーに裸のリポジトリを配置します。(言い換えれば、Git / Hg / Bzrは管理をプロジェクトタスクから分離することを強制しますが、ほとんどのSVNワークフローは2つを融合します。現在、人々がGitHubまたは他のそのようなプロバイダーに管理部分を委任するのを見るのが一般的です。)
Damien Diederen

2
このアイデアは、独自のプロジェクトをホストしている場合や、それらがすべてオープンソースである場合にのみ意味があります。それ以外の場合は、githubで無制限のプライベートプロジェクトが必要になるため、コストがかかる可能性があります
dkinzer

2
「元のリモートのgithubメモリースティック; git push $ remote; done」の代わりに、1つのコマンドで多くのリモートにプッシュするように特別なリモートを構成することもできます:stackoverflow.com/questions/36862/…。(場合によってはより便利な場合があります。)
imz-Ivan Zakharyaschev

2
不足しているのは、gitがオブジェクトをサブツリーで分離できるようにする方法だと思います。これにより、単一の「リポジトリ」を、個別の同期可能な分離可能なユニット(個別に残りの部分なしでダウンロード)で構成して、人々が特定の作業を行えるようにすることができます。残りの部分を知らないサブセット。
ピーターク

28

私は彼が推奨するダミアンの答えに追加したいと思います

$ for remote in origin github memorystick; do git push $remote; done

特別なリモコンを設定して、1つのコマンドで個々の実際のリモコンすべてにプッシュできます。私はそれをhttp://marc.info/?l=git&m=116231242118202&w=2で見つけました:

したがって、「git push」(同じブランチを複数回プッシュすることが理にかなっている)の場合、実際に私が行うことを実行できます。

  • .git / configには以下が含まれます:

    [remote "all"]
    url = master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6
    url = login.osdl.org:linux-2.6.git
    
  • そして今度git push all masterは、両方
    のリモートリポジトリに「マスター」ブランチをプッシュします。

contructionを使用して、URLを2回入力する手間を省くこともできます。

[url "<actual url base>"]
    insteadOf = <other url base>

3

また、これを処理するための推奨される方法についても知りたいので、現在使用している(SVNで)セットアップについて説明します。基本的に、独自のbinとlib dirsを含むミニファイルシステム階層を含むリポジトリを作成しました。このツリーのルートには、これらのbin、libなどを追加するように環境を設定するスクリプトがあります。他のディレクトリは適切な環境変数に追加されます。したがって、ルートディレクトリは基本的に次のようになります。

./bin/            # prepended to $PATH
./lib/            # prepended to $LD_LIBRARY_PATH
./lib/python/     # prepended to $PYTHONPATH
./setup_env.bash  # sets up the environment

/ binと/ libの中に、複数のプロジェクトとそれに対応するライブラリがあります。これは標準のプロジェクトではないことはわかっていますが、私のグループの他の誰かがリポジトリをチェックアウトして 'setup_env.bash'スクリプトを実行し、ローカルにすべてのプロジェクトの最新バージョンをローカルに置くのは非常に簡単ですチェックアウト。/ usr / binまたは/ usr / libのインストール/更新について心配する必要はなく、複数のチェックアウトとチェックアウトごとの非常にローカライズされた環境を簡単に維持できます。誰かがリポジトリ全体をrmするだけで、プログラムのアンインストールを心配する必要もありません。

これは問題なく機能しており、変更するかどうかはわかりません。この問題は、この1つの大きなリポジトリに多くのプロジェクトがあることです。このような環境を作成し、プロジェクトを独自のリポジトリに分割するgit / Hg / bzr標準的な方法はありますか?


3

、必要な状況に遭遇していないので、まだgitリポジトリのネストを試していません。#gitチャネルで読んだように、gitはリポジトリをネストすることで混乱するようです。つまり、gitリポジトリ内でgit-initを実行しようとしています。ネストされたgit構造を管理する唯一の方法は、git-submoduleまたはAndroidのrepoユーティリティを使用することです。

あなたが説明しているそのバックアップの責任については、私はそれを委任すると言います...私にとって、私は通常、各プロジェクトの「元の」リポジトリを職場のネットワークドライブに置き、IT技術者がバックアップ戦略によって定期的にバックアップします選択。それは簡単で、私はそれを心配する必要はありません。;)


2

mrを使用して複数のGitリポジトリを一度に管理するのはどうですか?

mr(1)コマンドは、リポジトリのセットに対して、それらが1つの複合リポジトリであるかのように、チェックアウト、更新、または他のアクションを実行できます。Subversion、git、cvs、mercurial、bzr、darcs、cvs、vcsh、fossil、veracityリポジトリの任意の組み合わせをサポートし、他のリビジョン管理システムのサポートを簡単に追加できます。[...]

シンプルなシェルスクリプトを介して非常に構成可能です。それができることのいくつかの例は次のとおりです。

[...]

  • gitリポジトリを更新するときは、2つの異なるアップストリームからプルし、2つをマージします。
  • 複数のリポジトリ更新を並行して実行し、更新プロセスを大幅に高速化します。
  • ラップトップがオフラインになったために失敗したアクションを覚えておいてください。そうすれば、オンラインに戻ったときに再試行できます。

1

ネストされたgit reposを使用する別の方法がありますが、それはあなたが求めている問題を解決しません。それでも、私が解決策を探している他の人のために:

トップレベルのgit repoでは、ネストされたgit repoを含む.gitignoreのフォルダーを非表示にするだけです。これにより、2つの別個の(ただしネストされた)gitリポジトリを簡単に作成できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.