如何确定写入我的远程git存储库需要这么长时间的文件?

时间:2016-12-29 21:01:32

标签: git repository push commit

我在Mac Sierra上使用Git 2.8。当我尝试将本地存储库推送到远程时,我遇到了问题。这需要很长时间。我认为这是因为它试图推送一个我必须无意中签入的非常大的文件。这就是当我尝试推送内容时会发生的事情。它只是挂起,然后我必须按Ctrl + C。

On branch master
Your branch is ahead of 'origin/master' by 62 commits.
  (use "git push" to publish your local commits)
nothing to commit, working directory clean
Counting objects: 609, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (608/608), done.
Writing objects:  20% (124/609), 33.04 MiB | 1.03 MiB/s 
localhost:myproject nataliab$ Killed by signal 2.

如何确定导致挂断的文件/文件是什么?我尝试了“git status”,但它没有告诉我任何事情......

localhost:myproject nataliab$ git status
On branch master
Your branch is ahead of 'origin/master' by 62 commits.
  (use "git push" to publish your local commits)
nothing to commit, working directory clean

感谢您的帮助, -

2 个答案:

答案 0 :(得分:0)

听起来您已将构建的二进制文件添加到Git存储库中。 在macOS中,您可以在Finder中搜索时设置高级过滤选项:

1。)打开Finder并转到存储库

2.单击“搜索”或按Command + F,然后将“此Mac”中的搜索位置更改为实际文件夹

3。)点击“种类”过滤器并选择“其他”,然后从属性列表中选择“文件大小”

4.单击第二个过滤器并选择“大于”

5.)在第三个空格中,输入大小以搜索大于(例如:500KB或1MB)的任何内容,并选择KB或MB作为最终过滤器

enter image description here

答案 1 :(得分:0)

TL; DR:做一个交互式rebase并用更好的提交替换你的坏提交,或使用BFG(见How to remove/delete a large file from commit history in Git repository?)。

Git推送提交,而不是文件

在Git中,每次提交都是永久性的,不可更改的。此外,提交历史记录:您的最新提交指向您的第二次提交,指向您的第三次提交,依此类推,一直回到第一次提交。

现在假设您提交了一个大文件(例如DVD图像,4.7 GB左右)。稍后,您删除该文件并再次提交。

当你转到git push生成的提交时,Git将 >该文件,以及创建文件的提交。

如果Git没有这样做,您将无法回想起包含大文件的提交。 Git的重点是能够回忆每次提交,所以这与版本控制相反。如果Git只发送了你的最新信息,那将是不受控制的转换。

文件是提交的副作用。 Git就是提交。档案只是偶然的奖金。当然,文件首先是提交的目的,但Git仍然是提交。

这对您意味着什么

您的大文件位于您拥有的提交中,他们不会:

localhost:myproject nataliab$ git status
On branch master
Your branch is ahead of 'origin/master' by 62 commits.
  (use "git push" to publish your local commits)
nothing to commit, working directory clean

在这62个(可能是 1 )提交的某个地方,你添加了一些大文件。在某个地方以后,你可能会删除它们 - 但是Git必须推送所有提交。

此外,提交是永久性的,不可更改的。您无法更改添加文件的旧提交。这只留下了一个可能的解决方案:根本不推动这些提交

你可能 - 也应该,真的 - 反对。大概你想要推送(至少一些)这些提交。但我告诉你的是,你不想推送这些提交。您希望推送一些稍微改动的更好的提交。

1 "可能",因为origin/master是你Git对名称master下的内容的记忆origin处的其他 Git存储库。此内存并非始终是最新的。你可以运行git fetch origin来获取它们的最新提交,从而让你的Git更新它的内存。但如果你是唯一一个使用其他存储库的人,你的Git内存就足够准确了。

复制"坏"致力于新的,不同的,更好的"提交

使用git log查看您当前正在推送的提交:

$ git log --name-status origin/master..master

--name-status参数告诉Git将每次提交与之前的提交进行比较(像往常一样),但不是显示完整的git diff,而只显示添加,修改和删除的文件。

您将有一个提交删除一些大文件,然后是一个早期提交,添加相同的大文件。您现在的工作是更正先前的提交,以便它根本不添加这些文件。

您实际上更改之前的提交!但是你可以 复制它到一个非常相似的提交:做一个几乎完全相同的提交,除了它没有添加大文件(S)。您所做的新提交将具有相同的父ID - 这就是Git在其他提交之前跟踪哪些提交的方式。它将具有相同的作者(您),相同的提交者(您),相同的日志消息,甚至可能是相同的日期......但它不会拥有大文件。

作为将此特定错误提交复制到新的更好提交的副作用,您将被迫复制每次后续提交。原因是每个提交都记录其先前(父)提交ID,并且新的和改进的复制提交将具有不同的父提交。所以现在你需要复制它的孩子。新的儿童副本"与前一个子项相同,除了两件事:父ID,以及大文件消失的事实。

对于删除大文件的每次提交都会重复此操作。现在, if 特定提交只是删除大文件,此时您可以放弃该提交:到目前为止您所制作的每个副本都缺少这些文件无论如何,所以没有什么可做的。但是,如果该提交除了删除大文件之外还会执行某些操作,那么您可能会想要保留其他部分。

在那之后,您可能只想复制每个剩余的提交,只更改其父ID。

有两种Git命令可以执行此类提交复制: git filter-branchgit rebase -i。前者有点难以使用,所以如果你要坚持使用Git附带的东西,我通常建议使用rebase,除非你需要复制的那些提交中有合并提交(任何这样的合并都会显示在git log输出中。

使用filter-branchrebase -i的说明位于上述链接问题的Greg Bacon's linked answer

虽然我从未使用过BFG,但据报道它的操作要简单得多。它没有像filter-branch和交互式rebase那样多的东西,所以它没有这么复杂的控件。但它仍然复制提交。

一旦提交全部被复制,你只需要忘记"坏的

Git分支的工作方式是名称master,只是指向分支master上的最新提交。每个提交都指向其早期的对应方。所以一旦你复制了'#34; bad"承诺更好的"那些,您的master将指向最新的复制提交。该提交指向其父级,依此类推,无论多少 - 可能是61,现在提交到达origin/master点所需的位置。

origin上的另一个Git存储库已经具有该提交以及每个早期提交。但现在你可以git push origin master,你的Git会调用他们的Git,找到推送的提交,并开始推送 - 推送的将是新的,更好的副本,而不是原件。

(原件会发生什么?最终,它们会老化并过期并删除。如果你想要它们,你至少有30天的时间让它们回来。)