git 过滤规则设置(.gitignore)

git 过滤规则设置(.gitignore)

[TOC]

本文简单介绍如何设置过滤 Git 文件的规则.

背景

Git 仓库中有些文件我们并不想追踪并传到 Git 上. 这个时候可以通过设置一些规则过滤掉它们, 使它们成为 ignored 状态. 每次通过手动区分的 git add FILE 命令明显不够用.

需要过滤的文件类型举例:

  • 依赖模块的缓存 /node_modules or /packages
  • 编译结果 .o, .pyc, and .class files
  • 构建结果 /bin, /out, or /target
  • 运行时刻的日志等中间文件 .log, .lock, or .tmp
  • 系统隐藏文件 .DS_Store or Thumbs.db
  • 个人 IDE 配置 .idea/workspace.xml

方法

4种方法

  1. 仓库忽略-共享规则

    当前仓库使用, 在当前仓库任意目录下创建 .gitignore 文件即可, Git 会通过它提供的规则忽略文件. .gitignore 文件可以提交到公有仓库中, 可以为该项目下的所有开发者都共享一套定义好的忽略规则.

    • 远程共用的效果需要将 .gitignore 文件加入 Git 的版本管理.
    • .gitignore 文件规则存在冲突时, 当前目录中的优先于父级目录中的, 更多优先级规则在后面.
  2. 仓库忽略-本地个人规则

    当前仓库使用. 编辑当前项目下的 $GIT_DIR/info/exclude 文件, 然后将需要忽略提交的文件写入其中. 此规则不会被共享. $GIT_DIR 为当前仓库中的 .git/ 目录.

  3. 全局忽略-个人所有仓库通用规则

    本地所有仓库中共同使用的忽略规则. 也是不共享的.

    • 命令行: 直接修改 core.excludesFile 值即可.

    • 修改配置文件: 修改 ~/.gitconfig 文件, 在 [core] 区域添加 excludesfile 属性, 如下:

      1
      2
      [core]
      excludesFile = ~/.gitignore

      或者如下自定义配置文件

      1
      git config --global core.excludesfile ~/.gitignore

​ 注:core.excludesFile 的默认值为 ~/.config/git/ignore.

  1. 命令行式忽略

    通过命令行提供忽略规则, 根据参数不同, 可达到 远程/本地 的效果. $GIT_DIR/info/exclude 文件第一行有如下底层(plumbing)命令.

    1
    git ls-files --others --exclude-from=.git/info/exclude

    实际上通过此命令也可以设置忽略规则文件. 具体用法可以参考命令手册翻译.

规则的优先级

.gitingore 文件中, 每一行指定一个忽略规则, Git 检查忽略规则的时候有多个来源, 它的优先级如下(由高到低):

  1. 从命令行中读取可用的忽略规则
  2. 当前目录定义的规则
  3. 父级目录定义的规则, 依次递推
  4. $GIT_DIR/info/exclude 文件中定义的规则
  5. core.excludesfile 中定义的全局规则

规则的匹配语法

.gitignore 文件中, 每一行的忽略规则的语法如下:

  1. 空格不匹配任意文件, 可作为分隔符, 可用反斜杠转义.

  2. 空行或者以 # 开头的行都会被 Git 忽略. 一般空行用于可读性的分隔, # 一般作注释用.

  3. 正则表达式: 可以使用标准的 glob 模式匹配(更准确地, 拓展的 glob). 所谓的 glob 模式是指 shell 所使用的简化了的正则表达式. 介绍 glob 的博文

  4. 目录与文件的区分: 由于 glob 模式的规则限制(也是 POSIX 标准), 表示目录的 / 无法用通配符匹配, 需要显式地写出匹配:

    • / 开头表示根目录下的文件或目录;
    • / 结束的模式只匹配文件夹以及在该文件夹路径下的内容, 但是不匹配该文件;
    • 如果一个模式不包含斜杠, 则它匹配相对于当前 .gitignore 文件路径的内容, 如果该模式不在 .gitignore 文件中, 则相对于项目根目录.
  5. Git 对于 .gitignore 是按行从上到下进行规则匹配的, 意味着如果前面的规则匹配的范围更大, 则后面的规则将不会生效.

  6. 以上规则仅适用于未被缓存或加入版本控制的文件

强制 ignored 文件重新被追踪

-f (--force) 选项

1
2
3
4
5
6
$ cat .gitignore
*.log

$ git add -f debug.log

$ git commit -m "Force adding debug.log"

对 ignored 文件进行存档

默认 stash 存档是不会对 untracked 以及 ignored 文件进行存档的. 但是可以通过增加参数的形式实现强制存档.

.gitignore 文件进行 debug

当有多个 .gitignore 匹配规则或者多个 .gitignore 文件时, 对某个文件的匹配情况进行 debug 比较困难. 可以使用如下命令找到对某一文件究竟是哪个 .gitignore 下的哪个匹配规则起到了作用.

1
2
$ git check-ignore -v debug.log
.gitignore:3:*.log debug.log

输出:

1
<file containing the pattern> : <line number of the pattern> : <pattern>    <file name>

对已经 commit 的文件进行过滤

通过 git rm--cached 选项将以及 commit 的文件从代码库中删除, 然后提交新的 .gitignore .

1
2
3
4
5
6
$ echo debug.log >> .gitignore

$ git rm --cached debug.log
rm 'debug.log'

$ git commit -m "Start ignoring debug.log"

也可以通过省略 --cached 选项同时删除代码区以及工作区的 ignored 文件.

如果需要忽略的文件已经上传到远端共享代码库. 需要把删除后的 commit, push 到远端即可实现远端的删除.

.gitignore 的规则示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#               表示此为注释,将被Git忽略
*.a 表示忽略所有 .a 结尾的文件
!lib.a 表示但lib.a除外
/TODO 表示仅仅忽略项目根目录下的 TODO 文件, 不包括 subdir/TODO
build/ 表示忽略 build/目录下的所有文件, 过滤整个build文件夹;
doc/*.txt 表示会忽略doc/notes.txt但不包括 doc/server/arch.txt

bin/: 表示忽略当前路径下的bin文件夹, 该文件夹下的所有内容都会被忽略, 不忽略 bin 文件.
/bin: 表示忽略根目录下的bin文件
fd1/* 忽略目录 fd1 下的全部内容;注意, 不管是根目录下的 /fd1/ 目录, 还是某个子目录 /child/fd1/ 目录, 都会被忽略;
/fd1/* 忽略根目录下的 /fd1/ 目录的全部内容;
/*.c: 表示忽略cat.c, 不忽略 build/cat.c
debug/*.obj: 表示忽略debug/io.obj, 不忽略 debug/common/io.obj和tools/debug/io.obj
**/foo: 表示忽略/foo,a/foo,a/b/foo等
a/**/b: 表示忽略a/b, a/x/b,a/x/y/b等
!/bin/run.sh 表示不忽略bin目录下的run.sh文件
*.log: 表示忽略所有 .log 文件
config.php: 表示忽略当前路径的 config.php 文件

/mtk/ 表示过滤整个文件夹
*.zip 表示过滤所有.zip文件
/mtk/do.c 表示过滤某个具体文件

/mtk/*
!/mtk/one.txt 只需要管理/mtk/目录中的one.txt文件, 这个目录中的其他文件都不需要管理.注意/mtk/*不能写为/mtk/, 否则父目录被前面的规则排除掉了, one.txt文件虽然加了!过滤规则, 也不会生效!

一些常用的 .gitignore 模板

github 收集了很多开发环境下的 gitignore 模板. 可以参考代码库.

例如 C++ 的参考模板如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# Prerequisites
*.d

# Compiled Object files
*.slo
*.lo
*.o
*.obj

# Precompiled Headers
*.gch
*.pch

# Compiled Dynamic libraries
*.so
*.dylib
*.dll

# Fortran module files
*.mod
*.smod

# Compiled Static libraries
*.lai
*.la
*.a
*.lib

# Executables
*.exe
*.out
*.app

本文参考链接:

.gitignore file - ignoring files in Git | Atlassian Git Tutorial

https://www.cnblogs.com/kevingrace/p/5690241.html

作者

cx

发布于

2022-06-21

更新于

2022-07-16

许可协议