1 つのディレクトリに 2 つの Git リポジトリがありますか? 質問する

1 つのディレクトリに 2 つの Git リポジトリがありますか? 質問する

1 つのディレクトリに 2 つの Git リポジトリを置くことは可能ですか? 不可能だと思いますが、質問します。基本的に、作業するすべてのマシンで共通であるはずのホーム ディレクトリの設定ファイル (例: .emacs) をチェックインし、マシン固有の設定を含むローカル ファイル (例: .emacs.local) 用の 2 番目のリポジトリを用意したいと考えています。これを実現するには、ローカル設定をサブディレクトリに置き、メインの Git リポジトリからそのサブディレクトリを無視するしか思いつきません。他に何かアイデアはありますか?

ベストアンサー1

この記事はこの点を比較的よく説明しています:

https://github.com/rrrene/gitscm-next/blob/master/app/views/blog/progit/2010-04-11-environment.markdown

基本的に、コマンドラインから作業する場合、これは想像するよりも簡単です。2 つの Git リポジトリが必要だとします。

.gitone
.gittwo

次のように設定できます。

git init .
mv .git .gitone
git init .
mv .git .gittwo

次のようにファイルを追加して、それを 1 つだけにコミットすることもできます。

git --git-dir=.gitone add test.txt
git --git-dir=.gitone commit -m "Test"

したがって、git のオプションが最初に来て、次にコマンド、そして git コマンドのオプションが来ます。次のように git コマンドを簡単にエイリアスできます。

#!/bin/sh
alias gitone='git --git-dir=.gitone'
alias gittwo='git --git-dir=.gittwo'

したがって、次のように、少しだけ入力を少なくして、どちらか一方にコミットすることができますgitone commit -m "blah"

より厄介なのは、無視です。.gitignore は通常、プロジェクト ルートにあるため、ルート全体を切り替えずに、これも切り替える方法を見つける必要があります。または、.git/info/exclude を使用することもできますが、その場合、実行するすべての無視はコミットまたはプッシュされず、他のユーザーに迷惑をかける可能性があります。いずれかのリポジトリを使用している他のユーザーが .gitignore をプッシュすると、競合が発生する可能性があります。これらの問題を解決する最善の方法は私にはわかりません。

TortoiseGit のような GUI ツールを好む場合も、いくつか課題があります。これらのツールの想定を満たすように、.gitone または .gittwo の名前を一時的に .git に変更する小さなスクリプトを作成することができます。

2つのリポジトリの回避

ブランチを合成することでも同様の結果を得ることができますが、処理を継続するにはかなりの作業が必要です。

元の質問にあるシステム固有の設定のようなローカルファイルがあるとします。他の開発者へのコミットからは除外したいのですが、実行に不可欠であったり、デバッグに重要になる可能性があるため、どこかにコミットしておきたいのです。

2 つの Git リポジトリの代わりに、次の操作を実行できます。

git checkout main
git checkout -b local
git add -A .
git commit -m "local changes"
git checkout main
git checkout -b chris
git checkout -b dev
git merge local

つまり、ローカルの変更から始めて、「local」というブランチにそれを出しました。このブランチをリモートにプッシュすることはありません。

これらの変更を脇に置いて、メインから別のブランチを作成し、プッシュする内容にちなんで名前を付けます (たとえば、自分の名前 (私の場合は「chris」))。

今のところ、2 つの異なるブランチがありますが、それらを連携させる方法はありません。3 つ目の合成ブランチを作成します。ここでの dev は、chris と local の組み合わせです。

開発は開発環境で行い、プッシュする時には次の操作を行います。

git checkout chris
git add -A .
git commit -m "My commit message"
git push

git checkout dev
git merge chris

これにより、変更がプッシュされ、Chris 上でクリーンアップされてから、dev に戻ってブランチが再構成されます。Chris は引き続きクリーンな状態を維持し、意味のある変更がプッシュされ、ローカルに保存したい内容はローカル ブランチ上で安全に保持されます。

さらに特別なシナリオ:

ローカルブランチをプッシュする

結局、「ローカル」ブランチをプッシュしたいとします。たとえば、重要な秘密がそこになく、git を部分的にバックアップとして使用している場合などです。解決方法は簡単です。ブランチに、開発者がプルして自分用に動作すると期待しないように、chris-local-settings のように長くて非常にわかりやすい名前を付けるだけです。長い名前を何度も入力するのが嫌なら (タブ補完では不十分)、ブランチを分岐するのは非常に簡単です。

git checkout chris-local-settings
git checkout -b local

生成されたファイル

ローカル ブランチがより複雑で、乱雑なファイルが生成され続けているとします。デバッグにはそれらのファイルが必要ですが、生成されていない変更だけが含まれたクリーンなブランチにそれらをプッシュすることは望ましくありません。

生成されたファイルはおそらくパターンに従っていますが、そうでない場合は、パターンに従うように、いつどこで生成されるかを決定できる可能性があります。たとえば、生成されたすべてのファイルが「bin」という名前のフォルダーに表示され、重要なコーディングを完了したばかりの場合、次のようになります。

git checkout local
cd bin
git add -A .
git commit -m "Generated files"
cd ..
git checkout chris
git commit -m "Commit message about my clean handwritten changes"
git push
git checkout dev
git merge local
git merge chris

生成されたファイルはすべて bin フォルダーにあることがわかっているので、そこに cd して git add するだけです。それらをローカルにきれいにダンプしてから、ルートに戻って残りをクリーンなブランチにコミットします。その後、dev ブランチを再構成します。

将来、特定の日時にビルドがどのような状態だったかを知る必要がある場合は、別のブランチを再構成するか、dev ブランチで時間を遡ることができます。とはいえ、私はビルドで dev ブランチを頻繁に破棄して再構成するため、残念ながら履歴はありません。

main で何らかの変更が行われ、ビルドに悪影響を与える前にそれらが機能することを確認する必要があるとします。

git checkout main
git pull
git checkout dev
git checkout -b test
git merge main

ここで、ビルドを検証するためのテストを実行します。うまくいかない場合は、次の操作を行います。

git checkout dev
git branch -D test

そして、メインに最後にプッシュした人に、メインを壊したと伝えに行きます。これで、壊れたメイン ブランチから離れて、開発環境に安全に移動できます。または、テストがうまくいけば、次のようになります。

git checkout chris
git merge main
git push
git branch -D dev
git checkout -b dev
git merge local

これにより、dev は chris のクリーンなマージになり、main の最新の内容がマージされるので、chris ブランチをプルする人は、main の最新の内容と私の変更のみを取得します。つまり、私は彼らに余分なマージ競合を投げかけません。しかし、それは私が dev の履歴を失い続けることを意味します。

おすすめ記事