我正在将我的Mercurial存储库转换为Git。部分文件系统如下所示:
|-- .gitignore
|-- .hgignore
`-- var
|-- .dummy
|-- asdf
`-- log
|-- .dummy
`-- asdf
我的.hgignore文件使用正则表达式。我的.hgignore文件的一部分如下:
^var/(?!\log|.dummy)
^var/log/(?!\.dummy)
我想跟踪.dummy
个文件,但不跟踪asdf
个文件。 hg status
返回:
? var/.dummy
? var/log/.dummy
如何在.gitignore中获得相同的效果?我尝试过以下方法:
/var/**/*
!/var/.dummy
!/var/log/.dummy
但是这不会忽视var/asdf
。如何跟踪var/.dummy
和var/log/.dummy
并忽略var/asdf
和var/log/asdf
?
答案 0 :(得分:10)
如果您只使用.dummy
文件作为占位符来确保在进行干净检查时始终获得这些特定(几乎为空)的目录,那么您应该只排除/var
和使用git add -f var/.dummy var/log/.dummy
开始显式跟踪占位符文件。有效的结果是您将忽略除明确跟踪的.dummy
文件之外的所有内容。
另一方面,如果您计划扩展几乎空目录的层次结构,而不仅仅是var/log
,那么您可以使用一些解释。
规则在gitignore(5)中有所描述,但有时很难理解所有规则以及它们如何相互作用。重要的是,最后一条规则获胜,而后来的规则只有在它们所依据的目录尚未被完全忽略时才有效。这意味着如果您忽略了目录,则必须先取消它们的内容,然后才能取消内容的一些内容(同时重新忽略其余内容)。
如果您想自动忽略.dummy
下var
个文件以外的所有内容,那么最简单的方法是将.gitignore
文件放在var
目录中,而不是在顶层做它。我在另一个SO answer中描述了这个解决方案。
# var/.gitignore
*
!/.gitignore
!.dummy
!*/
var
)。git add -f
开始跟踪此.gitignore
文件,则可以将其删除。).dummy
)为根的层次结构中任何深度的var
个文件。var
)
如果没有此规则,第一条规则将忽略子目录,Git甚至不会打开它们来查找.dummy
文件。最后两个模式是“递归的”,因为它们没有非尾部斜杠(意味着*
除了其他字符外还会匹配斜杠)。尾部斜杠使模式仅匹配目录。前导和嵌入式斜杠有效地将模式锚定到.gitignore
文件的位置(或者来自其他排除文件的模式的存储库的根)。我们的想法是,普通*.o
应该匹配任何地方,但dir/*.o
应仅匹配dir
下的项目(我们可以/*.o
使用dir/.gitignore
来实现{{1} }})。
如果您无法容忍var/.gitinore
文件,那么您仍然可以按照自己的要求进行操作,但无法在.dummy
下的任何位置自动“取消”var
个新# .gitignore at root of repository
/var/*
!/var/.dummy
!/var/log/
/var/log/*
!/var/log/.dummy
文件排除模式。
var
.gitignore
文件的兄弟var/.dummy
目录下的所有内容。var/log
。var/log
。var/log/.dummy
。.dummy
。模式是:unignore一个有趣的目录(第一次跳过这个,因为默认情况下一切都是“unignored”),忽略目录中的内容,取消其中的log
文件。对层次结构的每个较深部分重复该模式。
您可以将*
替换为var
,使其适用于var/cache/.dummy
下的任何目录,但它不会自动适用于更深层的目录(例如,它适用于{ {1}},但不适用于var/log/ssh/.dummy
)。这是因为我们使用非尾部斜杠并锚定模式。要手动使其工作,您必须重复该模式以为更深层部分生成更多排除规则(unignore有趣的目录,忽略dir的内容,unignore文件)。
答案 1 :(得分:2)
您无需使用正则表达式排除.dummy
。只需忽略所有内容,然后手动添加所有.dummy
。
忽略仅影响状态命令结果。