【发布时间】:2011-05-09 22:53:22
【问题描述】:
我偶尔会使用昂贵的 Internet 连接,我想知道(至少大约)有多少数据将通过git push 推送到远程。
【问题讨论】:
-
这似乎很棘手...推送是压缩的,所以要真正知道,您可能希望在它创建包之后但在它发送之前中断。您可以尝试检查相应捆绑包的大小,但这意味着有效打包两次。
我偶尔会使用昂贵的 Internet 连接,我想知道(至少大约)有多少数据将通过git push 推送到远程。
【问题讨论】:
您可以通过运行与 Git 在创建要推送的包文件时将在内部运行的内容类似的 Bash 来准确地找到答案:
$ echo $(git merge-base HEAD origin/master)..HEAD | git pack-objects --revs --thin --stdout -q | wc -c
这应该输出 Git 将发送的包文件的字节数。细分:
# Find the common ancestor of HEAD and origin/master, and output a
# revision range (<a>..<b>) string to git pack-objects.
echo $(git merge-base HEAD origin/master)..HEAD
# Generate the pack file containing the revision range specified above, writing
# it to stdout.
git pack-objects --revs --thin --stdout -q
# Print the byte count of the file contents passed via stdin.
wc -c
这是在您推送之前执行git fetch 的条件;如果不这样做,Git 将无法找到共同祖先,并将发送整个存储库的内容。请参阅this answer 了解更多信息。
【讨论】:
实际上,我认为我很喜欢我的评论,可以将其发布为答案!
当你推送时,git 会创建一个包含所有必要对象的包并将其上传到远程。这意味着我们正在寻找一种预测包装大小的方法。由于包是压缩的,因此很难根据差异或对象大小做任何事情;我们真正想做的就是看看那个包有多大。如果您可以在构建包之后中断推送,并根据包大小决定继续进行,那将是很好的,但我认为这是不可能的。我最好的猜测是尝试重新创建将被推送的包并检查它。
捆绑文件基本上是一个带有标头信息的包(如果您愿意,请查看the source)。这意味着它是一个方便的瓷器命令,可以创建一个您关心的大小的文件。 (比尝试手动使用 pack-objects 容易得多。)使用这样的东西:
git bundle create foo.bundle ^origin/master master
这将为您提供一个包含获取 master 所需的所有内容的包,因为遥控器具有 origin/master - 与 git push origin master 应该推送的内容完全相同。如果您有其他要推动的分支,您也可以添加它们;它只是采用 rev-list args:
git bundle create foo.bundle ^origin/master master ^origin/topic topic ...
只需检查创建的包的大小;它应该几乎等同于你最终会推动的东西。这确实意味着您最终将不得不创建两次包(一次使用捆绑包,一次使用推送),但除非这是一个非常大的推送,需要很长时间才能打包,否则这不应该是大问题。
【讨论】:
git 不知道您的分支的远程跟踪分支已被删除时,捆绑文件大小和git push origin master 的大小之间会出现奇怪的差异。推送将起作用,但似乎提交了该分支中每个提交的副本。要解决此问题,请通过git fetch -p 让git 知道已删除的远程分支,然后重复git push origin master。