我想知道当它推动变化时git正在做什么,以及为什么它似乎偶尔会推动更多的数据而不是我所做的更改.我对两个增加了大约100行代码的文件进行了一些更改 - 不到2k的文本,我想.
当我将数据推送到原点时,git将其转换为超过47mb的数据:
git push -u origin foo
Counting objects: 9195, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (6624/6624), done.
Writing objects: 100% (9195/9195), 47.08 MiB | 1.15 MiB/s, done.
Total 9195 (delta 5411), reused 6059 (delta 2357)
remote: Analyzing objects... (9195/9195) (50599 ms)
remote: Storing packfile... done (5560 ms)
remote: Storing index... done (15597 ms)
To <<redacted>>
* [new branch] foo -> foo
Branch foo set up to track remote branch foo from origin.
Run Code Online (Sandbox Code Playgroud)
当我区分我的更改时,(origin/master..HEAD)只显示了两个文件和一个提交.47mb的数据来自哪里?
我看到了这个:当我做"git push"时,统计数据意味着什么?(总计,delta等) 和这个:预测git push中将推送多少数据, 但这并没有真正告诉我发生了什么...为什么包/捆绑会很大?
我刚刚意识到存在非常现实的情况会导致非常大的推动.
推送什么对象发送?服务器上尚不存在.或者,而不是它现有的检测.它如何检查对象的存在?在推送开始时,服务器发送有的引用(分支和标签).因此,例如,如果他们有以下提交:
CLIENT SERVER
(foo) -----------> aaaaa1
|
(origin/master) -> aaaaa0 (master) -> aaaaa0
| |
... ...
Run Code Online (Sandbox Code Playgroud)
然后客户端将获得类似的东西/refs/heads/master aaaaa0
,并发现它必须只发送提交中的新内容aaaaa1
.
但是,如果有人向远程主人推送任何东西,那就不同了:
CLIENT SERVER
(foo) -----------> aaaaa1 (master) --> aaaaa2
| /
(origin/master) -> aaaaa0 aaaaa0
| |
... ...
Run Code Online (Sandbox Code Playgroud)
在这里,客户端获取refs/heads/master aaaaa2
,但它对aaaaa2一无所知,因此无法推断出aaaaa0
服务器上存在的内容.因此,在仅有2个分支的简单情况下,将发送整个历史记录而不是仅增量历史记录.
这不太可能发生在成长,积极开发,项目,其中有标签和许多分支,其中一些变得陈旧,不会更新.因此,用户可能会发送更多信息,但它并没有像您的情况那样变得那么大,并且没有任何损失.但是在非常小的团队中,它可以更频繁地发生,并且差异将是显着的.
为避免这种情况,您可以git fetch
在推送之前运行.然后,在我的示例中,aaaaa2
提交已经存在于客户端,git push foo
并且知道它不应该发送aaaaa0
和更早的历史记录.
请阅读此处了解协议中的推送实现.
PS:最近的git commit graph功能可能对它有所帮助,但我还没试过.
当我将这些数据推送到原始位置时,git 将其转换为超过 47mb 的数据。
看起来您的存储库包含大量二进制数据。
git-push
- 更新远程引用以及关联的对象
associated objects
?每次提交后,您都会将pack
数据执行 git 到名为
XX.pack
&& `XX.idx'的文件中
关于包装的好读物就在这里
打包的存档格式
.pack
被设计为独立的,因此可以在没有任何进一步信息的情况下解包。
因此,增量所依赖的每个对象都必须存在于包中。生成包索引文件
.idx
是为了快速、随机地访问包中的对象。将索引文件
.idx
和打包存档放在的子目录(或 上的任何目录).pack
中,Git 就可以从打包存档中读取数据。pack
$GIT_OBJECT_DIRECTORY
$GIT_ALTERNATE_OBJECT_DIRECTORIES
当 git 打包你的文件时,它会以一种智能的方式进行,因此提取数据会非常快。
为了实现这一目标,git 使用pack-heuristics,它基本上是在你的包中寻找相似的内容部分并将它们存储为单个内容,这意味着 - 如果你在许多文件中具有相同的标头(例如许可协议),git 将“找到”它并将存储它一次。
现在,包含此许可证的所有文件都将包含指向标头代码的指针。在这种情况下,git 不必一遍又一遍地存储相同的代码,因此包大小最小。
这就是为什么在 git 中存储二进制文件不是一个好主意且不建议的原因之一,因为相似性的机会非常低,因此包大小不会是最佳的。
Git 以压缩格式存储数据以减少空间,因此二进制文件在压缩(大小为 wize)时也不是最佳选择。
以下是使用 zipped 压缩的 git blob 示例:
归档时间: |
|
查看次数: |
955 次 |
最近记录: |