推动变化导致巨大的物体推动

时间:2013-10-30 17:20:35

标签: git

我有一个奇怪的问题,当我试图将更改从我的本地存储库推送到远程存储库时,有时(并且它发生了很多),git就像现有的分支无法识别并且它试图推送所有对象(其中20.000+),甚至我只对它们中的2个进行了更改,并且来自状态0000000000000000000000000000000000000000

样品:

me@my-desktop:~/repo/project/$ git push origin feature/myFeature 
Fetching remote heads...
  refs/
  refs/tags/
  refs/heads/
  refs/heads/feature/
updating 'refs/heads/feature/myFeature'
  from 0000000000000000000000000000000000000000
  to   161612d12a7a474fda294036e34c268131dbcb04
    sending 21322 objects

更新:我使用git flow和功能进行分支。

2 个答案:

答案 0 :(得分:1)

假设你正在使用http推送(使用DAV),我在git sources中的http-push.c中注意到以下内容:

/*
 * NEEDSWORK: remote_ls() ignores info/refs on the remote side.  But it
 * should _only_ heed the information from that file, instead of trying to
 * determine the refs from the remote file system (badly: it does not even
 * know about packed-refs).
 */

如果这个评论是准确的,问题是遥控器已打包目标引用,并且(如注释所述)推送无法找到引用,因此它发送每个对象。

因此,正如评论中提到的Matija Nalis一样,接收方的git gc导致了问题。你可以通过在接收器上重新创建解压缩的参考来测试这个:

cd (path to repo .git directory)
(verify that refs/heads/branch does not exist)
awk '$2 == "refs/heads/branch" { print $1 }' packed-refs

(将结果行写成refs/heads/branch,假设有一行,然后尝试推送)。

由于我不使用网络推送,我无法自行验证。

答案 1 :(得分:0)

该错误应在Git 2.28(2020年第三季度)中修复:由于“对象标志位分配不正确”,用于推动“哑” HTTP上的更改的代码与提交可达性代码的交互不良,该问题已得到纠正。

请参见commit 64472d1brian m. carlson (bk2204)(2020年6月23日)。
(由Junio C Hamano -- gitster --commit 67d99b8中合并,2020年7月6日)

http-push:确保在数据丢失时未强制执行的推送失败

报告人:迈克尔·沃德
签名人:RenéScharfe
签字人:布莱恩·米。卡尔森

当我们使用DAV-based protocol进行推送时,客户端是执行ref更新的客户端,因此进行检查以查看是否应允许非强制推送。

我们通过确定是否进行此项检查

  • (a)我们缺少ref或
  • 的旧值的目标文件
  • (b)引用的新值不比旧值新,

无论哪种情况,都拒绝推送。

但是,执行后一项检查的ref_newer函数由于某些对象标志的重用而具有奇怪的行为。

具体地说,它将在第一次调用时错误地返回false,然后在后续调用中正确地返回true。

之所以会发生这种情况,是因为http-push.c使用的对象标志与实现ref_newer,的{​​{3}}使用的对象标志相同,并且一段代码会误解另一段代码设置的标志。 / p>

请注意,并非在所有情况下都如此。

例如,如果将测试中使用的示例更改为使用一个存储库而不是两个存储库,然后倒回头部以添加提交,则测试通过,我们正确拒绝了推送。

但是,提供的示例确实触发了此行为,并且至少从Git 2.0.0开始,这种方式的代码已被破坏。

要解决此问题,让我们移动两组对象标志,以使它们不重叠,因为我们清楚地同时使用了它们。新集不应与其他用法冲突,因为其他用户要么是内置代码(没有编译到commit-reach.c中),要么是upload-pack(我们在这里同样不使用)。