.gitignore
ファイルを使用してgit
でバイナリファイルを無視するにはどうすればよいですか?
例:
$ g++ hello.c -o hello
「hello」ファイルはバイナリファイルです。 git
はこのファイルを無視できますか?
# Ignore all
*
# Unignore all with extensions
!*.*
# Unignore all dirs
!*/
### Above combination will ignore all files without extension ###
# Ignore files with extension `.class` & `.sm`
*.class
*.sm
# Ignore `bin` dir
bin/
# or
*/bin/*
# Unignore all `.jar` in `bin` dir
!*/bin/*.jar
# Ignore all `library.jar` in `bin` dir
*/bin/library.jar
# Ignore a file with extension
relative/path/to/dir/filename.extension
# Ignore a file without extension
relative/path/to/dir/anotherfile
次のようなものを追加します
*.o
.gitignoreファイルでそれをリポジトリのルートに配置し(または任意のサブディレクトリに配置できます-そのレベルから適用されます)、チェックインします。
編集:
拡張子のないバイナリの場合は、bin/
または他のフォルダに配置することをお勧めします。結局、コンテンツタイプに基づく無視はありません。
あなたが試すことができます
*
!*.*
しかし、それは絶対確実ではありません。
すべての実行可能ファイルを.gitignore
(おそらくあなたの質問から判断すると「バイナリファイル」という意味です)に追加するには、次を使用できます。
find . -executable -type f >>.gitignore
.gitignore
の行の順序を気にしない場合は、次のコマンドを使用して.gitignore
を更新することもできます。このコマンドも重複を削除し、アルファベット順をそのまま保持します。
T=$(mktemp); (cat .gitignore; find . -executable -type f | sed -e 's%^\./%%') | sort | uniq >$T; mv $T .gitignore
cat
が読み取りのためにファイルを開く前にファイルを切り捨てるので、出力を.gitignore
に直接パイプすることはできません。また、サブディレクトリに実行可能ファイルを含めたくない場合に検索するオプションとして\! -regex '.*/.*/.*'
を追加することもできます。
バイナリの最善の策は、標準パターンで簡単に除外できる拡張子を与えるか、ディレクトリレベルで除外できるディレクトリに配置することです。
拡張機能の提案は、拡張機能が標準であり基本的に必要であるため、Windowsにより適していますが、Unixでは、実行可能バイナリで拡張機能を使用する場合としない場合があります。この場合、それらをbin /フォルダーに入れて、bin/
を.gitignoreに追加できます。
非常に具体的な小さなスコープの例では、.gitignoreにhello
を入れるだけです。
.gitignore
で試すことができます:
*
!*.c
このアプローチには多くの欠点がありますが、小規模なプロジェクトには受け入れられます。
Makefileを使用している場合は、makeルールを変更して、新しいバイナリの名前を.gitignoreファイルに追加してみてください。
これは、小さなHaskellプロジェクトのMakefileの例です。
all: $(patsubst %.hs, %, $(wildcard *.hs))
%: %.hs
ghc $^
grep -xq "$@" .gitignore || echo $@ >> .gitignore
このメイクファイルは、Haskellコードから実行可能ファイルを作成するためのルールを定義します。 ghcが呼び出されたら、.gitignoreをチェックして、バイナリが既に含まれているかどうかを確認します。そうでない場合は、バイナリの名前をファイルに追加します。
ファイルを使用した別のソリューションを次に示します。このようにして、実行可能スクリプトはgitignoreになりません。ファイルからの出力をシステムに合わせて解釈する方法を変更する必要がある場合があります。次に、コミットするたびにこのスクリプトを呼び出すプリコミットフックを設定できます。
import subprocess, os
git_root = subprocess.check_output(['git', 'root']).decode("UTF-8").strip()
exes = []
cut = len(git_root)
for root, dirnames, filenames in os.walk(git_root+"/src/"):
for fname in filenames:
f = os.path.join(root,fname)
if not os.access(f,os.X_OK):
continue
ft = subprocess.check_output(['file', f]).decode("UTF-8")
if 'ELF' in ft and 'executable' in ft:
exes.append(f[cut:])
gifiles = [ str.strip(a) for a in open(git_root + "/.gitignore").readlines() ]
gitignore=frozenset(exes+gifiles)
with open(git_root+"/.gitignore", "w") as g:
for a in sorted(gitignore):
print(a, file=g)
多くの場合、バイナリファイルには拡張子がありません。これがあなたの場合はこれを試してください:
*
!/**/
!*.*
ルートだけでなく、いくつかのサブディレクトリでも無視する方法:
# Ignore everything in a root
/*
# But not files with extension located in a root
!/*.*
# And not my subdir (by name)
!/subdir/
# Ignore everything inside my subdir on any level below
/subdir/**/*
# A bit of magic, removing last slash or changing combination with previous line
# fails everything. Though very possibly it just says not to ignore sub-sub-dirs.
!/subdir/**/
# ...Also excluding (grand-)children files having extension on any level
# below subdir
!/subdir/**/*.*
または、特定の種類のファイルのみを含める場合:
/*
!/*.c
!/*.h
!/subdir/
/subdir/**/*
!/subdir/**/
!/subdir/**/*.c
!/subdir/**/*.h
必要に応じて、すべての新しいサブディレクトリでも同様に機能するようです!:
/*
!/*.c
!/*.h
!/*/
/*/**/*
!/*/**/
!/*/**/*.c
!/*/**/*.h
先頭のスラッシュは、最初の2行でのみ重要であり、その他の行ではオプションです。 !/*/
および!/subdir/
の末尾のスラッシュもオプションですが、この行のみです。
.gitignoreファイルでこれらのコマンドを実行してもファイルが表示される場合は、試してみてください。
git rm --cached FILENAME
その後、.gitignore、commit、Pushを追加します。それを理解するために40分かかった、これが私のような初心者に役立つことを願って
古いスレッドですが、まだ関連しています。リンク後に生成されるバイナリファイルの名前が[filname]になるようにmakefileを変更しました。bin次に、gitignoreに* .binファイルを追加しました。
このルーチンは私のニーズを満たします。
他の解決策は知りませんが、それらを1つずつ.gitignore
に追加します。
テストの大まかな方法は、fileコマンドの出力をgrepすることです。
find . \( ! -regex '.*/\..*' \) -type f | xargs -n 1 file | egrep "ASCII|text"
編集
単に実行可能ファイルにhello.bin
という名前を付けないのはなぜですか?
hello
または/hello
を.gitignoreに追加するだけです。どちらも動作します。
# Ignore all
*
# Unignore all files with extensions recursively
!**/*.*
# Unignore Makefiles recursively
!**/Makefile
# other .gitignore rules...
GOPATHディレクトリに2つのエントリを持つ.gitignoreファイルを作成しました。
/bin
/pkg
現在、コンパイルされたすべての開発を無視します。
.gitignore
メカニズムは、ファイルコンテンツではなく、ファイル名前に基づいてのみ機能します。バイナリファイルであることはコンテンツのプロパティであるため、gitにバイナリファイルを直接無視するように要求することはできませんが、名前でそれらを無視するだけです(他の提案として、すべてのバイナリファイル名を.gitignore
に追加するか、適切な命名規則)。
.gitignore
がファイル名で機能するという事実は、パフォーマンス面で重要なプロパティです。Gitはファイルをリストするだけでよく、無視してどのファイルを知るためにファイルを開いて読み取る必要はありません。言い換えれば、Gitの内容に基づいてファイルを無視するように要求できれば、Gitは非常に遅くなります。
.gitignoreは、少なくともLinuxでは、 glob programming を使用してファイルをフィルタリングします。
Meetupでコーディングの話をしようとしていますが、準備として、提示したい順序に従って名前が付けられた複数のサブディレクトリを持つディレクトリを作成しました:01_subject1、02_subject2、03_subject3。各サブディレクトリには、言語依存の拡張子を持つソースファイルが含まれており、一般的な慣行に従って、拡張子のないソースファイル名に一致する名前の実行可能ファイルにコンパイルされます。
次の.gitignore行を使用して、数字で始まるディレクトリのコンパイル済みファイルを除外します。
[0-9][0-9]_*/[!\.]*
ドキュメントの私の理解によると、それは動作しないはずです。末尾のアスタリスクは、「。」を含む任意の数の不特定の文字と一致する必要があるため、失敗します。 +拡張。 [!\.]
はピリオド以外の単一の文字とのみ一致するため、末尾のアスタリスクを省略すると失敗します(失敗します)。ただし、正規表現の場合と同様に、末尾のアスタリスクを追加しましたが、機能します。仕事では、gitはソースファイルへの変更を通知しますが、コンパイルされたファイルの存在または変更は通知しません。
以下を.gitignoreファイルに追加します。
[^\.]*
説明:
[] encloses a character class, e.g. [a-zA-Z] means "any letter".
^ means "not"
\. means a literal dot - without the backslash . means "any character"
* means "any number of these characters"