git 是否对同一磁盘上的远程服务器使用硬链接?
Does git use hardlinks for a remote on the same disk?
我有时会使用两个包含相同存储库的同级目录。使用
git remote add sibling ../the-other-directory
我通过
接管更改
git fetch sibling
git cherry-pick sibling/a-branch
这很实用,但是我对硬链接有顾虑:
如果存储库共享文件,那么其中一个崩溃可能也会导致另一个崩溃。损坏的存储库是我已经经历过的事情,我确信节省几兆字节和几毫秒是不值得的。
- 从同一分区上的存储库中提取时,git 是否使用硬链接?
- 如果是这样,是否有办法防止这种情况(例如
--no-hardlinks
用于 git-clone)?
不使用硬链接的另一个好处是有一个额外的备份,可以毫不费力地经常更新。
Git 在克隆时使用硬链接,但在获取时不使用。也就是说,当您通过 git remote add foo ../somewhere
然后 git fetch foo
添加遥控器时,您得到的是副本,而不是硬链接。
使用以下脚本进行测试表明,通过 git init
+ git remote add
+ git fetch
的伪克隆不会创建到源存储库的硬链接:
硬链接测试:
#!/usr/bin/env bash
tmpdir="$(mktemp -d)"
trap "rm -rf $tmpdir" EXIT
cd "$tmpdir"
set -x
git clone https://github.com/dictcp/awesome-git testrepo
git clone testrepo testrepo.localclone
mkdir testrepo.pseudoclone
cd testrepo.pseudoclone
git init
git remote add sibling ../testrepo
git fetch sibling
cd ..
ls -1 -i testrepo*/.git/objects/a0
输出的相关部分:
$ ls -1 -i testrepo*/.git/objects/a0
testrepo/.git/objects/a0:
417590 cdfa472f2bf8212a02a3edeb941868d651749d
testrepo.localclone/.git/objects/a0:
417590 cdfa472f2bf8212a02a3edeb941868d651749d
testrepo.pseudoclone/.git/objects/a0:
537341 cdfa472f2bf8212a02a3edeb941868d651749d
这意味着文件 testrepo.localclone/.git/objects/a0/cdfa472f2bf8212a02a3edeb941868d651749d
是指向 testrepo/.git/objects/a0/cdfa472f2bf8212a02a3edeb941868d651749d
的硬链接 - 它们的 inode 值相同(我的测试为 417590 运行,但你的里程数当然会有所不同) . testrepo.pseudoclone
仓库中相应文件的 inode 值(537341)告诉我们它是一个独立的副本。
满输出:
$ ./hardlinktest
+ git clone https://github.com/dictcp/awesome-git testrepo
Cloning into 'testrepo'...
remote: Counting objects: 58, done.
remote: Total 58 (delta 0), reused 0 (delta 0), pack-reused 58
Unpacking objects: 100% (58/58), done.
Checking connectivity... done.
+ git clone testrepo testrepo.localclone
Cloning into 'testrepo.localclone'...
done.
+ mkdir testrepo.pseudoclone
+ cd testrepo.pseudoclone
+ git init
Initialized empty Git repository in /tmp/tmp.ZWoH0OTA1P/testrepo.pseudoclone/.git/
+ git remote add sibling ../testrepo
+ git fetch sibling
remote: Counting objects: 58, done.
remote: Compressing objects: 100% (40/40), done.
remote: Total 58 (delta 17), reused 0 (delta 0)
Unpacking objects: 100% (58/58), done.
From ../testrepo
* [new branch] master -> sibling/master
+ cd ..
+ ls -1 -i testrepo/.git/objects/a0 testrepo.localclone/.git/objects/a0 testrepo.pseudoclone/.git/objects/a0
testrepo/.git/objects/a0:
417590 cdfa472f2bf8212a02a3edeb941868d651749d
testrepo.localclone/.git/objects/a0:
417590 cdfa472f2bf8212a02a3edeb941868d651749d
testrepo.pseudoclone/.git/objects/a0:
537341 cdfa472f2bf8212a02a3edeb941868d651749d
+ rm -rf /tmp/tmp.ZWoH0OTA1P
我有时会使用两个包含相同存储库的同级目录。使用
git remote add sibling ../the-other-directory
我通过
接管更改git fetch sibling
git cherry-pick sibling/a-branch
这很实用,但是我对硬链接有顾虑:
如果存储库共享文件,那么其中一个崩溃可能也会导致另一个崩溃。损坏的存储库是我已经经历过的事情,我确信节省几兆字节和几毫秒是不值得的。
- 从同一分区上的存储库中提取时,git 是否使用硬链接?
- 如果是这样,是否有办法防止这种情况(例如
--no-hardlinks
用于 git-clone)?
不使用硬链接的另一个好处是有一个额外的备份,可以毫不费力地经常更新。
Git 在克隆时使用硬链接,但在获取时不使用。也就是说,当您通过 git remote add foo ../somewhere
然后 git fetch foo
添加遥控器时,您得到的是副本,而不是硬链接。
使用以下脚本进行测试表明,通过 git init
+ git remote add
+ git fetch
的伪克隆不会创建到源存储库的硬链接:
硬链接测试:
#!/usr/bin/env bash
tmpdir="$(mktemp -d)"
trap "rm -rf $tmpdir" EXIT
cd "$tmpdir"
set -x
git clone https://github.com/dictcp/awesome-git testrepo
git clone testrepo testrepo.localclone
mkdir testrepo.pseudoclone
cd testrepo.pseudoclone
git init
git remote add sibling ../testrepo
git fetch sibling
cd ..
ls -1 -i testrepo*/.git/objects/a0
输出的相关部分:
$ ls -1 -i testrepo*/.git/objects/a0
testrepo/.git/objects/a0:
417590 cdfa472f2bf8212a02a3edeb941868d651749d
testrepo.localclone/.git/objects/a0:
417590 cdfa472f2bf8212a02a3edeb941868d651749d
testrepo.pseudoclone/.git/objects/a0:
537341 cdfa472f2bf8212a02a3edeb941868d651749d
这意味着文件 testrepo.localclone/.git/objects/a0/cdfa472f2bf8212a02a3edeb941868d651749d
是指向 testrepo/.git/objects/a0/cdfa472f2bf8212a02a3edeb941868d651749d
的硬链接 - 它们的 inode 值相同(我的测试为 417590 运行,但你的里程数当然会有所不同) . testrepo.pseudoclone
仓库中相应文件的 inode 值(537341)告诉我们它是一个独立的副本。
满输出:
$ ./hardlinktest
+ git clone https://github.com/dictcp/awesome-git testrepo
Cloning into 'testrepo'...
remote: Counting objects: 58, done.
remote: Total 58 (delta 0), reused 0 (delta 0), pack-reused 58
Unpacking objects: 100% (58/58), done.
Checking connectivity... done.
+ git clone testrepo testrepo.localclone
Cloning into 'testrepo.localclone'...
done.
+ mkdir testrepo.pseudoclone
+ cd testrepo.pseudoclone
+ git init
Initialized empty Git repository in /tmp/tmp.ZWoH0OTA1P/testrepo.pseudoclone/.git/
+ git remote add sibling ../testrepo
+ git fetch sibling
remote: Counting objects: 58, done.
remote: Compressing objects: 100% (40/40), done.
remote: Total 58 (delta 17), reused 0 (delta 0)
Unpacking objects: 100% (58/58), done.
From ../testrepo
* [new branch] master -> sibling/master
+ cd ..
+ ls -1 -i testrepo/.git/objects/a0 testrepo.localclone/.git/objects/a0 testrepo.pseudoclone/.git/objects/a0
testrepo/.git/objects/a0:
417590 cdfa472f2bf8212a02a3edeb941868d651749d
testrepo.localclone/.git/objects/a0:
417590 cdfa472f2bf8212a02a3edeb941868d651749d
testrepo.pseudoclone/.git/objects/a0:
537341 cdfa472f2bf8212a02a3edeb941868d651749d
+ rm -rf /tmp/tmp.ZWoH0OTA1P