没有二进制文件的gitignore

时间:2011-04-19 03:00:01

标签: git gitignore

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

示例:

$ g++ hello.c -o hello

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

18 个答案:

答案 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)

二进制文件通常没有扩展名。如果是这种情况,请尝试以下操作:

*
!/**/
!*.*

REF:https://stackoverflow.com/a/19023985/1060487

答案 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)

VenomVendors answer

为基础
# 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分钟让我明白了这一点,希望对我这样的新手有帮助