コミットで変更されたファイルに応じて、Gitのpre-またはpost-commitフックを使用して、自動生成されたファイルを同じコミットに追加したいと思います。これについてどうすればいいですか?
私はこれをコミット前のフックとして試しましたが、運はありません:
#!/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行を使用してみましたが、どちらも良くありません。
Git addもプリコミットでは機能しなかったため、.commitファイルを使用してプロセスをプリコミットとポストコミットに分割するというマークの考えに従いました。
これは理解しやすいコードです
事前コミットでは:
- ファイルの.commitなどをタップします。 (必ずこれを.gitignoreに追加してください)
#!/bin/sh
echo
touch .commit
exit
コミット後:
.commitが存在する場合、コミットは行われたが、ポストコミットはまだ実行されていないことがわかります。したがって、ここでコード生成を行うことができます。さらに、.commitが存在するかどうかをテストします。
- ファイルを追加する
- commit --amend -C HEAD --no-verify(ループを回避)
- .commitファイルを削除する
#!/bin/sh
echo
if [ -a .commit ]
then
rm .commit
git add yourfile
git commit --amend -C HEAD --no-verify
fi
exit
これにより、bashの知識がほとんどない人でもマークのアイデアを理解しやすくなります。
Pre-commitフックを使用して、必要なことを実行できます。 herokuのデプロイ(coffeescriptをjavascriptにコンパイルする)でも同様のことを行います。スクリプトが機能しないのは、exec
コマンドを不適切に使用したためです。
man page から:
組み込みの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
コミット前後のスクリプトを組み合わせて使用できます。
事前コミットでは:
コミット後:
.commitが存在する場合、コミットは行われたが、ポストコミットはまだ実行されていないことがわかります。したがって、ここでコード生成を行うことができます。さらに、.commitが存在するかどうかをテストします。
これはおおまかにメタストアから生成されたリポジトリに.metadataファイルを格納するために使用するプロセスです。
誰かがより良い方法を知っているなら、私はすべて耳ですが、今のところうまくいくようです。
_#!/bin/sh
#
# .git/hooks/pre-commit
#
git add file.xyz
_
これでうまくいきました。現在のコミットの一部になります。
git version 1.7.12.4 (Apple Git-37)
update-index
を使用できます。
git update-index --add my_files
post-commit
スクリプトを使用してファイルを生成し、次にthatを実行します(行に沿って何か)git add my_files; git commit --amend
。
ファイルが自動的に生成され、どこでも生成できる場合(Gitのpre-commitフックでビルドしたいという暗黙の意)、そもそもソース管理下に置くべきではありません。ソースファイルのみを制御する必要があります。生成されたファイルは、ビルドスクリプトの一部として生成されます。
生成されたファイルをソース管理下に置く唯一の理由は、生成するために一意の/特権付きリソース(ライセンスプログラムなど)が必要な場合、または生成にかなりの時間が必要な場合です。
追加
http://git-scm.com/docs/githooks から:
pre-commitこのフックはgit commitによって呼び出され、-no-verifyオプションでバイパスできます。これはパラメーターを取りません。提案されたコミットログメッセージを取得してコミットする前に呼び出されます。このスクリプトからゼロ以外のステータスで終了すると、git commitが中止されます。
デフォルトのpre-commitフックは、有効になっている場合、末尾に空白がある行の導入をキャッチし、そのような行が見つかるとコミットを中止します。
すべてのgit commitフックは、環境変数GIT_EDITOR =:で呼び出されます。コマンドがコミットメッセージを変更するためのエディターを起動しない場合。
Pre-commitフックの目的は、コミットを行う前の、ワークスペースの状態とコミットの内容の合否チェックです。コミットの内容を変更しようとしても機能しません。
私の推奨は、ビルドスクリプトに2つのステップを追加することです:(1)生成する必要のある古いファイルをすべてビルドする(そしてそれらをワークスペースに追加する)ステップ、および(2)そのステップ生成されたすべてのファイルが最新であることを確認し、ゼロ以外のステータスコードを返します。 Gitのプリコミットフックで2番目のステップを実行する必要があります。開発者は、必要に応じて最初のステップを実行するようにトレーニングする必要があります。
私も同じニーズを持っていて、このアプローチは私にはかなりうまくいきました:
#!/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 && git add my_files」として実行できます。
そして、あなたが再びコミットするために事前コミットを必要としないことは事実です(それは無限の厄介なループを作成します:p)
はい、gitフックを使用して、生成されたファイルをcommitに自動的に追加できます。ただし、トリッキーなスクリプトが必要です。
ここで解決した問題を見つけることができます。そこでは、コミットごとにファイルバージョンを更新し、新しい変更されたファイルを追加して、必要に応じてコミットを修正しています。それは完全に機能しています: 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が実行され、フラグファイルが見つかると、何が起こっているかを「認識」します。次に、フラグファイルを削除するだけで、再度作成しません。そうすることで、コミット後のフックがコミットを再度修正するのをブロックし、コミットを完全に終了させることができます。