5

在我的本地文件系统上,我希望能够只克隆 git repo (A) 的头部,因此新的 git repo (B) 不会出现任何历史记录。但我希望现在 B 中的文件的硬链接的好处是节省空间。有没有办法做到这一点?一旦 repo A 发生变化,硬链接是否有帮助?

谢谢!

4

2 回答 2

6

至少从 git 1.7.12 开始,似乎不可能使用对象数据库之间的硬链接进行本地浅层克隆。git clone --depth 1 --single-branch明确警告--depth在本地克隆中被忽略,并使用file://. 因此,您需要在硬链接和浅克隆之间进行选择。

即使存储库发生更改,硬链接也可以工作,至少在一段时间内,因为 git 将新对象添加到新文件中,并且从不修改现有文件。但是,为了提高效率,它偶尔会重新打包对象数据库,而且我看不到如何保留硬链接。

如果您选择浅克隆,则可以使用git clone --single-branch --depth 1 file://old_repo_dir选项创建克隆。我觉得这很烦人,这--depth 1意味着 1 项历史记录,因此您不仅会获得最新的提交,还会获得其父提交(如果是合并,则为父提交)。父级从原始存储库获取提交消息,但提交消息存在,因为实际上提交包含整个树的创建。

我更喜欢从带有我选择的提交消息的单个提交开始,该提交消息会创建初始树。这是通过首先在旧仓库中创建一个没有历史记录的新分支,然后将该分支拉到新的空仓库中来获得的。我在一个带有 664MB 对象数据库和 673k 个对象(Emacs bzr 存储库转换为 git)的大型存储库上对此进行了测试。当新的 repo 收到 pull 时,它有一个 36MB 的对象数据库,其中包含 3477 个对象——因此多余的内容显然被修剪了。以下是具体步骤:

# at the old repo:
git checkout --orphan tmp-snapshot
git commit -m "Initial commit."

# at the new repo location:
git init
git pull OLD_REPO_DIR tmp-snapshot:master

# back at the old repo:
git branch -D tmp-snapshot   # no longer serves a purpose

现在,master新 repo 的分支包含一个提交,其树与旧 repo 的树相同,并且没有任何历史记录。

于 2012-09-19T19:44:28.137 回答
2

您可以克隆它,然后重新创建头部提交以剥离父母。考虑到您的原始存储库的对象可能是打包的,无论如何,您的硬链接比您想要的要多。是的,硬链接会在一段时间内保持不变,但是一旦你开始执行 gc 或类似的操作,效果可能会消失。您还可以使用替代而不是硬链接。

查找文档git commit-tree以从树中创建提交,我无法告诉您确切的语法。

于 2012-09-19T19:04:49.717 回答