将 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
Converting git repository to shallow?
提问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
.
- Create a new empty branch
- Checkout the treeof the earliest commit you want to keep, without actually checking out the commit:
git checkout c0ffee -- .
(NowHEAD
is still pointing to your new empty branch, but your working tree and index both look like the tree ofc0ffee
) - Commit the whole tree:
git commit -m "Initial commit, copied from c0ffee"
- At this point
git diff-tree newbranch c0ffee
should produce no output -- they have the same tree. (Alternatively, you could dogit show -s c0ffee --format=%T
andgit show -s newbranch --format=%T
and they should show the same hash.) git rebase --onto newbranch c0ffee master
git branch -d newbranch
git gc
- 创建一个新的空分支
- 签出你想要保留的最早提交的树,而不实际签出提交:(
git checkout c0ffee -- .
现在HEAD
仍然指向你的新空分支,但你的工作树和索引都看起来像 的树c0ffee
) - 提交整个树:
git commit -m "Initial commit, copied from c0ffee"
- 此时
git diff-tree newbranch c0ffee
不应产生任何输出——它们具有相同的树。(或者,您可以执行git show -s c0ffee --format=%T
并且git show -s newbranch --format=%T
它们应该显示相同的哈希值。) git rebase --onto newbranch c0ffee master
git branch -d newbranch
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 1
as 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 5dcfbf5、commit 2588f6e、commit 328a435(2018 年 10 月 24 日)。(由Junio C Hamano合并-- --在ea100b6 提交中,2018 年 11 月 6 日)dscho
gitster
repack -ad
: prune the list of shallow commits
git repack
can drop unreachable commits without further warning, making the corresponding entries in.git/shallow
invalid, which causes serious problems when deepening the branches.One scenario where unreachable commits are dropped by
git repack
is when agit fetch --prune
(or even agit fetch
when 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 -adlf
will 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/shallow
file: 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 repack
when the-d
option is passed, unless-A
is 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-reachable
and--unpack-unreachable=<date>
into account.Note: an alternative solution discussed during the review of this patch was to teach
git fetch
to simply ignore entries in.git/shallow
if the corresponding commits do not exist locally.
A quick test, however, revealed that the.git/shallow
file 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 repack
是git fetch --prune
(或者甚至git fetch
是在此期间强制推送 ref 时)可以使之前可以访问的提交无法访问。因此,假设 a
git 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
文件是在浅克隆期间写入的,在这种情况下,提交也不存在,但确实需要发送“浅”行 。
因此,这种方法比此补丁提供的方法要挑剔得多。