4

ブランチとトランクのサーバー リポジトリがあります。ブランチは、すべてのチーム メンバーのリポジトリです。ブランチの下のリポジトリでのみ使用しようとしていますsvn hooksが、うまく機能していないようです。以下に、私がアプローチしようとした手順を示します。

  1. my_repoリモートサーバーからチェックアウトしましたbranch/my_repo

  2. ローカル リポジトリmy_repoにはコンテンツがないため、新しい svn リポジトリをローカルに作成し、/hooksフォルダを含むすべてをmy_repo.

  3. で空のファイルを作成し、my_repoテキスト行を追加しました。次にsvn add、このファイル。

  4. ファイルを変更し、my_repo/hooks/pre-commit.tmpl常にエラー コード 1 でパスしないようにします。今では次のようになります。

#!/ビン/sh
1番出口
  1. を pre-commit にコピーしpre-commit.tmpl、pre-commit の実行許可を自分に追加します

  2. サーバーには他の人が含まれており、サーバーの構造は次のようになります。

- サーバー
    - ブランチ
        - my_repo
            - マイファイル
            - フック
                - 事前コミット
        - トムのレポ
        - 他のチーム メンバーのリポジトリ
    - トランク
  1. チェックアウトしたレポで、次を使用して変更をコミットしました。svn commit -m "dumb change"

ここからコミットできなくなり、コード 1 のエラーが表示されるはずですよね? しかし、私はそれをどこにも見ません。

  1. 次に、フックフォルダーをブランチとトランクと同じレベルの最上位に配置してみました。つまり、構造は次のようになります。
-サーバ
    - 枝
        - my_repo
            - マイファイル
        - トムのレポ
        - 他のチーム メンバーのリポジトリ
    - トランク
    - フック
        - 事前コミット

しかし、まだ機能していません。はぁ...

ただし、David の助けを借りて、何をすべきか、何が問題なのかを突き止めました。したがって、所有者にフックファイルをサーバーに追加するよう依頼する必要がありました。サーバー上にリポジトリを作成しなかったため、作業ディレクトリにファイルが表示されません。2.今、私が試したことは次のとおりです。

  1) 私自身の Linux システムで、svnadmin で新しいリポジトリを作成します。これはおそらく test_server と呼ばれます。フォルダには confs、db、hooks、locks があります。ファイル: フォーマット、readme.txt
  2) 同じレベルで、新しいフォルダー (working_dir と呼ばれる) をローカルの作業ディレクトリとして mkdir し、test_server からチェックアウトします。現在、working_dir には test_server という名前のフォルダーが含まれており、このフォルダーは空です。手順 1 のフォルダーまたはファイルが表示されない
  3) 上記のように、test_server のフック ファイルを変更します。
  4) ファイルを追加して、working_dir/test_server フォルダー内のファイルに新しい行を追加してコミットします。
  5) commit failed with message: svn: Commit blocks by pre-commit hook(exit code 1) with no output. が表示されるはずです。

デビッドに感謝します。

4

5 に答える 5

6

フックを実行すると、STDOUT (通常はechoステートメントによって生成されるもの) が無効になります。これは、スクリプトがファイルにリダイレクトされたとしても、STDOUT を使用して何も出力できないことを意味します。

1代わりに、 (STDOUT)を使用する代わりに、別のファイル記述子を開く必要があります。コマンドを使用execして別のファイル記述子を開き、それをファイルにパイプできます。

exec 4> $my_file  #Opening my_file for writing
echo "This is going to $my_file" >&4

STDERR もリダイレクトされます。STDERR の出力が収集され、呼び出し元のクライアントに送り返されますが、フックがゼロ以外の終了コードを返した場合のみです。これにより、フックが失敗した理由をクライアントと通信する方法が提供されます。

また、フックが実行される環境はスクラブされているため、注意が必要です。でも$PATHnullです。

これらは、フック スクリプトがコマンド ラインから正常に実行される理由の一部ですが、フックとして実行された場合にはそうではありません。

フックが機能していると思わない場合は、ゼロ以外の終了コードで終了するように設定してください。Subversion からトランザクションが失敗したというメッセージが返ってきたら、フック スクリプトが実行されたことがわかります。

svnserveまた、リポジトリを使用しているのはあなただけであっても、少なくとも Subversion サーバーとして使用することをお勧めします。file://リポジトリを使用しているのは私だけであっても、私は決して使用しません。このsvnserveプロセスは非常に使いやすく、かなり軽量です。

また、svnフック スクリプトでは使用しないでください。svnlook代わりに使用してください。


補遺

私はこれについて非常に明確にしたいと思います。いくつかの定義に同意する必要があります。

  • SERVER は、Subversion リポジトリを実行しているマシンです。コマンドを使用して、リポジトリ自体として機能するディレクトリsvnadmin create fooを作成しました。foo
  • svnadmin createREPOSITORY DIRECTORY は、コマンドによって作成されたサーバー上のディレクトリです。これはリポジトリのサーバー側です。Subversion にチェックインしたファイルはここには表示されません。代わりに、hooksディレクトリとディレクトリが表示されますdb。これは、サーバーがその変更を追跡するために使用するものです。
  • svn checkoutWORKING DIRECTORY は、プロジェクトの特定のリビジョンをチェックアウトするために行ったディレクトリです。
  • REPOSITORY は、またはなどのさまざまなsvnコマンドを使用したときに取得する REPOSITORY DIRECTORY の仮想ビューです。これは REPOSITORY DIRECTORY ではなく、リポジトリのビューです。svn lssvn logsvn co

さて、これで解決しました:

hooksフック スクリプトは、ディレクトリの下の REPOSITORY DIRECTORY に格納されます。hooksREPOSITORY DIRECTORY を作成すると、フック スクリプト用のいくつかのテンプレートで呼び出されるサブディレクトリが既に存在します。これらには*.tmplサフィックスが付きます。フックを作成するには、これらのスクリプトのいずれかをフック スクリプトに置き換え、その*.tmplサフィックスを削除する必要があります。フック スクリプトには、実行権限があり、Subversion SERVER プロセスを実行しているユーザーが所有している必要があります。(サーバー上で実行中のユーザーhttpdまたはsvnserveコマンド)。

フックはリポジトリ全体用です。特定のブランチが影響を受ける場合にのみフックを起動しないように指示することはできません。ただし、フック スクリプトは、ファイルの場所を確認し、それに基づいてアクションを実行できます。まさにそれを行うpre-commit フックがあります。制御ファイルを使用して、ファイルの場所に基づいて必要なアクションを決定します。ただし、コミットが発生するたびに、何もする必要がない場合でも、このフックが起動します。

これがあなたの質問に答えることを願っています。

于 2013-02-20T03:10:27.607 に答える
1

のように、出力ファイルを別の場所で使用してみました/tmpか? 作業コピー ディレクトリに書き戻そうとしているように思えますが、フック スクリプトがそこにアクセスできないのではないでしょうか?

フックは、SVNクライアントではなく、 SVNサーバー プロセスが実行されているユーザーとして実行されることに注意してください。したがって、Apache WebDAV タイプのアクセスを使用している場合は、Apache のユーザーになります (と思います)。SSH アクセスを使用している場合は、構文にリストされているユーザーです。svn+ssh://user@path

于 2013-02-19T20:58:41.007 に答える
0

hooks/pre-commit.tmpl ファイルを変更すると、次のようになります

pre-commit フックには、pre-commit という名前を付ける必要があります。pre-commit.tmpl は単なるサンプル ファイルであり、実行されることはありません。

于 2013-02-20T01:46:33.157 に答える
0

あなたの質問を読んだ後、私は少し混乱しています。私はあなたの理解が正しいことを確認するためにここにいました:

Subversion には「チェックアウトされたレポ」というものはありません。リポジトリ (通常はリモート サーバー内) があり、そのリポジトリからチェックアウトすると、ローカルの作業コピーができます。フックは、ローカルの作業コピーではなく、リポジトリで発生するものです。

手順の説明から、これは私が得るものです:

  1. リモート リポジトリからチェックアウトしました: リモート サーバー

  2. チェックアウトされた作業コピーにはコンテンツがないため、新しい svn リポジトリをローカルに作成し、/hooks フォルダーを含むすべてをチェックアウトした作業コピーにコピーしました。

  3. チェックアウトした作業コピーに空のファイルを作成し、テキスト行を追加しました。次に、svn でこのファイルを追加します。

  4. 作業コピーの hooks/pre-commit.tmpl ファイルを変更し、次のようになりました: (削除)

  5. すべてのユーザーに実行許可を追加し、pre-commit.tmpl を pre-commit にコピーします(これらはすべて作業コピーで行われます)。

  6. チェックアウトした作業コピーで、svn commit -m "dumb change" を使用して変更をコミットしました。

私の理解が正しければ、単にフックの使用法を誤解しているだけです。フックは、作業コピーではなく、リポジトリに配置されるものです。フックは、ローカル マシンではなく、コミット中 (または他のアクションを実行中) にリポジトリ マシンで実行されます。

于 2013-02-20T02:41:10.003 に答える