【问题标题】:git tree (still) contains duplicates and an erroneous signal 13git 树(仍然)包含重复项和错误信号 13
【发布时间】:2014-05-20 21:13:29
【问题描述】:

我有一个 git 存储库,它是这样构建的。

$ git init

在多次添加、提交和疯狂敲击键盘之后,我准备将其推送到我的 GitHub 存储库。

$ git remote add origin git@github.com:me/Foo.git
$ git push -u origin master
Counting objects: 456, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (125/125), done.
remote: error: object c9edb23c0e6c48772785b2a7d89d08c0807b2d4a:contains duplicate file     entries
remote: fatal: Error in object
error: pack-objects died of signal 13
error: failed to push some refs to 'git@github.com:me/Foo.git'

搜索 SO,我找到了文章 git tree contains duplicate file entries 并按照那里的说明进行操作。

$ git ls-tree c9edb > bad_tree.txt

删除重复条目(只有 1 个!)

$ cat bad_tree.txt | git mktree
8ec5fe5a729ff6f71209cb9a4f75b0059c049190
$ git replace c9edb 8ec5f
$ git fsck --full
Checking object directories: 100% (256/256), done.
error in tree c9edb23c0e6c48772785b2a7d89d08c0807b2d4a: contains duplicate file entries
Checking objects: 100% (457/457), done.

好的,文章说 fsck 仍然会显示坏树,但是 push 现在应该可以工作了。让我们修复信号 13. SO 文章Can't push to GitHub error: pack-objects died of signal 13 说这是文件大小的问题。好的,让我们看看这个。

$ git count-objects -v
count: 0
size: 0
in-pack: 457
packs: 1
size-pack: 1910
prune-packable: 0
garbage: 0
size-garbage: 0

嗯,这很奇怪。它说它只有1.9MB。让我们仔细检查一下。

$ du -h .git
8.0K    .git/logs/refs/heads
12K     .git/logs/refs
24K     .git/logs
1.9M    .git/objects/pack
8.0K    .git/objects/info
1.9M    .git/objects
44K     .git/hooks
4.0K    .git/branches
12K     .git/info
4.0K    .git/refs/heads
4.0K    .git/refs/tags
4.0K    .git/refs/replace
16K     .git/refs
2.1M    .git

好吧,有些疯狂。 Git 和文件系统同意整个存储库只有 ~2MB,但我在推送时收到了 signal-13。唔。让我们再试一次。

$ git push -u origin master
Counting objects: 456, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (125/125), done.
remote: error: object c9edb23c0e6c48772785b2a7d89d08c0807b2d4a:contains duplicate file     entries
remote: fatal: Error in object
fatal: The remote end hung up unexpectedly
error: pack-objects died of signal 13
error: failed to push some refs to 'git@github.com:me/Foo.git'

Grr。确实是“来自地狱的内容管理员”。我的回购协议是不是很糟糕?有没有可能在没有历史记录的情况下只推送最后一次提交到 github? (最好不要让我的本地仓库成为另一个本地仓库的远程仓库并复制粘贴整个内容)。

【问题讨论】:

  • 所以从技术上讲,我不应该说这样的话,因为它并没有真正增加问题本身,而是 +1 做得很好,首先做自己的研究,并给予您已经尝试过的详细说明。
  • 我在链接的文章中找不到可以推送不良历史记录的地方,git replace docs 说它不适用于包传输(包是pack-objects 的输出) .
  • @jthill,你说得对。我在文档页面中没有看到。 filter-branch 中似乎也存在一个错误(无论是在代码中还是在文档中),因为文档说 filter-branch 将使所有 ref 替换永久化,但事实并非如此。
  • @Cupcake,谢谢!我只是想让它可读且易于理解。
  • @Tim 你知道你可以回答你自己的问题,对吧?

标签: git github


【解决方案1】:

相当偶然,我碰巧在阅读 O'Reilly Git book 并发现了一个使用 git branch-filter 的巧妙小技巧。我应该注意到duplicate entry 错误是由于在一次提交中将子文件夹作为目录和符号链接添加到索引中(我不会再这样做了!)。

$ git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch src/dupe' master

即使我们刚刚从轨道上删除了那个子目录,坏 blob 仍然在 repo 中。

$ git fsck
Checking object directories: 100% (256/256), done.
error in tree c9edb23c0e6c48772785b2a7d89d08c0807b2d4a: contains duplicate file entries
Checking objects: 100% (457/457), done.

看起来 git 不想放弃那个 blob!这很容易解决。仅通过克隆 repo 就可以(最安全地)处理悬空的 blob。

$ cd ~/Foo_new
$ git clone --no-hardlinks file://~/Foo

--no-hardlinks 选项可防止 git 使用硬链接优化克隆,并确保克隆的存储库包含旧存储库中所有内容的副本,因此您可以安全地删除旧存储库。快速检查显示现在一切正常。

$ git fsck --full
Checking object directories: 100% (256/256), done.
Checking objects: 100% (433/433), done.

现在我需要重置我的遥控器,因为这是一个克隆的 repo。

$ git remote set-url origin git@github.com:me/Foo.git

然后推送到 github。

$ git push origin master
Counting objects: 433, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (115/115), done.
Writing objects: 100% (433/433), 471.04 KiB | 0 bytes/s, done.
Total 433 (delta 318), reused 433 (delta 318)
To git@github.com:me/Foo.git
 * [new branch]      master -> master

成功了!

【讨论】:

    【解决方案2】:

    我今天也遇到了同样的问题,在尝试了上述很多方法之后,我最终没有“关心”历史本身,而是决定将历史压缩到一个提交中。

    例如手头的情况:

    • 分支主机坏了;
      • 尝试推送时出现错误 13
      • 这发生在大约 10-15 次提交后
    • branch origin/master 无法接收新的更新

    然后我执行了以下简单的步骤:

    • git checkout master
    • git 分支 master_maintained_for_old_history
    • git reset origin/master --soft
    • git commit -a -m 'a single squash commit ...'
    • git push -u origin master -f

    当尝试进行交互式变基时,这失败了,因为它仍在尝试“重用”现有的“损坏”提交来重播,从而导致问题再次发生。 这种简单地放弃所有破碎的历史并进行一次提交的解决方案最终对我来说是最干净的。

    干杯, 抢

    【讨论】:

      猜你喜欢
      • 2011-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-25
      • 2019-05-13
      相关资源
      最近更新 更多