Git推送拉取孤立分支时推送全部Pack对象的解决方法咨询
解决方案
问题根源
你当前的操作每次都会生成完全独立的全新提交(通过孤儿分支),该提交与仓库中所有旧对象无任何关联,Git无法识别两端共享的对象来做增量传输,因此只能全量打包所有相关对象。
优化后的操作流程
1. 首次迁移(仅执行一次)
首次将repo1转为无历史单提交仓库并推送到bare仓库时,首次全量传输是正常且无法避免的(两端无共享对象),流程如下:
# repo1 操作:创建无历史分支并完成初始提交 repo1> git checkout --orphan tmp repo1> git add . repo1> git commit -m "initial single commit" # 替换原master分支 repo1> git branch -D master repo1> git branch -m master # 清理本地无用对象 repo1> git reflog expire --expire-unreachable=now --all repo1> git gc --prune=now # 推送到bare仓库 repo1> git push --force <bare.git> master # bare仓库清理无用对象 bare.git> git reflog expire --expire-unreachable=now --all bare.git> git gc --prune=now # repo2 拉取内容 repo2> git fetch --force <bare.git> master repo2> git reset --hard FETCH_HEAD repo2> git reflog expire --expire-unreachable=now --all repo2> git gc --prune=now
2. 后续更新(实现增量传输)
后续需要更新内容时,禁止重复创建孤儿分支,直接在现有master分支上修改,通过提交覆盖的方式保留对象关联,让Git自动实现增量传输:
# repo1 中修改内容后 repo1> git add . # 用--amend覆盖当前提交,保留与旧提交的对象关联 repo1> git commit --amend --no-edit # 强制推送到bare仓库(仅传输变更的对象) repo1> git push --force <bare.git> master # bare仓库定期清理(无需每次推送都执行) bare.git> git reflog expire --expire-unreachable=now --all bare.git> git gc --prune=now # repo2 更新内容(仅拉取变更对象) repo2> git fetch --force <bare.git> master repo2> git reset --hard FETCH_HEAD
关键说明
- 首次全量传输是必然的,因为两端初始无任何共享对象。
git commit --amend的核心作用是让新提交与旧提交共享未变更的文件对象,Git可通过对比差异实现增量传输。- 频繁创建新孤儿分支会破坏对象关联,导致每次都触发全量传输,需避免该操作。
内容的提问来源于stack exchange,提问作者geek175
相关产品推荐
相关产品推荐

