3

構成ファイルをチェックし、無効な場合はプッシュを破棄する事前受信フックを git サーバーに設定したいと思います (ブランチ名に応じて特定のトークンの存在を確認したい)。しかし、preceive フックが (old-rev, new-rev, refname) のリストを受け取るだけで、ファイルの内容を検査するために見つけた唯一の方法は、これらの参照を比較することであり、あまり快適ではありません。

これを行う簡単な方法はありますか?precommit フックを使用すると簡単になりますが、サーバーに最後の障壁が必要です。

4

1 に答える 1

6

pre-receive または update フックは、新しいオブジェクト (コミット、注釈付きタグ オブジェクト、ツリー、ブロブ) がリポジトリに読み込まれた後、参照 (ブランチ名、タグ名など) が変更される前に呼び出されます。

これが、 pre-receive フックが ( 、、 ) トリプルのリストを取得する理由です。既存のリポジトリにはオブジェクトがあり、既存の参照 (存在する場合) は、SHA-1 が であるオブジェクト (通常はコミット、場合によってはタグ) を指します。Git は、SHA-1 が存在するオブジェクトを指すように変更することを提案しています(または、これら 2 つのうちの 1 つだけがすべてゼロの「null SHA-1」である場合は、オブジェクトを作成または削除します)。oldnewrefoldnew

ファイルの内容を検査するために私が見つけた唯一の方法は、それらの参照を比較することです

これは 1 つの方法ですが、すべてを抽出するための一連の git コマンドがすべて揃っています。たとえば、どこかに新しい空のディレクトリを作成し ( )、実行してそのパスに完全なツリーを取得できます。(ツリーが大きい場合、これには時間がかかる場合があります。もちろん、ツリーで実行するテストにはさらに時間がかかります。)mkdir pathgit --work-tree=path checkout sha1

何を正確に確認するかを決定する必要があります。これはあなたが望むほど複雑ですが、ブランチ名 (任意のブランチ名でrefある形式のa 、つまり、さらにスラッシュが含まれる可能性がある) については、ref 更新が次の 1 つ以上を実行する可能性があることを考慮してください (いくつかの組み合わせは明らかに不可能です):refs/heads/namename

  • 新しいブランチ名を追加
  • 新しいコミットを既存のブランチに追加する
  • 既存のブランチからコミットを削除する
  • 既存のブランチ名を削除する

たとえば、裸のレポのクローンがあり、originこれを行うとします。

git fetch origin                      # get up-to-date with origin
git checkout -b branch origin/branch  # make tracking branch for origin/branch
git reset --hard HEAD~3               # back up 3 commits
echo more stuff >> existing_file      # modify something
git commit -a -m 'add new text'       # commit the change
git revert --no-edit HEAD             # add another commit that undoes change
git push -f origin branch             # and push

その後、更新により 3 つのコミットが削除され、さらに 2 つのコミットが追加されます。newSHA-1をチェックアウトした場合に得られるツリー(ここでもold, new, のref3 重表記を使用) は、プッシュするように要求したバージョンとまったく同じように見えます。ツリーが合格しなければならないテストがある場合、おそらくHEAD~3実際に合格したバージョンはそれらのテストに合格するため、このバージョンも合格するでしょう。ただし、コミットして 1 行追加したものはテストに合格しないexisting_file可能性があり、3 つのコミットを削除したという事実が気に入らないかもしれません。

繰り返しますが、何をチェックしたいかを決定し、それを達成するためのコードを書くのはあなた次第です。強制プッシュがコミットを削除しているかどうかを確認します。これを許可または禁止します。新しいブランチ名が作成されているかどうかを確認します。許可または禁止します。ブランチ名が削除されているかどうかを確認します。許可または禁止します。コミットが追加されている場合は、すべての中間コミットのツリーを確認するか、最終ツリーのみを確認してください。許可または禁止します。追加されるコミットにはマージが含まれますか? タグは追加、削除、または変更されていますか? 等々。

楽しみのために、少し前に、これらの多くを実行するpre-receive シェル スクリプト(POSIX スタイルのシェル) を作成しました (コミットの内容はチェックしません)。私はいくつかの非常に軽いテストを行いましたが、うまくいくようです。より徹底的なチェックの出発点として使用できます。

ただし、真剣にチェックしている場合は、gitoliteの使用を検討することをお勧めします。

于 2013-10-10T14:16:58.813 に答える