Git 如何处理符号链接?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/954560/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 06:33:49  来源:igfitidea点击:

How does Git handle symbolic links?

gitversion-controlsymlink

提问by Alex

If I have a file or directory that is a symbolic link and I commit it to a Git repository, what happens to it?

如果我有一个作为符号链接的文件或目录,并且我将它提交到 Git 存储库,它会发生什么?

I would assume that it leaves it as a symbolic link until the file is deleted and then if you pull the file back from an old version it just creates a normal file.

我认为它会将它保留为符号链接,直到文件被删除,然后如果您从旧版本中拉回文件,它只会创建一个普通文件。

What does it do when I delete the file it references? Does it just commit the dangling link?

当我删除它引用的文件时,它会做什么?它只是提交悬空链接吗?

采纳答案by CB Bailey

Git just stores the contents of the link (i.e. the path of the file system object that it links to) in a 'blob' just like it would for a normal file. It then stores the name, mode and type (including the fact that it is a symlink) in the tree object that represents its containing directory.

Git 只是将链接的内容(即它链接到的文件系统对象的路径)存储在一个“blob”中,就像它存储普通文件一样。然后它将名称、模式和类型(包括它是符号链接的事实)存储在表示其包含目录的树对象中。

When you checkout a tree containing the link, it restores the object as a symlink regardless of whether the target file system object exists or not.

当您检出包含链接的树时,无论目标文件系统对象是否存在,它都会将对象恢复为符号链接。

If you delete the file that the symlink references it doesn't affect the Git-controlled symlink in any way. You will have a dangling reference. It is up to the user to either remove or change the link to point to something valid if needed.

如果删除符号链接引用的文件,它不会以任何方式影响 Git 控制的符号链接。你会有一个悬空的参考。如果需要,用户可以删除或更改链接以指向有效的内容。

回答by Dmitry Minkovsky

You can find out what Git does with a file by seeing what it does when you add it to the index. The index is like a pre-commit. With the index committed, you can use git checkoutto bring everything that was in the index back into the working directory. So, what does Git do when you add a symbolic link to the index?

您可以通过查看将文件添加到索引时的作用来了解 Git 对文件的作用。索引就像一个预提交。提交索引后,您可以使用git checkout将索引中的所有内容带回工作目录。那么,当你向索引添加符号链接时,Git 做了什么?

To find out, first, make a symbolic link:

要找出答案,首先,创建一个符号链接:

$ ln -s /path/referenced/by/symlink symlink

Git doesn't know about this file yet. git ls-fileslets you inspect your index (-sprints stat-like output):

Git 还不知道这个文件。git ls-files让您检查索引(-s类似打印stat输出):

$ git ls-files -s ./symlink
[nothing]

Now, add the contents of the symbolic link to the Git object store by adding it to the index. When you add a file to the index, Git stores its contents in the Git object store.

现在,通过将符号链接的内容添加到索引来将符号链接的内容添加到 Git 对象存储。当您将文件添加到索引时,Git 会将其内容存储在 Git 对象存储中。

$ git add ./symlink

So, what was added?

那么,添加了什么?

$ git ls-files -s ./symlink
120000 1596f9db1b9610f238b78dd168ae33faa2dec15c 0       symlink

The hash is a reference to the packed object that was created in the Git object store. You can examine this object if you look in .git/objects/15/96f9db1b9610f238b78dd168ae33faa2dec15cin the root of your repository. This is the file that Git stores in the repository, that you can later check out.If you examine this file, you'll see it is very small. It does not store the contents of the linked file.

散列是对在 Git 对象存储中创建的打包对象的引用。如果您查看.git/objects/15/96f9db1b9610f238b78dd168ae33faa2dec15c存储库的根目录,则可以检查此对象。这是 Git 存储在存储库中的文件,您可以稍后检出。如果您检查此文件,您会发现它非常小。它不存储链接文件的内容。

(Note 120000is the mode listed in ls-filesoutput. It would be something like 100644for a regular file.)

(注意120000ls-files输出中列出的模式。它类似于100644常规文件。)

But what does Git do with this object when you check it out from the repository and into your filesystem? It depends on the core.symlinksconfig. From man git-config:

但是当你从存储库中检出这个对象并进入你的文件系统时,Git 对它做了什么?这取决于core.symlinks配置。来自man git-config

core.symlinks

If false, symbolic links are checked out as small plain files that contain the link text.

core.symlinks

如果为 false,符号链接将作为包含链接文本的小型纯文件检出。

So, with a symbolic link in the repository, upon checkout you either get a text file with a reference to a full filesystem path, or a proper symbolic link, depending on the value of the core.symlinksconfig.

因此,使用存储库中的符号链接,在结帐时,您将获得一个引用完整文件系统路径的文本文件,或一个正确的符号链接,具体取决于core.symlinks配置的值。

Either way, the data referenced by the symlink is not stored in the repository.

无论哪种方式,符号链接引用的数据都不会存储在存储库中。

回答by Shekhar

"Editor's" note: This post may contain outdated information. Please see comments and this questionregarding changes in Git since 1.6.1.

“编者注”:这篇文章可能包含过时的信息。请参阅有关自 1.6.1 以来 Git 更改的评论和此问题

Symlinked directories:

符号链接目录:

It's important to note what happens when there is a directory which is a soft link. Any Git pull with an update removes the link and makes it a normal directory. This is what I learnt hard way. Some insights hereand here.

重要的是要注意当目录是软链接时会发生什么。任何带有更新的 Git 拉取都会删除链接并使其成为普通目录。这是我努力学到的。这里这里的一些见解

Example

例子

Before

 ls -l
 lrwxrwxrwx 1 admin adm   29 Sep 30 15:28 src/somedir -> /mnt/somedir

git add/commit/push

git add/commit/push

It remains the same

After git pullAND some updates found

git pull发现一些更新之后

 drwxrwsr-x 2 admin adm 4096 Oct  2 05:54 src/somedir