如何在 .gitignore 中获得 .hgignore 的正则表达式 ^var/(?!\log|.dummy) 和 ^var/log/(?!\.dummy) 的等效项?
我正在将 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 ?
I am converting my Mercurial repository to Git. Part of the file system looks like this:
|-- .gitignore
|-- .hgignore
`-- var
|-- .dummy
|-- asdf
`-- log
|-- .dummy
`-- asdf
My .hgignore file uses regular expressions. Part of my .hgignore file is as follows:
^var/(?!\log|.dummy)
^var/log/(?!\.dummy)
I want to track the .dummy
files but not the asdf
files. hg status
returns:
? var/.dummy
? var/log/.dummy
How can I get the same effect in .gitignore? I have tried the following:
/var/**/*
!/var/.dummy
!/var/log/.dummy
But this will not ignore var/asdf
as desired. How can I track var/.dummy
and var/log/.dummy
and ignore var/asdf
and var/log/asdf
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您仅使用
.dummy
文件作为占位符,以确保在进行干净签出时始终获得那些特定的(几乎为空)目录,那么您可能应该排除/var
并使用 git add -f var/.dummy var/log/.dummy 开始显式跟踪占位符文件。有效的结果是您将忽略除您明确跟踪的.dummy
文件之外的所有内容。另一方面,如果您计划将几乎空的目录的层次结构扩展到
var/log
之外,那么您可能可以利用一些解释。这些规则在gitignore(5)中描述,但有时它很难理解所有规则以及它们如何相互作用。重要的是最后一条规则获胜,并且后面的规则只有在它们所作用的目录尚未被完全忽略时才有效。这意味着,如果您忽略了目录,则必须先取消忽略它们,然后才能取消忽略其中的一些内容(同时重新忽略其余的内容)。
如果您想自动忽略
var
下除.dummy
文件之外的所有内容,那么最简单的方法是将一个.gitignore
文件放入您的var
目录而不是在顶层执行。我在另一个 所以回答。var
)。var
) 为根的层次结构中任何深度的.dummy
文件。var
)。如果没有这条规则,第一条规则将忽略子目录,Git 甚至永远不会打开它们来查找
.dummy
文件。最后两个模式是“递归”的,因为它们没有非尾部斜杠(这意味着
*
除了匹配其他字符之外还将匹配斜杠)。尾部斜杠使模式仅匹配目录。前导斜杠和嵌入斜杠有效地将模式锚定到 .gitignore 文件的位置(或者来自其他排除文件的模式的存储库的根目录)。这个想法是,一个普通的*.o
应该匹配任何地方,但是dir/*.o
应该只匹配直接在dir
下的项目(我们可以在dir/.gitignore
中使用/*.o
来实现后一种效果)。如果您不能容忍
var/.gitinore
文件,那么您仍然可以执行您所要求的操作,但您不能自动“忽略”.dummy
下任何位置的新.dummy
文件。 code>var 而不编辑排除模式。var
目录下与此.gitignore
文件同级的所有内容。var/.dummy
。var/log
。var/log
中的所有内容。var/log/.dummy
。模式是:取消忽略一个有趣的目录(第一次跳过这个,因为默认情况下所有内容都是“忽略”的),忽略目录中的内容,取消忽略其中的 .dummy 文件。对层次结构的每个较深层部分重复该模式。
您可以将
log
替换为*
,使其适用于直接位于var
下的任何目录,但它不会自动适用于更深的目录(例如,它适用于var/cache/.dummy
,但不适用于var/log/ssh/.dummy
)。这是因为我们使用非尾随斜杠并锚定模式。要手动使其工作,您必须重复该模式以为更深的部分生成更多排除规则(忽略感兴趣的目录、忽略目录的内容、忽略文件)。If you are only using the
.dummy
files as placeholders to make sure that you always get those particular (nearly empty) directories when you make a clean checkout, then you should probably just exclude/var
and usegit add -f var/.dummy var/log/.dummy
to start explicitly tracking the placeholder files. The effective result is that you will ignore everything except the.dummy
files that you explicitly tracked.On the other hand, if you plan on expanding the hierarchy of nearly empty directories beyond just
var/log
, then you might be able to make use of a bit of explanation.The rules are described in gitignore(5), but sometimes it is difficult to make sense of all the rules and how they interact. The important part is that the last rule wins, and that later rules can only be effective if the directories they act on are not already wholly ignored. This means that you if you have ignored directories, you have to unignore them before you can unignore a bit of their contents (while re-ignoring the rest of their contents).
If you want to automatically ignore everything except
.dummy
files undervar
, then the simplest way of doing this involves putting a.gitignore
file in yourvar
directory instead of doing it at the top level. I described this solution in another SO answer.var
).git add -f
to start tracking this.gitignore
file)..dummy
files at any depth in the hierarchy rooted at this directory (var
).var
).Without this rule, the first rule will ignore the subdirectories and Git would never even open them to look for
.dummy
files.The last two patterns are “recursive” because they do not have a non-trailing slash (meaning that
*
will match slashes in addition to other characters). A trailing slash makes the pattern match only directories. Leading and embedded slashes effectively anchor the pattern to the location of the.gitignore
file (or the root of the repository for patterns from other exclude files). The idea is that a plain*.o
should match anywhere, butdir/*.o
should only match items directly underdir
(and we can use/*.o
for this latter effect indir/.gitignore
).If you can not tolerate a
var/.gitinore
file, then you can still do what you asked, but you can not automatically “unignore” new.dummy
files anywhere undervar
without editing the exclude patterns.var
directory that is a sibling of this.gitignore
file.var/.dummy
.var/log
.var/log
.var/log/.dummy
.The pattern is: unignore an interesting directory (skip this the first time, since everything is “unignored” by default), ignore what is in the directory, unignore the
.dummy
file in it. Repeat the pattern for each deeper part of the hierarchy.You can replace
log
with*
to make it work for any directory directly undervar
, but it will not automatically work for directories that are deeper (e.g. it would work forvar/cache/.dummy
, but not forvar/log/ssh/.dummy
). This is because we are using non-trailing slashes and anchor the patterns. To manually make it work, you have to repeat the pattern to generate more exclusion rules for the deeper parts (unignore interesting dir, ignore contents of dir, unignore file).您不需要使用正则表达式排除
.dummy
。只需忽略所有内容并手动添加所有.dummy
即可。忽略仅影响状态命令结果。
You don't need to exclude
.dummy
with regex. Just ignore everything and manually add then all your.dummy
.Ignore affects only on the status command result.