如何在.gitignore中获得等效的.hgignore的正则表达式^ var /(?!\ log | .dummy)和^ var/log /(?!\.dummy)?

sal*_*ane 4 git mercurial gitignore hgignore

我正在将我的Mercurial存储库转换为Git.部分文件系统如下所示:

|-- .gitignore
|-- .hgignore
`-- var
    |-- .dummy
    |-- asdf
    `-- log
        |-- .dummy
        `-- asdf
Run Code Online (Sandbox Code Playgroud)

我的.hgignore文件使用正则表达式.我的.hgignore文件的一部分如下:

^var/(?!\log|.dummy)
^var/log/(?!\.dummy)
Run Code Online (Sandbox Code Playgroud)

我想跟踪.dummy文件而不是asdf文件.hg status收益:

? var/.dummy
? var/log/.dummy
Run Code Online (Sandbox Code Playgroud)

如何在.gitignore中获得相同的效果?我尝试过以下方法:

/var/**/*
!/var/.dummy
!/var/log/.dummy
Run Code Online (Sandbox Code Playgroud)

但这不会忽视var/asdf所希望的.如何跟踪var/.dummyvar/log/.dummy而忽略var/asdfvar/log/asdf

Chr*_*sen 10

如果您仅使用.dummy文件作为占位符来确保在进行干净检出时始终获得这些特定(几乎为空)的目录,那么您应该只是排除/var并使用git add -f var/.dummy var/log/.dummy开始显式跟踪占位符文件.有效的结果是您将忽略除.dummy明确跟踪的文件之外的所有内容.

另一方面,如果您计划扩展几乎空目录的层次结构var/log,那么您可以使用一些解释.

这些规则在gitignore(5)中有所描述,但有时很难理解所有规则以及它们如何相互作用.重要的是,最后一条规则获胜,而后来的规则只有在它们所依据的目录尚未被完全忽略时才有效.这意味着,如果您忽略了目录,则必须先取消它们的内容,然后才能取消内容的一些内容(同时重新忽略其余内容).


如果你想自动忽略除了.dummy文件之外的所有内容var,那么最简单的方法是将.gitignore文件放在你的var目录中,而不是在顶层执行.我描述了这种解决方案的另一个SO回答.

# var/.gitignore
*
!/.gitignore
!.dummy
!*/
Run Code Online (Sandbox Code Playgroud)
  1. 忽略此目录中的所有内容(var).
  2. 但是,不要忽略这一个.gitignore文件(如果你愿意git add -f开始跟踪这个.gitignore文件,你可以把它留下来).
  3. 此外,不要忽略.dummy以此目录(var)为根的层次结构中任何深度的文件.
  4. 另外,不要忽略此目录下任何深度的任何目录(var).
    没有这个规则,第一个规则将忽略子目录,Git甚至不会打开它们来查找.dummy文件.

最后两个模式是"递归的",因为它们没有非尾部斜杠(这意味着*除了其他字符之外还会匹配斜杠).尾部斜杠使模式仅匹配目录.前导和嵌入式斜杠有效地将模式锚定到.gitignore文件的位置(或者来自其他排除文件的模式的存储库的根).我们的想法是普通*.o应该匹配任何地方,但dir/*.o应该只匹配直接下面的项目dir(我们可以/*.o用于后一种效果dir/.gitignore).


如果您无法容忍var/.gitinore文件,那么您仍然可以按照您的要求进行操作,但.dummyvar不编辑排除模式的情况下,您无法在任何地方自动"取消签名"新文件.

# .gitignore at root of repository
/var/*
!/var/.dummy

!/var/log/
/var/log/*
!/var/log/.dummy
Run Code Online (Sandbox Code Playgroud)
  1. 忽略var.gitignore文件的兄弟目录下的所有内容.
  2. 但是,不要忽视var/.dummy.
  3. 另外,不要忽略该目录var/log.
  4. 但是,直接忽略一切var/log.
  5. 但是,不要忽视var/log/.dummy.

模式是:unignore一个有趣的目录(第一次跳过这个,因为默认情况下一切都是"unignored"),忽略目录中的内容,取消其中的.dummy文件.对层次结构的每个较深部分重复该模式.

您可以替换log使用*,使其成为任何目录工作的直属var,但它不会自动为更深层次的目录(例如,它会工作的工作var/cache/.dummy,但不适合var/log/ssh/.dummy).这是因为我们使用非尾部斜杠并锚定模式.要手动使其工作,您必须重复该模式以为更深的部分生成更多排除规则(unignore有趣的目录,忽略dir的内容,unignore文件).