如何让Git遵循符号链接?

Mat*_*att 198 git symlink

我最好是一个shell脚本用副本替换符号链接,还是有另一种方式告诉Git遵循符号链接?

PS:我知道它不是很安全,但我只想在一些特定情况下这样做.

小智 136

我做了什么来添加到符号链接中的文件到Git(我没有使用符号链接但是):

sudo mount --bind SOURCEDIRECTORY TARGETDIRECTORY
Run Code Online (Sandbox Code Playgroud)

在Git托管目录中执行此命令.TARGETDIRECTORY必须在SOURCEDIRECTORY安装到它之前创建.

它适用于Linux,但不适用于OS X!这个技巧也帮助了Subversion.我使用它来包含来自Dropbox帐户的文件,其中webdesigner执行他/她的东西.

  • @Adobe:将它放在/ etc/fstab中,如下所示:/ sourcedir/targetdir none bind (15认同)
  • 要撤消此绑定,请使用`umount [mydir]`.(+1为您的精彩提示,@ user252400) (11认同)
  • 这仅适用于会话期间.使它"永恒"的最佳方法是什么? (9认同)
  • sshfs可以在不需要sudo的情况下实现这种技巧. (8认同)
  • 如果不需要sudo,这将是一个非常好的方法. (7认同)
  • 对于OSX,请使用http://bindfs.org/(您可以使用`brew install bindfs`获取它,请务必按照屏幕上显示的说明正确设置osxfuse). (5认同)
  • @sylvainulg:甜蜜的把戏!你仍然需要sudo但只能安装sshfs [apt-get install sshfs].然后一个简单的[sshfs用户名@ localhost:/ etc /文件夹./target_folder]为git做了工作.Brillant;).这里的最佳解决方案! (2认同)
  • 这个和硬链接之间有什么区别? (2认同)

spi*_*ier 71

为什么不以相反的方式创建符号链接?意思是代替从Git存储库到应用程序目录的链接,只需链接另一种方式.

例如,假设我正在设置一个~/application需要配置文件的应用程序config.conf:

  • 我添加config.conf到我的Git存储库,例如,at ~/repos/application/config.conf.
  • 然后我~/application通过运行 创建一个符号链接ln -s ~/repos/application/config.conf.

这种方法可能并不总是有效,但到目前为止它对我来说效果很好.

  • 在我的情况下,我想要一个从一个git repo到另一个git仓库的链接,所以我可以在任一位置编辑文件并提交回各自的遥控器.在Windows 7上,一个联结("mklink/j")就可以了. (12认同)
  • 似乎是唯一的方式,它并没有那么糟糕...我认为你的方式非常优雅.git跟踪内容,而不是文件.因此,将所有内容保持在一起并从那里进行符号链接到其他地方是有道理的 (4认同)
  • 当然。有时答案就是这么简单。 (3认同)
  • 没有回答这个问题:(我希望我的存储库的一部分同步到我的 iCloud 中。不幸的是,iCloud 不遵循符号链接,所以我想我可以让 git 遵循符号链接,并将原始文件存储在 iCloud 中。结果没有人遵循符号链接:\ (2认同)

Ken*_*ric 44

注意:自Git 1.6.1起,此建议现已根据评论过时.Git曾经以这种方式行事,而不再这样做.


Git默认尝试存储符号链接而不是跟随它们(对于紧凑性,它通常是人们想要的).

但是,当符号链接是目录时,我偶然设法让它在符号链接之外添加文件.

即:

  /foo/
  /foo/baz
  /bar/foo --> /foo
  /bar/foo/baz
Run Code Online (Sandbox Code Playgroud)

通过做

 git add /bar/foo/baz
Run Code Online (Sandbox Code Playgroud)

当我尝试它时,它似乎工作.然而,当时我的这种行为是不受欢迎的,所以我无法向你提供除此之外的信息.

  • 提交725b06050a083474e240a2436121e0a80bb9f175和806d13b1ccdbdde4bbdfb96902791c4b7ed125f6引入了一些更改,这些更改阻止了您在符号链接目录之外添加文件,因此这在1.6.1版本的git中不起作用 (72认同)
  • 在osx上对我不起作用.说"超出了象征性的联系" (17认同)
  • @ user1767316阅读了整个内容和评论。它曾经可以工作,现在不再起作用。软件更改,但堆栈溢出可接受的答案没有。我已经说明这还行不通。再看另一个答案。 (2认同)

fre*_*nte 44

请改用硬链接.这与软(符号)链接不同.所有程序,包括git将文件视为常规文件.请注意,内容可以通过改变被修改或者源或目的地.

在macOS上(10.13 High Sierra之前)

如果您已经安装了git和Xcode,请安装hardlink.它是创建硬链接的微观工具.

要创建硬链接,只需:

hln source destination
Run Code Online (Sandbox Code Playgroud)

macOS High Sierra更新

Apple文件系统是否支持目录硬链接?

Apple File System不支持目录硬链接.在macOS上从HFS +转换为APFS卷格式时,所有目录硬链接都将转换为符号链接或别名.

来自developer.apple.com上的APFS FAQ

关注https://github.com/selkhateeb/hardlink/issues/31以了解未来的替代方案.

在Linux和其他Unix风格

ln命令可以生成硬链接:

ln source destination
Run Code Online (Sandbox Code Playgroud)

在Windows上(Vista,7,8,...)

有人建议在Windows上使用mklink创建一个联结,但我还没有尝试过:

mklink /j "source" "destination"
Run Code Online (Sandbox Code Playgroud)

  • 你不能硬链接到目录,对吗? (20认同)
  • 请注意:这基本上就是我所寻找的,但后来我了解到,在Linux上,不幸的是,硬链接无法跨越文件系统边界(这是我的用例). (6认同)
  • @Nanne不,但你可以这样做:`cp -al source destination`.`-l'表示硬链接文件而不是复制. (6认同)
  • 遗憾的是,您无法硬链接目录或跨文件系统边界.这使得这个解决方案对我来说双重无法解决. (5认同)

Abb*_*fei 19

这是一个预提交钩子,用这些符号链接的内容替换索引中的符号链接blob.

把它放入.git/hooks/pre-commit,并使其可执行:

#!/bin/sh
# (replace "find ." with "find ./<path>" below, to work with only specific paths)

# (these lines are really all one line, on multiple lines for clarity)
# ...find symlinks which do not dereference to directories...
find . -type l -exec test '!' -d {} ';' -print -exec sh -c \
# ...remove the symlink blob, and add the content diff, to the index/cache
    'git rm --cached "$1"; diff -au /dev/null "$1" | git apply --cached -p1 -' \
# ...and call out to "sh".
    "process_links_to_nondir" {} ';'

# the end
Run Code Online (Sandbox Code Playgroud)

笔记

我们尽可能使用符合POSIX标准的功能; 但是,diff -a不是POSIX兼容,可能还有其他.

此代码中可能存在一些错误/错误,即使它已经过一些测试.

  • 很高兴看到尝试实际回答文件而不是目录的问题.但是请注意,上面仍然会在``git status``中显示``typechange``,这些文件实际上是符号链接,但现在它们不是git. (4认同)
  • @Abbafei你可以修改脚本使其在Ubuntu(14.04)上运行吗?它显示了`find:缺少-exec'的参数.可能需要逐步执行命令,而不是将所有内容组合成单行. (3认同)

小智 12

我过去常常在符号链接之外添加文件已有一段时间了.过去工作得很好,没有做任何特殊安排.自从我更新到Git 1.6.1后,这不再适用了.

您可以切换到Git 1.6.0来完成这项工作.我希望Git的未来版本会有一个标志,git-add允许它再次遵循符号链接.


ijo*_*eph 7

MacOS(我有Mojave / 10.14,git版本2.7.1)上,使用bindfs

brew install bindfs

cd /path/to/git_controlled_dir

mkdir local_copy_dir

bindfs <source_dir> local_copy_dir

其他评论已暗示了这一点,但其他答案中并未明确提供。希望这可以节省一些时间。


Von*_*onC 6

使用Git 2.3.2+(Q1 2015年),还有就是Git会另一起案件遵循符号链接了:见犯e0d201b通过JUNIOÇ滨野(gitster)(主Git的维护者)

apply:不要触摸符号链接之外的文件

因为Git将符号链接跟踪为符号链接,所以在其主要部分中具有符号链接的路径(例如path/to/dir/file,在哪里path/to/dir是到其他地方的符号链接,无论是在工作树内部还是外部)都不会出现在有效应用的补丁中,除非相同的补丁首先删除符号链接以允许在那里创建目录.

检测并拒绝这样的补丁.

类似地,当输入创建符号链接path/to/dir然后创建文件时path/to/dir/file,我们需要将其标记为错误,而不path/to/dir在文件系统中实际创建符号链接.

相反,对于输入中在结果中留下路径(即非删除)的任何补丁,我们通过检查输入中的所有补丁然后检查补丁的目标来检查补丁将创建的结果树的所有前导路径应用程序(索引或工作树).

这样,我们:

  • 抓住恶作剧或错误,同时添加符号链接path/to/dir和文件path/to/dir/file,
  • 同时允许删除符号的有效补丁link path/to/dir然后添加文件path/to/dir/file.

这意味着,在这种情况下,错误消息将不是通用的"%s: patch does not apply",但更具体的一个:

affected file '%s' is beyond a symbolic link
Run Code Online (Sandbox Code Playgroud)


Alc*_*aro 6

我厌倦了这里的每个解决方案要么已经过时,要么需要root,所以我做了一个基于LD_PRELOAD的解决方案(仅限Linux).

它与Git的内部结构挂钩,覆盖了'这是一个符号链接吗?' 函数,允许将符号链接视为其内容.默认情况下,所有指向repo外部的链接都是内联的; 请参阅链接了解详情.