如何让 Git 遵循符号链接?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/86402/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I get Git to follow symlinks?
提问by Matt
Is my best be going to be a shell script which replaces symlinks with copies, or is there another way of telling Git to follow symlinks?
我最好是成为一个用副本替换符号链接的 shell 脚本,还是有另一种方法告诉 Git 遵循符号链接?
PS: I know it's not very secure, but I only want to do it in a few specific cases.
PS:我知道它不是很安全,但我只想在少数特定情况下这样做。
采纳答案by Kent Fredric
NOTE:This advice is now out-dated as per comment since Git 1.6.1. Git used to behave this way, and no longer does.
注意:自 Git 1.6.1 以来,根据评论,此建议现已过时。Git 曾经有过这种行为,现在不再如此。
Git by default attempts to store symlinks instead of following them (for compactness, and it's generally what people want).
默认情况下,Git 尝试存储符号链接而不是跟随它们(为了紧凑,这通常是人们想要的)。
However, I accidentally managed to get it to add files beyond the symlink when the symlink is a directory.
但是,当符号链接是目录时,我不小心设法让它在符号链接之外添加文件。
I.e.:
IE:
/foo/
/foo/baz
/bar/foo --> /foo
/bar/foo/baz
by doing
通过做
git add /bar/foo/baz
it appeared to work when I tried it. That behavior was however unwanted by me at the time, so I can't give you information beyond that.
当我尝试它时,它似乎有效。然而,当时我不希望这种行为,所以我不能给你更多的信息。
回答by user252400
What I did to add to get the files within a symlink into Git (I didn't use a symlink but):
为了将符号链接中的文件添加到 Git 中,我做了什么添加(我没有使用符号链接但是):
sudo mount --bind SOURCEDIRECTORY TARGETDIRECTORY
Do this command in the Git-managed directory. TARGETDIRECTORY
has to be created before the SOURCEDIRECTORY
is mounted into it.
在 Git 管理的目录中执行此命令。TARGETDIRECTORY
必须在SOURCEDIRECTORY
安装到它之前创建。
It works fine on Linux, but not on OS X! That trick helped me with Subversion too. I use it to include files from an Dropbox account, where a webdesigner does his/her stuff.
它在 Linux 上运行良好,但不适用于 OS X!这个技巧也帮助我使用 Subversion。我用它来包含来自 Dropbox 帐户的文件,网页设计师在那里做他/她的事情。
回答by spier
Why not create symlinks the other way around? Meaning instead of linking from the Git repository to the application directory, just link the other way around.
为什么不以相反的方式创建符号链接?这意味着不是从 Git 存储库链接到应用程序目录,而是以相反的方式链接。
For example, let's say I am setting up an application installed in ~/application
that needs a configuration file config.conf
:
例如,假设我正在设置一个~/application
需要配置文件的应用程序config.conf
:
- I add
config.conf
to my Git repository, for example, at~/repos/application/config.conf
. - Then I create a symlink from
~/application
by runningln -s ~/repos/application/config.conf
.
- 我添加
config.conf
到我的 Git 存储库,例如,在~/repos/application/config.conf
. - 然后我
~/application
通过运行 创建一个符号链接ln -s ~/repos/application/config.conf
。
This approach might not always work, but it worked well for me so far.
这种方法可能并不总是有效,但到目前为止对我来说效果很好。
回答by fregante
Use hard links instead. This differs from a soft (symbolic) link. All programs, including git
will treat the file as a regular file. Note that the contents can be modified by changing eitherthe source or the destination.
改用硬链接。这与软(符号)链接不同。所有程序,包括git
将文件视为常规文件。请注意,内容可以通过改变被修改或者源或目的地。
On macOS (before 10.13 High Sierra)
在 macOS 上(10.13 High Sierra 之前)
If you already have git and Xcode installed, install hardlink. It's a microscopic tool to create hard links.
如果您已经安装了 git 和 Xcode,请安装 hardlink。它是创建硬链接的微观工具。
To create the hard link, simply:
要创建硬链接,只需:
hln source destination
macOS High Sierra update
macOS High Sierra 更新
Does Apple File System support directory hard links?
Directory hard links are not supported by Apple File System. All directory hard links are converted to symbolic links or aliases when you convert from HFS+ to APFS volume formats on macOS.
Apple 文件系统是否支持目录硬链接?
Apple 文件系统不支持目录硬链接。当您在 macOS 上从 HFS+ 转换为 APFS 卷格式时,所有目录硬链接都会转换为符号链接或别名。
Follow https://github.com/selkhateeb/hardlink/issues/31for future alternatives.
按照https://github.com/selkhateeb/hardlink/issues/31了解未来的替代方案。
On Linux and other Unix flavors
在 Linux 和其他 Unix 版本上
The ln
command can make hard links:
该ln
命令可以建立硬链接:
ln source destination
On Windows (Vista, 7, 8, …)
在 Windows 上(Vista、7、8 ……)
Someone suggested to use mklinkcreate a junction on Windows, but I haven't tried it:
有人建议在 Windows 上使用mklink创建一个结点,但我没有尝试过:
mklink /j "source" "destination"
回答by Abbafei
This is a pre-commit hookwhich replaces the symlink blobs in the index, with the content of those symlinks.
这是一个预提交钩子,它用这些符号链接的内容替换索引中的符号链接 blob。
Put this in .git/hooks/pre-commit
, and make it executable:
将其放入.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 ""; diff -au /dev/null "" | git apply --cached -p1 -' \
# ...and call out to "sh".
"process_links_to_nondir" {} ';'
# the end
Notes
笔记
We use POSIX compliant functionality as much as possible; however, diff -a
is not POSIX compliant, possibly among other things.
我们尽可能使用符合 POSIX 的功能;但是,diff -a
不符合 POSIX 标准,可能还有其他问题。
There may be some mistakes/errors in this code, even though it was tested somewhat.
这段代码中可能有一些错误/错误,即使它经过了一些测试。
回答by ijoseph
On MacOS
(I have Mojave/ 10.14, git
version 2.7.1), use bindfs
.
在MacOS
(我有 Mojave/10.14,git
版本 2.7.1)上,使用bindfs
.
brew install bindfs
brew install bindfs
cd /path/to/git_controlled_dir
cd /path/to/git_controlled_dir
mkdir local_copy_dir
mkdir local_copy_dir
bindfs </full/path/to/source_dir> </full/path/to/local_copy_dir>
bindfs </full/path/to/source_dir> </full/path/to/local_copy_dir>
It's been hinted by other comments, but not clearly provided in other answers. Hopefully this saves someone some time.
其他评论已经暗示了这一点,但在其他答案中没有明确提供。希望这可以节省一些时间。
回答by Erik Schnetter
I used to add files beyond symlinks for quite some time now. This used to work just fine, without making any special arrangements. Since I updated to Git 1.6.1, this does not work any more.
我曾经在很长一段时间内添加符号链接之外的文件。这过去工作得很好,没有做任何特殊安排。由于我更新到 Git 1.6.1,这不再起作用。
You may be able to switch to Git 1.6.0 to make this work. I hope that a future version of Git will have a flag to git-add
allowing it to follow symlinks again.
您可以切换到 Git 1.6.0 来完成这项工作。我希望 Git 的未来版本将有一个标志,git-add
允许它再次遵循符号链接。
回答by Alcaro
I got tired of every solution in here either being outdated or requiring root, so I made an LD_PRELOAD-based solution(Linux only).
我厌倦了这里的每个解决方案要么过时要么需要 root,所以我做了一个基于 LD_PRELOAD 的解决方案(仅限 Linux)。
It hooks into Git's internals, overriding the 'is this a symlink?' function, allowing symlinks to be treated as their contents. By default, all links to outside the repo are inlined; see the link for details.
它挂钩到 Git 的内部结构,覆盖了“这是一个符号链接吗?” 功能,允许将符号链接视为其内容。默认情况下,所有到 repo 外部的链接都是内联的;有关详细信息,请参阅链接。
回答by VonC
With Git 2.3.2+ (Q1 2015), there is one other case where Git will notfollow symlink anymore: see commit e0d201bby Junio C Hamano (gitster
)(main Git maintainer)
使用Git 2.3.2+(Q1 2015年),有一个其他情况下的Git将不会跟随符号链接了:见犯e0d201b通过JUNIOÇ滨野(gitster
)(主Git的维护者)
apply
: do not touch a file beyond a symbolic link
apply
: 不要触及符号链接之外的文件
Because Git tracks symbolic links as symbolic links, a path that has a symbolic link in its leading part (e.g.
path/to/dir/file
, wherepath/to/dir
is a symbolic link to somewhere else, be it inside or outside the working tree) can never appear in a patch that validly applies, unless the same patch first removes the symbolic link to allow a directory to be created there.Detect and reject such a patch.
Similarly, when an input creates a symbolic link
path/to/dir
and then creates a filepath/to/dir/file
, we need to flag it as an error without actually creatingpath/to/dir
symbolic link in the filesystem.Instead, for any patch in the input that leaves a path (i.e. a non deletion) in the result, we check all leading paths against the resulting tree that the patch would create by inspecting all the patches in the input and then the target of patch application (either the index or the working tree).
This way, we:
- catch a mischief or a mistake to add a symbolic link
path/to/dir
and a filepath/to/dir/file
at the same time,- while allowing a valid patch that removes a symbolic
link path/to/dir
and then adds a filepath/to/dir/file
.
由于 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
。
That means, in that case, the error message won't be a generic one like "%s: patch does not apply"
, but a more specific one:
这意味着,在这种情况下,错误消息将不是像 那样的通用消息"%s: patch does not apply"
,而是更具体的消息:
affected file '%s' is beyond a symbolic link
回答by J Chris A
Hmmm, mount --bind
doesn't seem to work on Darwin.
嗯,mount --bind
似乎对达尔文不起作用。
Does anyone have a trick that does?
有没有人有这样做的技巧?
[edited]
[编辑]
OK, I found the answer on Mac OS X is to make a hardlink. Except that that API is not exposed via ln
, so you have to use your own tiny program to do this. Here is a link to that program:
好的,我发现在 Mac OS X 上的答案是建立硬链接。除了那个 API 没有通过 公开ln
,所以你必须使用你自己的小程序来做到这一点。这是该程序的链接:
Creating directory hard links in Mac OS X
Enjoy!
享受!