81

そのコミットで変更されたファイルに応じて、Git のコミット前またはコミット後のフックを使用して、自動生成されたファイルを同じコミットに追加したいと考えています。これについてどうすればいいですか?

これをプリコミットフックとして試しましたが、うまくいきませんでした:

#!/bin/sh
files=`git diff --cached --name-status`
re="<files of importance>"
if [[ $files =~ $re ]]
then
  echo "Creating files"
  exec bundle exec create_my_files
  exec git add my_files
  exec git commit --amend -C HEAD
fi

これにより、それらがリポジトリに正常に追加されますが、コミットには追加されません。また、コミット前のインスペクションとともに、コミット後のフックで最後の2つのexec行を使用しようとしましたが、どちらもうまくいきませんでした。

4

10 に答える 10

70

git add もプリコミットでは機能しなかったため、.commit ファイルを使用してプロセスをプリコミットとポストコミットに分割するというマークのアイデアに従いました。

ここに理解しやすいはずのコードがあります

事前コミットで:

  • ファイル .commit などに触れます。(必ず .gitignore に追加してください)
#!/bin/sh 
echo 
touch .commit 
exit

コミット後:

.commit が存在する場合、コミットが行われたばかりであることがわかりますが、ポストコミットはまだ実行されていません。したがって、ここでコード生成を行うことができます。さらに、.commit が存在するかどうかをテストします。

  • ファイルを追加する
  • commit --amend -C HEAD --no-verify (ループを避ける)
  • .commit ファイルを削除
#!/bin/sh
echo
if [ -e .commit ]
    then
    rm .commit
    git add yourfile
    git commit --amend -C HEAD --no-verify
fi
exit

これにより、bash の知識がほとんどない人でも、mark のアイデアに従うことが容易になることを願っています。

于 2012-10-09T14:44:03.713 に答える
36

pre-commit フックを使用して、必要なことを行うことができます。Heroku のデプロイでも同様のことを行います (coffeescript を javascript にコンパイルします)。スクリプトが機能しない理由は、execコマンドを不適切に使用したためです。

マニュアルページから:

exec ビルトインは、現在実行中のシェル プロセス イメージを新しいコマンドに置き換えるために使用されます。正常に完了すると、exec は戻りません。exec はパイプライン内では使用できません。

最初の exec コマンドだけが実行されています。その後、スクリプトは基本的に終了します。

次のようなものを試してみてください (pre-commit フックとして):

#!/bin/sh
files=`git diff --cached --name-status`
re="<files of importance>"
if [[ $files =~ $re ]]
then
  echo "Creating files"
  bundle exec create_my_files
  git add my_files
fi
于 2010-10-19T19:14:16.467 に答える
14
#!/bin/sh
#
#  .git/hooks/pre-commit
#

git add file.xyz

これは私にとってはうまくいきました。これは現在のコミットの一部になります。

git version 1.7.12.4 (Apple Git-37)

于 2013-02-14T12:03:05.590 に答える
10

使用できますupdate-index

git update-index --add my_files

于 2010-07-19T19:26:46.903 に答える
10

コミット前スクリプトとコミット後スクリプトを組み合わせて使用​​できます。

事前コミットで:

  • ファイル .commit などに触れます。(必ず .gitignore に追加してください)

コミット後:

.commit が存在する場合、コミットが行われたばかりであることがわかりますが、ポストコミットはまだ実行されていません。したがって、ここでコード生成を行うことができます。さらに、.commit が存在するかどうかをテストします。

  • ファイルを追加する
  • commit --amend -C HEAD --no-verify (ループを避ける)
  • .commit ファイルを削除

これは、metastore から生成されたリポジトリに .metadata ファイルを格納するために使用するおおよそのプロセスです。

誰かがより良い方法を知っていれば、私はすべて耳にしますが、今のところうまくいくようです。

于 2012-04-16T20:14:44.340 に答える
2

ファイルが自動的に生成され、どこにでも生成できる場合 (Git pre-commit フックでそれらをビルドしたいという意図があることを暗示しています)、そもそもそれらをソース管理下に置くべきではありません。ソース ファイルのみを制御する必要があります。生成されたファイルは、ビルド スクリプトの一部として生成する必要があります。

生成されたファイルをソース管理下に置く唯一の理由は、生成に固有の/特権リソース (ライセンス プログラムなど) が必要な場合、または生成にかなりの時間がかかる場合です。

追加した

http://git-scm.com/docs/githooksから:

pre-commitこのフックは git commit によって呼び出され、 --no-verify オプションでバイパスできます。パラメーターを必要とせず、提案されたコミット ログ メッセージを取得してコミットを行う前に呼び出されます。このスクリプトをゼロ以外のステータスで終了すると、git commit が中止されます。

デフォルトの pre-commit フックは、有効にすると、末尾に空白がある行の導入をキャッチし、そのような行が見つかったときにコミットを中止します。

すべての git コミット フックは、環境変数 GIT_EDITOR=: で呼び出されます。コマンドがコミット メッセージを変更するためのエディターを表示しない場合。

pre-commit フックの目的は、コミットを行う前に、ワークスペースの状態とコミットの内容を合否チェックすることです。コミットの内容を変更しようとしてもうまくいきません。

ビルド スクリプトに次の 2 つの手順を追加することをお勧めします。(1) 生成する必要があるすべての古いファイルをビルドする手順 (およびそれらをワークスペースに追加する手順)、および (2) 次の手順を実行します。生成されたすべてのファイルが最新であることを確認し、ゼロ以外のステータス コードを返します。Git precommit フックは、2 番目のステップを実行する必要があります。開発者は、必要に応じて最初のステップを実行できるようにトレーニングする必要があります。

于 2010-07-19T19:32:39.300 に答える
2

post-commit代わりに、ファイルを生成するスクリプトを作成し、それを実行するのはどうですか(の行に沿った何か) git add my_files; git commit --amend

于 2010-07-19T20:31:41.343 に答える
1

私にも同じニーズがあり、このアプローチは私にとって非常にうまくいきました。

#!/bin/sh
files='git diff --cached --name-only'
re="<files of importance>"
if [[ $files =~ $re ]]
then
   echo "Creating files"
   create_my_files && git add my_files
fi

ここで、「create_my_files」は実行可能である必要があります。たとえば、Pythonファイルの場合は、「python create_my_files &&gitaddmy_files」として実行できます。

確かに、再度コミットするために事前コミットは必要ありません(これにより、無限の厄介なループが作成されます:p)

于 2012-01-10T00:57:22.300 に答える
1

はい、git フックを使用して、コミット時に生成されたファイルを自動的に追加できます。しかし、それにはトリッキーなスクリプトが必要です。

ここで、解決した問題を見つけることができます。そこでは、コミットごとにファイル バージョンを更新し、新しい変更されたファイルを追加し、必要に応じてコミットを修正します。完全に機能しています: https://github.com/evandrocoan/.versioning

次に、「updateVersion.sh」ファイルの「バージョン ファイルの置換」アルゴリズムをアルゴリズムに置き換えます。ブランチの制限を削除するなど、いくつかの変更が必要になる場合があります。これは、'develop' ブランチにいる場合にのみスクリプトが実行されるためです。

また、ステージングされている場合、指定されたファイルのみを変更します。ファイルがステージングされていない場合、通常のコミット以外は何もしません。より正確には、すべてのステップで何をしているかを出力します。

その裏技、解説します。それはかなりトリッキーです。prepare-commit-msg-hook で、目的のファイルがステージングおよびコミットされているかどうかを検出します。その後、フラグ ファイルを作成し、prepare-commit-msg-hook を停止します。その後、post-commit-hook で、フラグ ファイルが存在するかどうかを確認します。はいの場合、コミット時にファイルを修正します。

注意、それは prepare-commit-msg-hook を再度呼び出すため、無限ループを作成します (修正中です)。しかし、フラグファイルが原因で発生しません。prepare-commit-msg-hook が実行されてフラグ ファイルが見つかると、何が起こっているかを「認識」します。次に、フラグファイルを削除するだけで、再度作成しません。これを行うと、post-commit-hook がコミットを再度修正するのをブロックし、コミットを完全に終了できるようにします。

于 2016-07-21T04:03:47.480 に答える