忽略根目录以外的 .gitignore 文件。

3

我的实际问题

我希望只有根目录下的.gitignore文件忽略文件,即子目录中的.gitignore文件不应该忽略文件。

明确一下

我不想忽略其他的.gitignore文件。 我希望它们被提交到git中,但是我不希望它们忽略其他文件。

具体用例

假设我想将一个样板项目结构提交到git。 假设项目结构如下:

project-root/
│
├── boilerplate/
│   ├──directory/
│   ├──some-other-directory/
│   ├──.env
└── └──.gitignore // Has a line ".env" which will ignore the .env file in this directory 
│
├── boilerplate2/
│   ├──directory/
│   ├──some-other-directory/
│   ├──.env
└── └──.gitignore
│
└── .gitignore // The .gitignore in root 

现在,在boilerplate目录中的.gitignore文件将忽略.env,而我不想要这个。我该如何阻止嵌套的.gitignore文件生效? 我尝试了什么? 我在主.gitignore文件中尝试使用否定(!)运算符。对于上面的示例结构,它等同于!boilerplate/.env。根目录下的.gitignore文件无法覆盖指定目录中的.gitignore文件。为什么会这样呢?有没有解决方法? 编辑: VonC建议使用脚本自动化处理,但这不是问题所在。问题是,如果可能的话,如何仅使用.gitignore来解决这个问题。
1个回答

1
现在,在boilerplate目录中的.gitignore文件将会忽略.env,但我不想要这样。
实际上并不会这样。如果boilerplate/.env已经被添加(git add --force)并提交了,那么对该特定的.env文件的任何更改仍然会被检测到,而不是被忽略。
OP补充道:
但是当我运行git status时,由于boilerplate/.gitignore(也没有被提交),git会忽略boilerplate/.env。
那么,是的,它会忽略所有的.env文件,除非它们本身就是版本。
根目录下的 .gitignore 对指定目录中的 .gitignore 文件没有任何影响,它不能覆盖指定目录中的 .gitignore 文件。这遵循了 .gitignore 的优先规则
从路径所在的同级目录或任何父级目录(直到工作树的顶层)读取模式,高级别文件中的模式被低级别文件中的模式覆盖,直到包含该文件的目录。
在你的情况下,我会做以下几点:
  • 保留 .env 规则
  • 仅将具有默认初始值的 .env.tpl 模板文件进行版本控制
  • 添加一个 .gitattributes 文件,其中包含一个 smudge 内容过滤驱动程序 脚本声明,用于处理 *.tpl 文件

该smudge脚本(例如“script_tpl”,也可以进行版本控制)将是一个bash脚本(即使在Windows上也可以工作,因为Git for Windows附带有 bash.exe):

#!/bin/bash

file="${f%.tpl}" # ex: .env.tpl => .env
if [[ ! "${file}" ]]; then cp "${f}" "${file}"; fi

我会在本地克隆的存储库中添加一个名为“senv”的脚本,以便任何合作者都可以执行它,从而自动注册内容过滤器驱动程序。 它将包括以下内容:
#!/bin/bash
DIR="$( cd "$( dirname "$(readlink -f "${BASH_SOURCE[0]}")" )" && pwd )"
# assuming the smudge script is at the root of the repository
which script_tpl || export PATH=${PATH}:${DIR} 
git config --global filter.tpl.smudge 'script_tpl'

这样,每当你切换分支时,污点脚本会检查是否存在 .env 文件,如果不存在,则会创建一个(该文件将被各种 .gitignore 文件忽略)。

既没有提交.env也没有提交boilerplate/。只有根目录下的.gitignore被提交了。但是当我执行git status时,由于boilerplate/.gitignore(也未提交),git会忽略boilerplate/.env - Shivang Kakkar
@StarkProgrammer 好的,我已经更新了我的答案,提出了一种替代方案。 - VonC
如果我理解正确,你首先要做的是将.env重命名为.env.tpl作为模板文件。然后,你提供了一个脚本,如果不存在.env.tpl则创建一个.env.tpl。如果我重命名文件,整个过程就不需要了,因为.gitignore无论如何都不会忽略.env.tpl。然后我可以将文件重命名为.env。但这违背了问题的目的,因为它应该与“如何使用.gitignore”相关,而不是与“bash脚本”相关。 - Shivang Kakkar
@StarkProgrammer 要创建 .env 文件,不要创建 .env.tpl 文件。 - VonC

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接