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通知更改为源文件,但不是编译文件的存在或更改。