git
使用.gitignore
文件时如何忽略二进制文件?
例:
$ g++ hello.c -o hello
“ hello”文件是一个二进制文件。可以git
忽略此文件吗?
[^\.]*
。
git
使用.gitignore
文件时如何忽略二进制文件?
例:
$ g++ hello.c -o hello
“ hello”文件是一个二进制文件。可以git
忽略此文件吗?
[^\.]*
。
Answers:
# 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
!/**/
代替!*/
;哪一个是正确的?/ cc @VonC
添加类似
*.o
在.gitignore文件中,并将其放置在仓库的根目录中(或者您可以将其放置在所需的任何子目录中-从该级别开始应用),然后将其检入。
编辑:
对于没有扩展名的二进制文件,最好将它们放在bin/
其他文件夹中。毕竟,没有基于内容类型的忽略。
你可以试试
*
!*.*
但这不是万无一失的。
gcc
通过创建的文件做同样的事情-o $@
。
要将所有可执行文件附加到您的.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
请注意,您不能直接将输出通过管道传输到.gitignore
,因为这会在cat
打开文件进行读取之前截断文件。另外,您可能希望添加\! -regex '.*/.*/.*'
一个选项来查找是否不想在子目录中包括可执行文件。
您可以尝试.gitignore
:
*
!*.c
这种方法有很多缺点,但是对于小型项目是可以接受的。
如果使用的是makefile,则可以尝试修改make规则,以将新二进制文件的名称附加到.gitignore文件中。
这是一个小的Haskell项目的示例Makefile。
all: $(patsubst %.hs, %, $(wildcard *.hs))
%: %.hs
ghc $^
grep -xq "$@" .gitignore || echo $@ >> .gitignore
这个makefile定义了一个用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
斜杠仅在前两行中很重要,而在其他行中则是可选的。尾部的斜线!/*/
和!/subdir/
也是可选的,但仅限于此行。
如果对.gitignore文件执行以下命令,但文件似乎仍然出现,则可能需要尝试:
git rm --cached FILENAME
之后,添加您的.gitignore,提交并推送。花了40分钟让我明白了这一点,希望对我这样的新手有所帮助
旧线程,但仍然相关。我更改了makefile,因此链接后生成的二进制文件的名称为[filname]。bin,而不只是[filname]。然后我在gitignore中添加了* .bin文件。
这个例行程序满足了我的需求。
.gitignore使用Glob编程至少在Linux上来过滤文件。
我将在一次Meetup上进行编码讨论,并且在准备过程中,我创建了一个目录,其中包含几个子目录,这些子目录根据我想要显示的顺序命名:01_subject1、02_subject2、03_subject3。每个子目录都包含一个源文件,该文件具有与语言相关的扩展名,根据常规惯例,该文件会编译为名称与源文件名匹配且没有扩展名的可执行文件。
我使用以下.gitignore行将编译后的文件排除在数字前缀目录中:
[0-9][0-9]_*/[!\.]*
根据我对文档的理解,它不起作用。星号结尾应失败,因为它应与任意数量的未指定字符匹配,包括“。”。+扩展名。省略结尾的星号应该会失败(并且确实会失败),因为[!\.]
仅匹配一个非句点字符。但是,我像在正则表达式中一样添加了结尾的星号,并且可以使用。通过工作,我的意思是git注意到对源文件的更改,但没有注意到已编译文件的存在或更改。
# Ignore all
*
# Unignore all files with extensions recursively
!**/*.*
# Unignore Makefiles recursively
!**/Makefile
# other .gitignore rules...