git如何处理符号链接?
如果我有一个文件或目录是一个符号链接,我把它交给一个git仓库发生了什么?
我会假设它把它作为一个符号链接,直到文件被删除,然后如果你从旧版本拉文件,它只是创build一个正常的文件。
当我删除它引用的文件时它做了什么? 它只是提交悬挂链接?
git只是将链接的内容(即链接到的文件系统对象的path)存储在“blob”中,就像正常文件一样。 然后在表示其包含目录的树对象中存储名称,模式和types(包括它是符号链接的事实)。
在检出包含链接的树时,无论目标文件系统对象是否存在,它都会将该对象恢复为符号链接。
如果删除符号链接引用的文件,则不会以任何方式影响git控制的符号链接。 你会有一个悬而未决的参考。 如果需要,用户可以移除或更改链接以指向有效的内容。
符号链接的目录:
当有一个目录是一个软链接时,注意会发生什么是很重要的。 任何git拉更新删除链接,并使其成为一个正常的目录。 这是我学到的很好的方式。 一些见解这里和这里。
例
之前
ls -l lrwxrwxrwx 1 admin adm 29 Sep 30 15:28 src/somedir -> /mnt/somedir
git添加/提交/推送
It remains the same
后git拉和一些更新发现
drwxrwsr-x 2 admin adm 4096 Oct 2 05:54 src/somedir
TL; DR:由符号链接引用的数据不存储在存储库中。
您可以通过查看Git在将文件添加到索引时执行什么操作来了解Git执行的操作。 索引就像一个预先提交。 在提交索引的情况下,可以使用git checkout
将索引中的所有内容放回到工作目录中。 那么,当你添加一个符号链接到索引时,Git会做什么?
要弄清楚,首先要做一个符号链接:
$ ln -s /Path/referenced/by/symlink symlink
Git还不知道这个文件。 git ls-files
让你检查你的索引( -s
打印stat
的输出):
$ git ls-files -s ./symlink $
现在,将符号链接的内容添加到索引中,以将其添加到Git对象存储中。 当你添加一个文件到索引时,Git将它的内容存储在Git对象存储中。
$ git add ./symlink
那么,增加了什么?
$ git ls-files -s ./symlink 120000 1596f9db1b9610f238b78dd168ae33faa2dec15c 0 symlink $
散列是对在Git对象存储中创build的打包对象的引用。 如果您查看.git/objects/15/96f9db1b9610f238b78dd168ae33faa2dec15c
则可以检查此对象。
120000
是文件模式。 对于一个普通的文件来说就像100644
一样,并且是链接的特殊模式。 从man git-config
:
core.symlinks
如果为false,则将符号链接检出为包含链接文本的小纯文件。 git-update-index(1)和git-add(1)不会将loggingtypes更改为常规文件。
使用git cat-file -p
来打印内容:
$ git cat-file -p 1596f9db1 /Path/referenced/by/symlink
所以,这就是Git对符号链接所做的事情:当你git checkout
符号链接时,根据configuration,你可以得到一个引用完整文件系统path或符号链接的文本文件。 由符号链接引用的数据不存储在存储库中。