将 git 存储库转换为浅层?

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

Converting git repository to shallow?

git

提问by Robert

How can I convert an already cloned git repository to a shallow repository?

如何将已经克隆的 git 存储库转换为浅层存储库?

The git repository is downloaded through a script outside of my control so I cannot do a shallow clone.

git 存储库是通过我无法控制的脚本下载的,因此我无法进行浅层克隆。

The reason for doing this is to save disk space. (Yes, I'm really short on disk space so even though a shallow repository doesn't save much, it is needed.)

这样做的原因是为了节省磁盘空间。(是的,我的磁盘空间真的很短缺,所以即使浅存储库不会节省多少,它也是必需的。)

I already tried

我已经试过了

git repack -a -d -f -depth=1

But that actually made the repository larger.

但这实际上使存储库更大。

采纳答案by MatrixFrog

Let's say the earliest commit you want to keep has a SHA1 of c0ffee.

假设您要保留的最早提交的 SHA1 为c0ffee.

  1. Create a new empty branch
  2. Checkout the treeof the earliest commit you want to keep, without actually checking out the commit: git checkout c0ffee -- .(Now HEADis still pointing to your new empty branch, but your working tree and index both look like the tree of c0ffee)
  3. Commit the whole tree: git commit -m "Initial commit, copied from c0ffee"
  4. At this point git diff-tree newbranch c0ffeeshould produce no output -- they have the same tree. (Alternatively, you could do git show -s c0ffee --format=%Tand git show -s newbranch --format=%Tand they should show the same hash.)
  5. git rebase --onto newbranch c0ffee master
  6. git branch -d newbranch
  7. git gc
  1. 创建一个新的空分支
  2. 签出你想要保留的最早提交的,而不实际签出提交:(git checkout c0ffee -- .现在HEAD仍然指向你的新空分支,但你的工作树和索引都看起来像 的树c0ffee
  3. 提交整个树: git commit -m "Initial commit, copied from c0ffee"
  4. 此时git diff-tree newbranch c0ffee不应产生任何输出——它们具有相同的树。(或者,您可以执行git show -s c0ffee --format=%T并且git show -s newbranch --format=%T它们应该显示相同的哈希值。)
  5. git rebase --onto newbranch c0ffee master
  6. git branch -d newbranch
  7. git gc

回答by fuzzyTew

This worked for me:

这对我有用:

git pull --depth 1
git gc --prune=all

回答by user212328

You can convert git repo to a shallow one in place along this lines:

您可以按照以下方式将 git repo 转换为浅层:

git show-ref -s HEAD > .git/shallow
git reflog expire --expire=0
git prune
git prune-packed

Make sure to make backup since this is destructive operation, also keep in mind that cloning nor fetching from shallow repo is not supported! To really remove all the history you also need to remove all references to previous commits before pruning.

确保进行备份,因为这是破坏性操作,还请记住,不支持克隆或从浅存储库中获取!要真正删除所有历史记录,您还需要在修剪之前删除对先前提交的所有引用。

回答by VasiliNovikov

You can make a shallow clone of an already existing repo by:

您可以通过以下方式对现有存储库进行浅层克隆:

git clone --depth 1 file:///full/path/to/original/dir destination

Note that the first "address" should be a file://, that's important. Also, git will assume your original local file:// address to be the "remote" ("origin"), so you'll need to update the new repository specifying the correct git remote.

请注意,第一个“地址”应该是file://,这很重要。此外,git 将假定您的原始本地 file:// 地址是“远程”(“来源”),因此您需要更新新存储库,指定正确的git remote.

回答by Pop Catalin

Convert to shallow since a specific date:

自特定日期以来转换为浅:

git pull --shallow-since=YYYY-mm-dd
git gc --prune=all

Also works:

也有效:

git fetch --shallow-since=YYYY-mm-dd
git gc --prune=all

回答by VonC

Note that a shallow repo (like one with git clone --depth 1as a way to convert an existing repo to a shallow one) can fail on git repack.

请注意,浅层存储库(例如git clone --depth 1将现有存储库转换为浅层存储库的一种方式)可能会失败git repack

See commit 5dcfbf5, commit 2588f6e, commit 328a435(24 Oct 2018) by Johannes Schindelin (dscho).
(Merged by Junio C Hamano -- gitster--in commit ea100b6, 06 Nov 2018)

请参阅Johannes Schindelin ( ) 的commit 5dcfbf5commit 2588f6ecommit 328a435(2018 年 10 月 24 日(由Junio C Hamano合并-- --ea100b6 提交中,2018 年 11 月 6 日)dscho
gitster

repack -ad: prune the list of shallow commits

git repackcan drop unreachable commits without further warning, making the corresponding entries in .git/shallowinvalid, which causes serious problems when deepening the branches.

One scenario where unreachable commits are dropped by git repackis when a git fetch --prune(or even a git fetchwhen a ref was force-pushed in the meantime) can make a commit unreachable that was reachable before.

Therefore it is not safe to assume that a git repack -adlfwill keep unreachable commits alone (under the assumption that they had not been packed in the first place, which is an assumption at least some of Git's code seems to make).

This is particularly important to keep in mind when looking at the .git/shallowfile: if any commits listed in that file become unreachable, it is not a problem, but if they go missing, it isa problem.
One symptom of this problem is that a deepening fetch may now fail with:

fatal: error in object: unshallow <commit-hash>

To avoid this problem, let's prune the shallow list in git repackwhen the -doption is passed, unless -Ais passed, too (which would force the now-unreachable objects to be turned into loose objects instead of being deleted).
Additionally, we also need to take --keep-reachableand --unpack-unreachable=<date>into account.

Note: an alternative solution discussed during the review of this patch was to teach git fetchto simply ignore entries in .git/shallowif the corresponding commits do not exist locally.
A quick test, however, revealed that the .git/shallowfile is written during a shallow clone, in which case the commits do not exist, either, but the "shallow" line doesneed to be sent.
Therefore, this approach would be a lot more finicky than the approach presented by the this patch.

repack -ad: 修剪浅提交列表

git repack可以在没有进一步警告的情况下丢弃不可达的提交,使相应的条目.git/shallow无效,这在深化分支时会导致严重的问题。

无法访问的提交被丢弃的一种情况git repackgit fetch --prune(或者甚至git fetch是在此期间强制推送 ref 时)可以使之前可以访问的提交无法访问。

因此,假设 agit repack -adlf将单独保留无法访问的提交是不安全的(假设它们首先没有被打包,这是至少一些 Git 代码似乎做出的假设)。

在查看.git/shallow文件时要记住这一点特别重要:如果该 文件中列出的任何提交变得不可访问,这不是问题,但如果它们丢失,则一个问题。
这个问题的一个症状是深化获取现在可能会失败:

fatal: error in object: unshallow <commit-hash>

为了避免这个问题,让我们git repack-d选项被传递时修剪浅表,除非也-A被传递(这将迫使现在无法访问的对象变成松散的对象而不是被删除)。
此外,我们还需要考虑--keep-reachable--unpack-unreachable=<date>考虑。

注意:在此补丁期间讨论的替代解决方案是教导如果相应的提交在本地不存在git fetch.git/shallow则简单地忽略条目。
然而,快速测试显示该.git/shallow文件是在浅克隆期间写入的,在这种情况下,提交也不存在,但确实需要发送“浅”行 。
因此,这种方法比此补丁提供的方法要挑剔得多。