如何使用git
文件在.gitignore
中忽略二进制文件?
示例:
$ g++ hello.c -o hello
“hello”文件是二进制文件。 git
可以忽略此文件吗?
答案 0 :(得分:107)
# 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
答案 1 :(得分:39)
添加类似
的内容*.o
<。>在.gitignore文件中并将其放在您的仓库的根目录下(或者您可以放置在您想要的任何子目录中 - 它将从该级别开始应用)并将其签入。
编辑:
对于没有扩展名的二进制文件,最好将它们放在bin/
或其他文件夹中。毕竟没有基于内容类型的忽略。
你可以尝试
*
!*.*
但这不是万无一失的。
答案 2 :(得分:26)
要将所有可执行文件附加到您的.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 '.*/.*/.*'
作为选项,以查找是否要在子目录中包含可执行文件。
答案 3 :(得分:23)
使用二进制文件最好的办法是给它们一个扩展名,您可以使用标准模式轻松过滤掉它,或者将它们放入可以在目录级别过滤掉的目录中。
扩展建议更适用于Windows,因为扩展是标准的,基本上是必需的,但在Unix中,您可能会也可能不会在可执行二进制文件上使用扩展。在这种情况下,您可以将它们放在bin /文件夹中,并将bin/
添加到.gitignore。
在非常具体的小范围示例中,您只需将hello
放入.gitignore即可。
答案 4 :(得分:13)
您可以尝试使用.gitignore
:
*
!*.c
这种方法有许多缺点,但对小型项目来说是可以接受的。
答案 5 :(得分:12)
如果您正在使用makefile,则可以尝试修改make规则,以将新二进制文件的名称附加到.gitignore文件中。
这是一个小型Haskell项目的Makefile示例;
all: $(patsubst %.hs, %, $(wildcard *.hs))
%: %.hs
ghc $^
grep -xq "$@" .gitignore || echo $@ >> .gitignore
此makefile定义了一个用于从Haskell代码创建可执行文件的规则。在调用ghc之后,我们检查.gitignore以查看二进制文件是否已经在其中。如果不是,我们将二进制文件的名称附加到文件中。
答案 6 :(得分:4)
这是使用文件的另一种解决方案。这样,可执行脚本不会以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)
答案 7 :(得分:3)
在某些子目录中也忽略的方法,不仅在根目录中:
# 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/
中的尾部斜线也是可选的,但仅限于此行。
答案 8 :(得分:1)
只需将hello
或/hello
添加到您的.gitignore即可。要么有效。
答案 9 :(得分:1)
旧线程,但仍然相关。
我更改了makefile,以使链接后生成的二进制文件具有名称[filname]。 bin ,而不仅仅是[filname]。然后我在gitignore中添加了* .bin文件。
这个例行程序满足了我的需求。
答案 10 :(得分:1)
答案 11 :(得分:1)
我不知道任何其他解决方案,只是将它们逐个添加到.gitignore
。
一种粗略的测试方法是grep文件命令的输出:
find . \( ! -regex '.*/\..*' \) -type f | xargs -n 1 file | egrep "ASCII|text"
修改强>
为什么不简单地将可执行文件命名为hello.bin
?
答案 12 :(得分:0)
.gitignore使用glob programming来过滤文件,至少在Linux上。
我准备在Meetup上进行编码谈话,并且在准备中,我创建了一个目录,其中包含几个子目录,这些子目录根据我想要呈现的顺序命名:01_subject1,02_subject2,03_subject3。每个子目录都包含一个源文件,该文件具有依赖于语言的扩展,该文件编译为一个可执行文件,其名称与源文件名匹配,而不是根据惯例的扩展名。
我使用以下.gitignore行排除数字前缀目录中的编译文件:
[0-9][0-9]_*/[!\.]*
根据我对文档的理解,它应该不起作用。使用尾随星号应该会失败,因为它应匹配任意数量的未指定字符,包括“。” +扩展名。省略尾随星号应该失败(并且确实如此),因为[!\.]
仅匹配单个非句点字符。但是,我添加了尾随星号,就像我对正则表达式一样,它可以工作。通过工作,我的意思是 git 注意到源文件的更改,但不是对已编译文件的存在或更改。
答案 13 :(得分:0)
# Ignore all
*
# Unignore all files with extensions recursively
!**/*.*
# Unignore Makefiles recursively
!**/Makefile
# other .gitignore rules...
答案 14 :(得分:0)
将以下内容添加到您的.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"
答案 15 :(得分:0)
.gitignore
机制仅基于文件名称,而不基于文件内容。作为二进制文件是内容的属性,因此您不能要求git直接忽略二进制文件,而只能按名称忽略它们(并且如其他建议那样,您可以将所有二进制文件名添加到{{1} }或使用适当的命名约定。
.gitignore
在文件名上起作用的事实是从性能角度考虑的重要属性:Git仅需要列出文件,而无需打开和读取文件即可知道要忽略的文件。换句话说,如果您可以要求Git根据文件的内容忽略文件,它将非常慢。
答案 16 :(得分:0)
我在GOPATH目录中创建了一个带有两个条目的.gitignore文件。
/bin
/pkg
目前忽略了所有已编制的开发项目。
答案 17 :(得分:0)
如果对.gitignore文件执行以下命令,但文件似乎仍然出现,您可能需要尝试:
git rm --cached FILENAME
然后,添加您的.gitignore,提交并推送。 花了40分钟让我明白了这一点,希望对我这样的新手有帮助