将git repository转换为shallow?

s5a0g9ez  于 2023-04-19  发布在  Git
关注(0)|答案(6)|浏览(156)

如何将已经克隆的git仓库转换为浅仓库?
git仓库是通过我无法控制的脚本下载的,所以我不能做一个浅克隆。
这样做的原因是为了保存磁盘空间(是的,我的磁盘空间真的很紧张,所以即使浅存储库并不能节省很多,它也是需要的)。
我已经试过了

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

但这实际上使仓库变大了。

vbkedwbf

vbkedwbf1#

首先,你可能需要删除标签(因为它们会阻止GC处理带标签的提交),比如:

git tag -d $(git tag -l)

然后,这对我起了作用:

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

这仍然会留下reflog,它像标签一样引用额外的提交,可能会占用空间。请注意,除非非常需要,否则我不会删除reflog:它包含用于从错误中恢复的本地更改历史。
在下面的评论中有关于如何删除reflog的其他命令,以及一个类似问题的链接,该问题的答案较长。
如果你仍然有很多空间使用,确保你删除了标签,你应该在删除reflog之前先尝试。

yqyhoc1h

yqyhoc1h2#

你可以沿着下面的方式将git repo转换为shallow repo:

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

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

xuo3flqw

xuo3flqw3#

从特定日期开始转换为浅:

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

也适用于:

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

lvjbypge4#

创建本地仓库的浅克隆****:

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

注意第一个“address”应该是file://,这很重要。另外,git会假设你的原始本地file://地址是“remote”(“origin”),所以你需要更新新仓库,指定正确的git remote

vbopmzt1

vbopmzt15#

将@fuzzyTew的答案与对该答案的评论相结合:

git pull --depth 1
git tag -d $(git tag -l)
git reflog expire --expire=all --all
git gc --prune=all

想要在整个磁盘上运行此命令来保存空间吗?-然后运行以下fd命令:

fd -HIFt d '.git' -x bash -c 'pushd "$0" && ( git pull --depth 1; git tag -d $(git tag -l); git reflog expire --expire=all --all; git gc --prune=all ) && popd' {//}

或者使用常规的find

find -type d -name '.git' -exec bash -c 'pushd "${0%/*}" && ( git pull --depth 1; git tag -d $(git tag -l); git reflog expire --expire=all --all; git gc --prune=all ) && popd' {} \;
nxagd54h

nxagd54h6#

请注意,浅仓库(例如使用git clone --depth 1将现有仓库转换为浅仓库的仓库)可能会在git repack上失败。
参见commit 5dcfbf5commit 2588f6ecommit 328a435(2018年10月24日)by Johannes Schindelin ( dscho )
(由Junio C Hamano -- gitster --合并至commit ea100b6,2018年11月6日)
repack -ad:修剪浅提交列表
git repack可以在没有进一步警告的情况下丢弃无法访问的提交,使.git/shallow中的相应条目无效,这在深化分支时会导致严重的问题。
git repack删除不可达提交的一种情况是,当git fetch --prune(甚至当引用被强制推送时,git fetch)可以使之前可达的提交不可达。
因此,假设git repack -adlf将单独保存无法访问的提交是不安全的(假设它们一开始就没有被打包,至少Git的一些代码似乎是这样假设的)。
在查看.git/shallow文件时,请记住这一点特别重要:如果文件中列出的任何提交变得不可访问,这不是问题,但如果它们丢失了,这就是一个问题。
此问题的一个症状是,深化提取现在可能会失败,并且:

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

为了避免这个问题,让我们在传递-d选项时修剪git repack中的浅列表,除非也传递了-A(这将迫使现在无法访问的对象变成松散对象,而不是被删除)。
此外,我们还需要考虑--keep-reachable--unpack-unreachable=<date>
注:在审查此补丁时讨论的另一种解决方案是教git fetch在本地不存在相应提交时忽略.git/shallow中的条目。
然而,一个快速测试显示,.git/shallow文件是在浅 * 克隆 * 期间写入的,在这种情况下,提交也不存在,但“浅”行 * 需要发送。
因此,这种方法比这个补丁提供的方法要挑剔得多。

相关问题