2009-10-01 3 views
52

gitとpythonを使用すると面白い状況が続きますが、他の状況でも起こりそうです。新しいブランチをチェックアウトするときに、* .pycファイルやそれ以外の場合は空のディレクトリを自動的に削除します

私がフォルダ/ foo /でgit repoを作ったとしましょう。そのフォルダに/foo/program.pyを入れます。私はprogram.pyを実行し、program.pycが作成されます。私は.gitignoreファイルに* .pycを持っているので、gitはそれを追跡しません。

ここで別のブランチ、devを作ってみましょう。このdevブランチでは、/ foo /フォルダを完全に削除します。

これで、masterブランチに戻り、/ foo /が再表示されます。私はprogram.pyを実行し、program.pycファイルが再び現れます。すべては順調です。

私はdevブランチに戻ります。/foo /ディレクトリは消えます。 devブランチではなくmasterブランチにのみ存在します。しかし、それはまだそこにあります。どうして?無視されたprogram.pycファイルは、ブランチの切り替え時にフォルダが削除されないようにするためです。

この問題の解決策は、分岐を切り替える前にすべての* .pycファイルを再帰的に削除することです。私はこのコマンドで簡単にそれを行うことができます。

問題は、私がブランチを変更するたびにほとんどこれを行うことを覚えておかなければならないということです。私はこのコマンドのエイリアスを作ることができましたが、ブランチを変更するたびにタイプすることを覚えておく必要があります。私もgit-branchのエイリアスを作ることができましたが、それはうまくいきません。 git branchコマンドはブランチを変更するだけでなく、私が使用するたびにすべてのpycファイルを削除したくありません。ヘック、私は非パイソンレポでそれを使用するかもしれない、そして何?

ブランチを変更したときにのみ実行するgitフックを設定する方法はありますか?または、ブランチを切り替えるたびに、* .pycファイルをすべて消去するように設定する方法がありますか?

+6

find + rmの代わりに使うことができる 'git clean'コマンドがあります(詳細はマンページを参照してください)。 –

+2

この質問に言及する記事があります:http://codeinthehole.com/writing/a-useful-git-post-checkout-hook-for-python-repos/記事のgitフックコードは、解答に触発されています下記:https://gist.github.com/miebach/7391024 – mit

+0

Javaプロジェクトにもこれらが必要ですか? '* .class'ファイルを削除するには? – dashmug

答えて

40

post-checkoutフックが、.git/hooks/post-checkoutに配置されます。あなたのgitのバージョンによっては、おそらくサンプルがあり、おそらく.sampleまたはおそらく実行可能ではありません。短い説明:以前のHEAD、新しいHEAD、およびブランチが変更された場合は1のフラグ、それが単なるファイルのチェックアウトの場合は0の3つのパラメータを取得します。詳細については、man githooksを参照してください。必要なものを実行してそこに置くためのシェルスクリプトを書くことができるはずです。

編集:チェックアウトが自動的に空になるディレクトリを整理するように、この事前チェックアウトを行うことを検討しています。しかし、事前チェックアウトのフックはありませんので、ディレクトリを削除するためにスクリプトを使用する必要があります。

別名: エイリアスはgitconfigの一部で、リポジトリのローカル(〜/ .gitconfigではなく.git/config)にすることができます。エイリアス(git-checkoutではgit-branchではなく)を使ってこれを行うことを選択した場合、それらを簡単にPython関連のリポジトリに入れることができます。この場合も、この目的のために特別なエイリアスを作成します(例:cc for checkout clean)。 pycファイルをクリーンアップしたくない場合は、チェックアウト(または別のエイリアス形式)を使用することができます。

+3

ありがとう!また、事前チェックアウトフックが必要です。 – Apreche

+0

ええ、gitの開発者はフックを追加するのにかなり控えめなアプローチをとっているようです。あなた自身に1つを追加するのは非常に難しいことではありません! (checkout関数の最後にある)ポストチェックアウトフックへの呼び出しを見ると、古い/新しいハッシュとブランチとファイルチェックアウトフラグをハッシュしてから、ジェネリックを呼び出す1行のラッパー関数を呼び出しますrun_hook関数です。 – Cascabel

+3

私が書いたポストチェックアウトフックはこちらです。それは完全に動作します。 #!/ usr/bin/env bash find/path/to/repo/-name "* .pyc" -exec rm {} \; find/path/to/repo/-depth -type d -empty -exec rmdir {} \; – Apreche

35

だけコピーして更新コメントに埋葬されたAprecheによって良い解決策を:

保存このシェルスクリプトをファイル/path/to/repo/.git/hooks/post-checkoutに、そしてそれを実行します。

#! /bin/sh 

# Start from the repository root. 
cd ./$(git rev-parse --show-cdup) 

# Delete .pyc files and empty directories. 
find . -name "*.pyc" -delete 
find . -type d -empty -delete 
+1

。チェックアウト時にgit repoの最上位ディレクトリにあると仮定して動作します。レポ内でより深くチェックアウトすると、そこからのpycファイルのみがクリーンアップされます。 – Apreche

+1

更新されたスクリプトは常にリポジトリのルートから開始されます。 –

+0

'find。 \(-name '* .pyc' -o -name '* .pyo' \)-exec rm -v {} \;は問題のあるファイルタイプをカバーします。 – Tom

2

私のソリューションは、gitのとより互換性があります。 Gitは任意のファイルをチェックアウトによって削除されただけenptyディレクトリを削除します。完全なワークコピーツリーは検索されません。 だけのpycファイルに関連する:それは、Pythonのバージョンなど

私の最初の実装は非常に明確に原理を説明すると、さまざまなテストのためtoxパッケージにより、仮想環境のような非常に大きな無視ツリーで大きなリポジトリまたはリポジトリに便利ですバージョン管理のファイルが消去されます。それは効率と望ましくない副作用のためです。

#!/bin/bash 
# A hook that removes orphan "*.pyc" files for "*.py" beeing deleted. 
# It doesn not clean anything e.g. for .py files deleted manually. 
oldrev="$1" 
newrev="$2" 
# ignored param: branchcheckout="$3" 

for x in $(git diff --name-only --diff-filter=DR $oldrev..$newrev | grep "\.py$") 
do 
    if test -a ${x}c && ! test -a ${x}; then 
     rm ${x}c 
    fi 
done 

post-checkoutフックが完全なツリーを検索することなく、Gitチェックアウトによって削除されたファイルを正確に知ら取得できるように便利な3つのパラメータを受け取ります。

質問を読んだ後、私はフックコードをPythonに書き直し、空のディレクトリについての要件に従って拡張しました。 * .pycファイルのファイルに問題がある

""" 
A hook to git that removes orphan files "*.pyc" and "*.pyo" for "*.py" 
beeing deleted or renamed by git checkout. It also removes their empty parent 
directories. 
Nothing is cleaned for .py files deleted manually or by "git rm" etc. 
Place it to "my_local_repository/.git/hooks/post-checkout" and make it executable 
""" 
  • 私の完全な短いソースコード(パイソン)
    https://gist.github.com/hynekcer/476a593a3fc584278b87#file-post-checkout-py

    にドキュメンテーション文字列でありますPython 3では重要ではない親ディレクトリに関連する* .py *ファイルがなければ、__pycache__の* .pycファイルは実行できません。

  • フックがリポジトリのルートで毎回開始されるため、変更ディレクトリは不要です。

  • コンパイルされたコード__pycache__のキャッシュディレクトリは、重要ではない(バイナリ配布には参加しない)ため、また部分的な削除が遅くなる可能性があるため、高効率のため完全にクリーンアップされます。
4

もう一つの選択肢は、これをgitの問題として解決するのではなく、Pythonの問題です。 PYTHONDONTWRITEBYTECODE環境変数を使用して、Pythonが最初に.pycファイルを書き込まないようにすることができます。その後、ブランチを切り替えるときに、クリーンアップするものはありません。

関連する問題