如何在git中使用.gitignore文件忽略二进制文件?

例子:

$ g++ hello.c -o hello

“hello”文件是二进制文件。git可以忽略这个文件吗?


当前回答

这是另一个使用文件的解决方案。这样,可执行脚本就不会在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)

其他回答

要将所有可执行文件追加到.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打开文件以供读取之前截断该文件。此外,您可能还想添加\!正则表达式”。* / * /。如果您不希望在子目录中包含可执行文件,则可以将*'作为查找选项。

对于二进制文件,最好的办法是为它们提供一个可以用标准模式轻松过滤掉的扩展名,或者将它们放入可以在目录级别过滤掉的目录中。

扩展建议在Windows中更适用,因为扩展是标准的,并且基本上是必需的,但在Unix中,您可以对可执行二进制文件使用扩展,也可以不使用扩展。在这种情况下,您可以将它们放在bin/文件夹中,并将bin/添加到.gitignore中。

在您非常具体的小范围示例中,您可以将hello放在.gitignore中。

.gitignore机制仅基于文件名工作,而不是基于文件内容。二进制文件是内容的属性,因此你不能要求git直接忽略二进制文件,而只能通过名称来忽略它们(正如其他人建议的那样,你可以将所有二进制文件名添加到.gitignore中,或者使用适当的命名约定)。

事实上,.gitignore处理文件名是一个重要的性能属性:Git只需要列出文件,而不需要打开和读取它们来知道要忽略哪些文件。换句话说,如果您要求Git根据文件的内容忽略文件,那么Git会非常慢。

我在GOPATH目录中创建了一个包含两个条目的.gitignore文件。

/bin
/pkg

目前,它忽略所有已编译的开发。

你可以试试你的。gitignore:

*
!*.c

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