使用Git跟踪我的基本配置文件时,我在编写.gitignore文件时遇到了问题。
我的目标是在我的存储库中包含两件事:
~/
中的所有dotfiles,这是我的gitroot。~/.vim/bundle
到目前为止,我尝试了以下方法,但无济于事。
的.gitignore:
# Ignore everything
*
# Include top-level dot files.
!/.*
# Include vim plugins
!/.vim/bundle/*
这只会在我的gitroot中使用dotfiles。
注意。
我的gitroot是我的用户目录~/
。
更新
在以下表格中,~/.vim
文件夹 上演:
# Ignore everything
*
# Include top-level dot files.
!/.*
# Include vim plugins
!/.vim
所以,我猜我应该以某种方式表达路径名/.vim/bundle
。
答案 0 :(得分:3)
你正在遇到一个破坏你的用例的优化:一旦Git决定不查看目录,它就永远不会在目录中找到它将添加的文件。要修复它,您至少还需要一个规则:
!/.vim/bundle/
您可以使用其他规则来阻止所有优化:
!*/
这也应该使问题消失(以更深入的搜索为代价,导致很多缓慢)。
你有一个良好的开端,但是你遇到了一个有问题的优化(我认为Git人员试图修复)。我们还必须假设当前在索引(也就是临时区域)中的内容,因为索引内容会影响Git扫描目录的方式。让我们假设你的索引真的是空的,因为它会在git init
新的存储库之后。这样,由于没有现有的索引条目,它们不会影响Git的正常目录扫描过程。
我们假设您的工作树包含名为README
和.profile
的文件,以及目录d/
和.vim/
。您的.gitignore
有三条规则。第一个是正规则(“忽略”),第二个和第三个是否定规则(“不要忽略”)。规则本身减去!
,是:
*
/.*
/.vim/bundle/*
现在,当Git正在使用README
时,首先检查匹配的*
,然后检查不匹配的/.*
,然后检查/.vim/bundle/*
也不匹配。最后一个匹配规则生效:*
表示“忽略”,因此README
将被忽略。另一方面,文件.profile
是前两个规则,因此第二个规则适用,它会显示!
,因此.profile
未跟踪但未被忽略:git status
将抱怨它,git add .
会将它添加到索引中。
现在让我们考虑如何处理d/
和.vim/
。这些是目录,而不是文件:Git不会保存它们,但它可能会也可能不会保存 中的文件。为此,它必须阅读并检查其中的所有文件名。这是非常昂贵的,所以Git将首先尝试完全跳过目录。这是我提到的有问题的优化。
无论如何,d/
匹配第一条规则但不匹配其他两条规则。这意味着Git可以完全跳过阅读d/
。 git status
不会抱怨它,git add
也不会扫描它。
到目前为止,我们都很好。 .vim/
匹配第二条规则(但不是第三条规则),因此Git会查看.vim
内部。
假设.vim/
包含.netrwhist
,after/
,bundle/
,以及其他一些目录。 .netrwhist
匹配*
,与/.*
不匹配,与/.vim/bundle/*
不匹配,因此适用*
匹配并被忽略。 after/
目录与*
匹配,与/.*
不匹配,与/.vim/bundle/*
不匹配,因此未读。
现在我们遇到了问题:.vim/bundle/
是一个目录。 Git根据您的.gitignore
指令检查此路径名。 bundle/
匹配*
。 .vim/bundle
与/.*
不匹配,因为这意味着顶层的文件; .vim/bundle/
是一个目录,不在顶级。该路径也与第三个指令/.vim/bundle/*
不匹配,后者要求这是 .vim/bundle/
中的文件或目录。所以唯一匹配的指令是第一个,.vim/bundle
未读就像d/
那样。
这意味着Git永远不会在 .vim/bundle/
中找到任何文件或目录。它永远不会检查任何文件(如果有的话),它从不扫描子目录中的更多文件。您需要强制Git查看.vim/bundle/
。
如果索引中的某个文件的路径名为.vim/bundle/a/b
,则Git必须扫描目录.vim/bundle/a
。所以放在那里的任何 new 文件都会出现!我不确定Git是否曾在这种情况下跳过.vim/bundle/
本身(理论上它可以,但我认为它在实践中没有)。在索引中有文件路径后,该文件将被跟踪,并且它在任何.gitignore
中的存在变得无关紧要。
但是,请注意,索引现在中的文件不一定位于索引明天中,如果您删除它们或者如果您查看其他提交的位置这些文件不存在。整件事情有点棘手。
答案 1 :(得分:2)
前导斜杠表示相对于gitroot的绝对路径;删除它以选择所有的dotfiles。
# Ignore everything
*
# Include all dot files.
!.*
# Include vim plugins
!/.vim/bundle/*
Here is一个方便而简洁的参考示例。
您需要暂存然后提交.gitignore
才能使更改生效。很高兴你可以反复git commit --amend
进行进一步的更改,以保持历史清洁,直到你有你想要的为止。
作为一个模糊相关的旁边,我经常看到有人试图将“项目中任意位置folder
的文件夹”与/folder
匹配,其中**/folder
应该是vue/dist/vue.esm
}。
答案 2 :(得分:0)
我受到this answer的启发,编写了以下适当的.gitignore
文件。 :)
# We use a whitelisting approach to track certain configuration files.
# Apparently, this needs to be done recursively because git can't see past a directory that is not
# included. Hence, if we want to include a subdirectory, we first need to include its upper
# directory, by the whitelisting procedure as shown below.
# Exclude all files and non-hidden directories.
/*
# Include all dotfiles.
!.*
# Exclude all hidden directories.
.*/
# Include the upper directory.
!/.vim
# Exclude all files and non-hidden directories.
/.vim/*
# Include the vim plugins.
!/.vim/bundle