Git 和硬链接

发布于 2024-09-24 05:17:37 字数 78 浏览 1 评论 0原文

考虑到Git不能识别指向存储库之外的符号链接,那么使用硬链接有什么问题吗?

Git 能破坏它们吗? 你能指点我详细的信息吗?

Considering that Git does not recognize symbolic links that point outside of the repository, is there any problem using hard links?

Could Git break them?
Can you please point me to detailed information?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

笨死的猪 2024-10-01 05:17:37

“树”对象代表 Git 中的目录,存储文件名和(子集)权限。它不存储 inode 号(或其他类型的文件 ID)。因此硬链接不能在git中表示,至少没有第三方工具,例如metastoregit-cache-meta (我不确定即使使用这些工具是否也可能)。

Git 尝试不触及不需要更新的文件,但您必须考虑到 git 不会尝试保留硬链接,因此它们可能会被 git 破坏。


关于指向外部存储库的符号链接:git 对它们没有任何问题,并且应该保留符号链接的内容...但此类链接的实用性对我来说是可疑的,因为这些符号链接是否会被破坏取决于在文件系统布局外部 git 存储库上,并且不受 git 控制。

The 'tree' object, representing directories in Git, stores file name and (subset of) permissions. It doesn't store inode number (or other kind of file id). Therefore hard links cannot be represented in git, at least not without third party tools such as metastore or git-cache-meta (and I am not sure if it is possible even with those tools).

Git tries to not touch files that it doesn't need to update, but you have to take into account that git doesn't try to preserve hardlinks, so they can be broken by git.


About symbolic links pointing outside repository: git has no problems with them and should preserve contents of symbolic links... but utility of such links is dubious to me, as whether those symlinks would be broken or not depends on the filesystem layout outside git repository, and not under control of git.

木森分化 2024-10-01 05:17:37

我发现,使用钩子,您可以捕获 git pull 事件(当有东西要拉时...)将脚本事件处理程序写入 .git/hooks/post-merge 文件。

首先,您必须chmod +x它。

然后,将 ln 命令放入其中,以便在每次拉取时重新创建硬链接。整齐啊!

它有效,我只需要为我的项目使用它,并且 ls -i 显示文件在 pull 后自动链接。


我的 .git/hooks/post-merge 示例:

#!/bin/sh
ln -f $GIT_DIR/../apresentacao/apresentacao.pdf $GIT_DIR/../capa/apresentacao.pdf
ln -f $GIT_DIR/../avaliacoesMono/avaliacao_monografias_2011_Nilo.pdf $GIT_DIR/../capa/avaliacoes.pdf
ln -f $GIT_DIR/../posters/poster_Nilo_sci.pdf $GIT_DIR/../capa/poster.pdf
ln -f $GIT_DIR/../monografia/monografia_Nilo.pdf $GIT_DIR/../capa/monografia_Nilo.pdf

重要提示:如您所见,存储库中任何文件的路径都应以 $GIT_DIR 开头,然后添加文件的部分相对路径。

同样重要的是: -f 是必要的,因为您正在重新创建目标文件。

编辑

现代 git 客户端似乎自然地支持存储库内部的符号链接和硬链接,即使在推送到远程位置然后从中克隆时也是如此。不过,我再也不需要链接到 git 存储库之外了...

$ mkdir tmp
$ cd tmp
$ git --version
git version 2.24.3 (Apple Git-128)
$ git init .
Initialized empty Git repository in /Users/teixeira/tmp/.git/
$ mkdir x
$ cd x
$ echo 123 > original
$ cat original
123
$ cd ..
$ ln -s x/original symlink
$ cat symlink
123
$ ln x/original hardlink
$ cat hardlink
123
$ git add .
$ git commit -m 'Symlink and hardlink commit'
[master (root-commit) 8df3134] Symlink and hardlink commit
 3 files changed, 3 insertions(+)
 create mode 100644 hardlink
 create mode 120000 symlink
 create mode 100644 x/original

从本地 git 存储库克隆

$ cd
$ git clone tmp/ teste_tmp
Cloning into 'teste_tmp'...
done.
$ cd teste_tmp/
$ ls
hardlink  symlink  x
$ cat symlink
123
$ cat hardlink
123

从远程存储库克隆

$ cd ~/tmp
$ git remote add origin https://github.com/myUser/myRepo.git
$ git push origin master
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 8 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (5/5), 361 bytes | 361.00 KiB/s, done.
Total 5 (delta 0), reused 0 (delta 0)
To https://github.com/myUser/myRepo.git
 + 964dfce...8df3134 master -> master
$ cd ../
$ git clone https://github.com/myUser/myRepo.git
Cloning into 'myRepo'...
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 5 (delta 0), reused 5 (delta 0), pack-reused 0
Unpacking objects: 100% (5/5), done.
$ cd myRepo/
$ cat symlink
123
$ cat hardlink
123

https: //github.com/mokacoding/symlinks 还指出了一件重要的事情:符号链接必须相对定义。

I found out that, using hooks, you can capture the git pull event (when there is something to pull...) writing the script event handler to .git/hooks/post-merge file.

First, you have to chmod +x it.

Then, put the ln commands inside it to recreate hard links at each pull. Neat huh!

It works, I just needed that for my project and ls -i shows that files were automatically linked after pull.


My example of .git/hooks/post-merge:

#!/bin/sh
ln -f $GIT_DIR/../apresentacao/apresentacao.pdf $GIT_DIR/../capa/apresentacao.pdf
ln -f $GIT_DIR/../avaliacoesMono/avaliacao_monografias_2011_Nilo.pdf $GIT_DIR/../capa/avaliacoes.pdf
ln -f $GIT_DIR/../posters/poster_Nilo_sci.pdf $GIT_DIR/../capa/poster.pdf
ln -f $GIT_DIR/../monografia/monografia_Nilo.pdf $GIT_DIR/../capa/monografia_Nilo.pdf

IMPORTANT: As you can see, the path to any file in your repository should begin with $GIT_DIR, then add the partial relative path to the file.

Also important: -f is necessary, because you are recreating the destination file.

EDIT

Modern git client seems to support symlinks and hardlinks inside of the repository naturally, even when pushing to a remote location and then cloning from it. I never had the need again to link outside a git repo though...

$ mkdir tmp
$ cd tmp
$ git --version
git version 2.24.3 (Apple Git-128)
$ git init .
Initialized empty Git repository in /Users/teixeira/tmp/.git/
$ mkdir x
$ cd x
$ echo 123 > original
$ cat original
123
$ cd ..
$ ln -s x/original symlink
$ cat symlink
123
$ ln x/original hardlink
$ cat hardlink
123
$ git add .
$ git commit -m 'Symlink and hardlink commit'
[master (root-commit) 8df3134] Symlink and hardlink commit
 3 files changed, 3 insertions(+)
 create mode 100644 hardlink
 create mode 120000 symlink
 create mode 100644 x/original

Cloning from local git repository

$ cd
$ git clone tmp/ teste_tmp
Cloning into 'teste_tmp'...
done.
$ cd teste_tmp/
$ ls
hardlink  symlink  x
$ cat symlink
123
$ cat hardlink
123

Cloning from remote repository

$ cd ~/tmp
$ git remote add origin https://github.com/myUser/myRepo.git
$ git push origin master
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 8 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (5/5), 361 bytes | 361.00 KiB/s, done.
Total 5 (delta 0), reused 0 (delta 0)
To https://github.com/myUser/myRepo.git
 + 964dfce...8df3134 master -> master
$ cd ../
$ git clone https://github.com/myUser/myRepo.git
Cloning into 'myRepo'...
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 5 (delta 0), reused 5 (delta 0), pack-reused 0
Unpacking objects: 100% (5/5), done.
$ cd myRepo/
$ cat symlink
123
$ cat hardlink
123

https://github.com/mokacoding/symlinks also points an important thing: symlinks must be defined relatively.

∞琼窗梦回ˉ 2024-10-01 05:17:37

从此 msysgit问题

连接点不是符号链接;因此,msysGit 根本不支持符号链接。

此外,Git 从未跟踪过硬链接

关于硬链接的评论总体上涉及 Git。具体问题是面向 Microsoft Windows 的(因为它是关于 msysgit 的),并且讨论争论了符号链接的潜在支持。

From this msysgit issue

Junction points are not symbolic links; therefore, symbolic links are simply unsupported in msysGit.

Also, hard links were never tracked by Git.

The comment about hard links concerns Git in general. The specific issue was Microsoft Windows-oriented (since it was about msysgit), and the discussion debates the potential support of symbolic links.

凉城已无爱 2024-10-01 05:17:37

谷歌“git 保留硬链接”,它表明 git 不知道如何保留硬链接结构 AFAIK,也许是有意设计的。

我的 Web 项目使用硬链接如下:

www/products/index.php
www/products/dell_latitude_id577/index.php #(hard linked to above)
www/products/dell_inspiron_id323/index.php #(hard linked again to above)

me@server:www/products$ ls -l index.php
-rwxr-xr-x 3 me me 1958 Aug 22 22:10 index.php*

如果我想对 index.php 进行更改,我会在一处更改它,硬链接(产品详细信息页面)指向更改 - 除非 git 在克隆过程中不保留这种关系并拉动其他计算机。

me@server:www$ git pull

在另一台机器上将为每个硬链接创建一个新的index.php。

Google 'git preserve hard links' and it shows that git does not know how to preserve hard link structure AFAIK, perhaps by design.

Web projects of mine use hard links as follows:

www/products/index.php
www/products/dell_latitude_id577/index.php #(hard linked to above)
www/products/dell_inspiron_id323/index.php #(hard linked again to above)

me@server:www/products$ ls -l index.php
-rwxr-xr-x 3 me me 1958 Aug 22 22:10 index.php*

If I wanted to make changes to index.php I change it in one place and the hard links (product detail pages) point to the changes -- except git does not preserve this relationship during cloning and pulling on other computers.

me@server:www$ git pull

on another machine will create a new index.php for each hard link.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文