3

裸でないリポジトリへのプッシュ操作を安全にすることに関して、そこにいる git の専門家からのガイダンスを使用できます。基本的に、私はこれを行う方法について計画を立てており、計画が正気かどうかについてアドバイスを使用できます:)

通常、git で裸でないリポジトリにプッシュすると、その作業コピーとインデックスは更新されません。私が発見したように、後で手動で更新するのを忘れると、深刻な問題が発生する可能性があります!

私たちのグループには、人々がクローンを作成してプッシュバックする「中央」リポジトリがいくつかありますが、多くの人々は、クローンのクローンを作成し、必要に応じてそれらの間で真の分散方式でプッシュ/プルできるようにしたいと考えています。これを安全にするために、「clone」または「init」を介して作成されたすべてのリポジトリに、プッシュ操作の後に作業ディレクトリとインデックスを更新して同期する post-receive フックが自動的にインストールされるようにしたいと思います。新しい頭。

これは、hooks サブディレクトリに post-receive フックを含むテンプレート ディレクトリを作成し、グループの全員に次のことをさせることで実現できることがわかりました。

git config --global init.templatedir /path/to/template/dir

現在、受信後のフックは次のようになっています。

export GIT_WORK_TREE=..
git checkout -f HEAD

これは期待どおりに動作するように見えますが、チェックアウト コマンドについては不明な点があります。作業ディレクトリとインデックスを HEAD の状態と同期する目的で、「git checkout -f HEAD」と「git reset --hard HEAD」は同等ですか?

「git reset --hard HEAD」が自分のやりたいことを実行することはわかっていますが、受信後のフックで使用すると、テストでプッシュ操作が大幅に遅くなるため、質問します (すべてのファイルの新しいチェックアウトを行うようです。ファイルが作業ディレクトリでダーティかクリーンかに関係なく)。「git checkout -f HEAD」は、同じことをはるかに高速に実行するように見えます(クリーンな作業ディレクトリとHEADと同期したインデックスを取得します)が、チェックアウトコマンドがオンザフライで実行される傾向があることを考えると、少し緊張していますコミットされていない作業ディレクトリの変更とマージします。このコマンドは、すべての場合 (ファイルの削除、名前の変更などを含む) で HEAD の状態と正確に一致する作業ディレクトリとインデックスを本当に提供してくれますか?

アドバイスをよろしくお願いします!

4

2 に答える 2

5

私は問題を誤解していたかもしれません。開発者が作業中の変更をコミットしていない間、誰でも開発者の作業ディレクトリにプッシュできるように設定しますか? それは、一言で言えば「安全」にすることはできません。

ほとんどの人は、プライベートな通常の作業ディレクトリを用意し、そのクローンを同じディスク上のパブリック リポジトリに作成し、それを共有します。これはハードリンクを使用するため、追加のスペースはほとんど使用しません。あなたが変更を同僚のパブリック ベア リポジトリにプッシュすると、同僚は変更を受け取る準備ができたときに作業ディレクトリにプルします。または、変更をパブリックの裸のレポにプッシュし、同僚が準備ができたらそこからプルします。ベアでないリポジトリへのプッシュをセットアップするのが難しいのには理由があります。

于 2011-05-20T19:40:35.887 に答える
4

Git FAQエントリで示されているpost-updateフックを使用することをお勧めします」 「git push」後にリモート リポジトリに変更が表示されないのはなぜですか?」.

ハードリセットを実行する前に、ステージングされた変更とステージングされていない変更を (追跡されたファイルに) 隠します。単純なハード リセットよりも安全ですが、FAQ エントリにあるように、発生する可能性のあるすべての状況をカバーしているわけではありません (たとえば、既存の競合があるインデックスを隠しておくことはできません。変更を自動マージすることはできません)。 do などのように変更されていないファイルにgit checkout)。


ただし、…
可能であれば、…
チェックアウトされたブランチへのプッシュは最初から避けるべきでしょう。

チェックアウトされたブランチにプッシュしない限り、裸でないリポジトリにプッシュしても問題ありません (結局のところ、関連する構成変数はreceive.denyCurrentBranch「<code>receive.denyNonBare」ではなく です)。

上記のリンクの FAQ エントリの最後の段落は、(以下のコメントで Mark Longair が言及しているように)裸でないリポジトリにプッシュするためのアプローチを概説する別のエントリにリンクしています。エントリの動機は、2 つの非ベア リポジトリ間の非対称ネットワーク接続ですが、この手法は、非ベア リポジトリにプッシュする必要がある、またはプッシュしたいあらゆる状況に適用できます。

この後者の FAQ エントリは、リモート追跡ブランチ (下refs/remotes/) へのプッシュの例を示しています。refs/heads/HEAD をデタッチせずに (を使用せずに) チェックアウトできるのは以下の参照のみであるため、「チェックアウトされたブランチへのプッシュ」を回避するためgit symoblic-refに、外部へのプッシュrefs/heads/は安全なはずです。

集中型環境で作業しているため、そのようなプッシュの送信先に関するポリシーを作成できる場合があります。例えば:

コミットを他の誰かの非ベア リポジトリにプッシュする必要がある場合は、それらを にプッシュしますrefs/remotes/from/<your-username>/<branch>。通常のリモート追跡ブランチとの競合を避けるために、 という名前のリモートを定義するべきではありませんfrom。このようにプッシュされたブランチはgit branch -a(または) に表示されるため、プレフィックス-rなしで参照できます。refs/remotes/ただし、構成変数がないため、from疑似リモートは表示されません。git remoteremote.from.url

例:

alice$ remote add betty bettys-machine:path/to/some/non-bare/repository
alice$ git push betty master:refs/remotes/from/alice/bug/123/master

betty$ git log --reverse -p origin/master..from/alice/bug/123/master
于 2011-05-20T17:46:36.657 に答える