gitignore没有二进制文件

如何使用.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/或其他文件夹中。 毕竟不存在基于内容types的忽视。

你可以试试

 * !*.* 

但这不是万无一失的。

与二进制文件最好的select是给它们一个扩展,你可以很容易地过滤出一个标准模式,或者把它们放到可以在目录级别过滤掉的目录中。

扩展build议更适用于Windows,因为扩展是标准的,基本上是必需的,但在Unix中,您可能会或可能不会在可执行文件上使用扩展名。 在这种情况下,你可以把它们放在一个bin /文件夹中,并将bin/添加到你的.gitignore中。

在你非常具体的小范围的例子中,你可以在你的.gitignore中打个hello

要追加所有可执行文件到你的.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 '.*/.*/.*' \! -regex '.*/.*/.*'作为选项来查找是否不想在子目录中包含可执行文件。

你可以试试你的.gitignore

 * !*.c 

这种方法有许多缺点,但对于小型项目来说是可以接受的。

如果您使用的是makefile,则可以尝试修改make规则,以将新的二进制文件的名称附加到.gitignore文件中。

下面是一个Haskell小项目的示例Makefile。

 all: $(patsubst %.hs, %, $(wildcard *.hs)) %: %.hs ghc $^ grep -xq "$@" .gitignore || echo $@ >> .gitignore 

这个makefile定义了一个用Haskell代码创build可执行文件的规则。 在调用ghc之后,我们检查.gitignore以查看二进制文件是否已经存在。 如果不是,我们将二进制文件的名称附加到文件中。

这是另一个使用file的解决scheme。 这样可执行脚本不会在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) 

一种方式也忽略了一些subdir,不仅在一个根:

 # 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/**/*.* 

或者,如果您只想包含一些特定types的文件:

 /* !/*.c !/*.h !/subdir/ /subdir/**/* !/subdir/**/ !/subdir/**/*.c !/subdir/**/*.h 

似乎它甚至可以像每个新的子目录一样工作!

 /* !/*.c !/*.h !/*/ /*/**/* !/*/**/ !/*/**/*.c !/*/**/*.h 

主要的斜线只在前两行很重要,在其他的时候是可选的。 !/*/!/subdir/尾部斜杠也是可选的,但仅限于此行。

只需在你的.gitignore中添加hello/hello即可。 要么工作。

我不知道任何其他解决scheme,但将它们逐一添加到.gitignore

粗略的testing方法是grep文件命令的输出:

 find . \( ! -regex '.*/\..*' \) -type f | xargs -n 1 file | egrep "ASCII|text" 

编辑

你为什么不简单地命名你的可执行文件hello.bin

我在GOPATH目录中创build了两个条目的.gitignore文件。

 /bin /pkg 

目前,它忽略了所有编制的事态发展。

.gitignore使用glob编程来过滤文件,至less在Linux上。

我正准备在Meetup上进行编码讨论,准备好后,我制作了一个目录,其中有几个子目录按照我想要显示的顺序命名:01_subject1,02_subject2,03_subject3。 每个子目录都包含一个具有语言相关扩展的源文件,根据惯例,该源文件编译为名称与源文件名匹配的可执行文件,而不带扩展名。

我使用以下.gitignore行排除数字前缀目录中的编译文件:

[0-9][0-9]_*/[!\.]*

根据我对文档的理解,它不应该工作。 尾随星号应该失败,因为它应该匹配任意数量的未指定的字符,包括“。”。 +扩展名。 省略尾随星号应该失败(并且),因为[!\.]只匹配一个非句点字符。 但是,我添加了尾随星号,就像我为正则expression式,它的工作原理。 通过工作,我的意思是git通知更改为源文件,但不是编译文件的存在或更改。