告诉git忽略符号链接

79
这个问题在类似形式下出现过这里这里,但它们似乎与我所寻找的不符。
我正在使用StaticMatic制作一个项目,这是一个Ruby静态站点生成器。基本上,它只是一个包含Haml模板、Sass和CoffeeScript的src/目录。StaticMatic提供了一个开发服务器来编译这些内容成为一个静态站点,以及一个生成静态站点到build/目录的命令。
我的修改是允许添加src/_modules/foo/目录,其中可能包含src/_modules/foo/bar.haml文件。运行服务器或构建站点时,会在src/bar.haml创建一个指向foo/中文件的符号链接。
到目前为止还不错。(冲突已经处理好了等等)
之所以要将_modules/中的单独目录分开,是因为它们可以被作为git子模块跟踪并且可以独立地被其他团队检出。本质上,这允许多个团队在一个静态站点中工作不同的页面(实际上是JS应用程序),而不需要复制主要的布局等内容。
问题在于git希望将这些符号链接看作文件。例如,git status会显示:
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be commited)
#
#       src/_modules/bar/foo.haml
#       src/foo.haml

...我只想显示src/_modules/bar/foo.haml,并忽略src/foo.haml

一种方法是让我的链接生成代码将链接附加到.gitignore中,但通过编程方式操作.gitignore可能会出现错误。 (也许这个担忧是不合理的?)

我理想的解决方案是:

[filetype = link]

...在.gitignore文件中忽略一个特定的文件夹。据我所知,这似乎是不可能的,难道它可以做到吗?


1
问题在于git希望将这些符号链接视为文件。事实并非如此,它只是想将它们作为符号链接进行跟踪。我不确定您为什么不想跟踪符号链接,因为它们似乎是站点结构的重要组成部分。 - CB Bailey
2
啊,谢谢你的澄清。但是,符号链接并不是任何东西的重要部分,它们只是暂时的粘合剂,让开发服务器和构建过程将它们视为属于主目录/src的一部分。每次启动服务器或创建构建时,符号链接都会被重新创建。 - user225643
此外,我不想要它们的原因是因为你可能只想在网站的某个部分工作,而不关心模块是否已被签出或更新。 - user225643
可能是Git:忽略符号链接的重复问题。 - Phrogz
8个回答

35

这似乎是一个更好的想法

find . -type l | sed -e s'/^\.\///g' >> .gitignore

Find命令会为所有文件添加"./"前缀。除非您将其删除,否则gitignore无法对它们进行操作。一旦您去掉开头的".\",它就可以像魔术般工作。


18
不需要使用sed。用“*”替换“.”:find * -type l >> .gitignore - Nick Petrovic
4
“find .”命令会在每个搜索结果前面加上“./”,但“find *”则不会。我认为这就是@nickptrvc所说的。我不确定其他内容是否保持不变,但乍一看好像是这样的。 - Mark
3
使用 find . -type l -printf '%P\n' 怎么样?不需要用到 sed,所以对于大型仓库来说速度应该更快。 - Doron Behar
3
我只想要当前目录下的链接,因此我执行了 find * -maxdepth 1 -type l >> .gitignore。我想其他网上的人也会觉得这很有用。 - Nathan majicvr.com
这将使git忽略仓库中所有具有相同名称的文件。 - a113nw
显示剩余4条评论

23

根据您使用的git版本,它应该遵循符号链接。有一个配置设置core.symlinks,可能设置为false,因此不允许git将其作为目录进行跟踪(假设git >= 1.6)。将符号链接添加到.gitignore文件或手动添加这些链接似乎是完全合理的。您还可以执行类似于find . -type l >> .gitignore的操作。


7
请注意,git config core.symlinks false(供快速阅读的人)。但请注意,这会将符号链接作为文本文件提交,其目标可能在其他用户的系统上无效。 - JellicleCat

18

我们遇到了类似的问题,需要忽略符号链接目录或实际目录,但不是同名子目录或以相同字母开头的文件。例如:

  • 忽略 - (符号链接) ./media
  • 忽略 - (目录) ./media
  • 不要忽略 - ./something/media
  • 不要忽略 - ./media.bak
  • 不要忽略 - ./media-somethingelse

我最终在.gitignore中使用了以下内容:

media
!*/media

这看起来有点奇怪,但基本上意思是(第一行)忽略所有的“media”,但是(第二行)不要忽略任何不在根目录下的“media”。这种方法需要一定的特定性(不忽略子目录中的内容),但应该很容易调整/扩展。


13
你可以直接执行/media命令。在此,绝对路径是指包含.gitignore文件的目录。 - Zenexer

6

我的另一个问题的答案是相关的。请点击链接查看

该方法仅添加未跟踪的符号链接,因此可以重复使用而不会添加重复条目、子模块中或已被忽略的符号链接或有意跟踪的符号链接。

for f in $(git status --porcelain | grep '^??' | sed 's/^?? //'); do
    test -L "$f" && echo $f >> .gitignore;
    test -d "$f" && echo $f\* >> .gitignore;
done

谢谢,这很好。我做了类似的事情。如果文件名中有空格,这个变体将用于列出未跟踪的符号链接:git status --porcelain | grep '^??' | sed 's/^?? //' | while read A; do [ -L "$A" ] && echo "$A"; done - Sam Watkins

3

我使用了最适合我的解决方案-命名协议。

对于文件 在我的解决方案中,每个指向文件的符号链接都有一个前缀,例如“bla.outsidemodule.ts”。 在.gitignore文件中,只需要:

**/*.outsidemodule.*

有文件夹 此外,在解决方案的根目录下,我有一个名为“platform”的文件夹,其中包含其他部分解决方案所需的公共库/模块。结构如下:

 - ./platform              <- sources
 - ./client/src/platform   <- symlink to ./platform
 - ./server/src/platform   <- symlink to ./platform
 - ./exchange/src/platform <- symlink to ./platform
 - ./service/src/platform  <- symlink to ./platform

在 .gitignore 文件中只需要添加:

**/platform <- exclude all "platform" folders
!./platform <- do not exclude folder "platform" if it's on a root 

3
如果您真的希望忽略一个符号链接或文件名,但不忽略目录名,您可以在 .gitignore 文件中添加以下内容:
/media
!/media/

按照 @Chris_Rasys 的说法,这将会:

  • 忽略 - (符号链接) ./media
  • 忽略 - (文件) ./media
  • 不忽略 - (目录) ./media
  • 不忽略 - ./something/media
  • 不忽略 - ./media.bak
  • 不忽略 - ./media-somethingelse

2

虽然我的解决方案可能看起来有点傻,但我宁愿这样做,也不想每次添加新文件时都更新.gitignore文件。

我只需以默认名称(例如“链接到xxx”)留下链接,然后在我的.gitignore文件中添加以下行:

link to *

然后,您只需确保不将任何其他文件/文件夹命名为以“link to”开头的名称,就可以解决问题。


1
但是如果我们要将所有符号链接都标记为“link\ to\ original_name”,那么我们就需要重新制作整个项目,不需要,谢谢! - pythonian29033
3
这肯定是一种“跳出传统思维”的方式。我欣赏这种灵感。 - kkahl
“重新做整个项目”?听起来更像是一个内嵌的bash命令,写起来比这条评论需要花费更少的时间。 - a113nw

0

我不保留可执行文件和符号链接在我的存储库中...所以当我执行"git status"时,我希望也省略它们。

如果你和我一样,想要忽略符号链接、目录和可执行文件(类似于$NAG_HOME/libexec中的某些文件),你可以将这些文件添加到.gitignore中,如下所示:

   file * | egrep 'ELF|symbolic|directory' | awk -F\: '{ print $1 }' >> .gitignore

   echo ".gitignore" >> .gitignore

然后,当您执行git status时,如果您尚未将它们添加到存储库中,则不会返回这些文件的列表。


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