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

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


当前回答

使用硬链接代替。这不同于软(符号)链接。包括git在内的所有程序都将该文件视为常规文件。注意,可以通过更改源或目标来修改内容。

macOS版本(10.13 High Sierra之前版本)

如果你已经安装了git和Xcode,安装hardlink。这是一个创建硬链接的微观工具。

要创建硬链接,只需:

hln source destination

macOS High Sierra更新

苹果文件系统支持目录硬链接吗? 苹果文件系统不支持目录硬链接。在macOS上从HFS+转换为APFS卷格式时,所有目录硬链接都转换为符号链接或别名。 来自APFS FAQ上developer.apple.com

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

在Linux和其他Unix版本上

ln命令可以创建硬链接:

ln source destination

在Windows (Vista, 7,8,…)

使用mklink在Windows上创建一个连接:

mklink /j "source" "destination"

其他回答

符号链接的转换可能很有用。链接到Git文件夹中,而不是脚本中的符号链接。

@user252400建议的另一种实现是使用bwrap,这是一个小型setuid沙盒,可以在所有主要发行版中找到——通常默认安装。Bwrap允许你无需sudo就可以绑定挂载目录,并在git或shell退出时自动解除绑定。

假设你的开发过程不是很疯狂(见下文),在一个私有的命名空间中启动bash,并在git目录下绑定外部目录:

bwrap --ro-bind / / \
      --bind {EXTERNAL-DIR} {MOUNTPOINT-IN-GIT-DIR} \
      --dev /dev \
      bash

然后做你通常做的所有事情,比如git添加、git提交等等。当你完成时,退出bash。干净简单。

注意:为了防止沙盒转义,bwrap不允许执行其他setuid二进制文件。详见man bwrap。

我使用的是Git 1.5.4.3,如果传递的符号链接后面有斜杠,它会跟着它。如。

# Adds the symlink itself
$ git add symlink

# Follows symlink and adds the denoted directory's contents
$ git add symlink/

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

酿造安装bindfs

cd / path / to / git_controlled_dir

mkdir local_copy_dir

bindfs </full/path/ source_dir> </full/path/ local_dir >

其他评论暗示了这一点,但在其他答案中没有明确提供。希望这能为大家节省一些时间。

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

把它放在.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

笔记

我们尽可能多地使用POSIX兼容功能;然而,diff -a不符合POSIX,可能还有其他原因。

这段代码中可能有一些错误/错误,即使它经过了一些测试。