当我的分支领先于 master 5 次提交时,如何在提交中删除太大的文件

Posted

技术标签:

【中文标题】当我的分支领先于 master 5 次提交时,如何在提交中删除太大的文件【英文标题】:How to remove a too large file in a commit when my branch is ahead of master by 5 commits 【发布时间】:2013-11-28 22:24:09 【问题描述】:

我整天都被这个问题困住了,在这里寻找答案:( ...

上下文

我一个人在一个项目上工作,直到现在我都使用 github 来保存我的工作,而不是在我的计算机上。 不幸的是,我在本地存储库中添加了一个非常大的文件:300mb(超过了 Github 的限制)。

我做了什么

我将尝试记录我所做的事情:

    我(愚蠢地)将所有内容添加到索引中:

    git add *
    

    我提交了更改:

    git commit -m "Blablabla"
    

    我试图推送到原始主机

    git push origin master 
    

    花了一点时间,所以我只是CTRL+C,重复步骤2和3四次,直到我意识到一个文件太大而无法推送到github。

    我犯了一个可怕的错误来删除我的大文件(我不记得我是使用 git rm 还是简单的 rm)

    我按照 (https://help.github.com/articles/remove-sensitive-data) 上的说明进行操作

    当我尝试 git filter branch 时,我收到以下错误:“无法重写分支:您有未暂存的更改。”

提前致谢!

【问题讨论】:

Update a development team with rewritten Git repo history, removing big files的可能重复 【参考方案1】:

看来您唯一的问题是进行未分阶段的更改。您没有提供有关实际不同步的任何细节,所以这是在黑暗中拍摄的,但假设您在步骤 4 中简单-rmd 文件,您将从索引中将其带回:

git checkout large_file

如果没有,你就靠自己了。您的目标是确保您的索引和工作树处于相同状态。这显示为 git status 报告没有提交,工作目录干净。

确保树干净的核选项是git reset --hard。如果您想尝试,请事先备份您的树+repo。

一旦你的工作副本是干净的,你可以继续你的步骤 5 和 6。

【讨论】:

感谢您的回答!我rmd 我的大文件然后提交了 4 次......大文件对我来说并不重要。我只是不希望它上传到 github。【参考方案2】:

当您删除文件时,这将是一个更改,这就是 git 抱怨的未分级更改。如果您执行 git status,您应该会看到列为已删除/已删除的文件。要撤消此更改,您应该git checkout -- <filename>。然后文件将返回并且您的分支应该是干净的。您也可以git reset --hard 这将使您的 repo 恢复到您提交的状态。

我假设这是最后一次提交,其中包含您要删除的非常大的文件。你可以做一个git reset HEAD~ 然后你可以重做提交(不添加大文件)。那么您应该可以毫无问题地git push

由于文件不在最后一次提交中,因此您可以毫无问题地完成最后的步骤。您只需要提交或删除您的更改。

http://git-scm.com/book/en/Git-Tools-Rewriting-History

【讨论】:

非常感谢您的回答!问题是,我删除了不在最新提交中的大文件......所以当我发出git status 时,我没有在列表中看到我的大文件...... 您得到的错误是由于未提交的修改,因此您需要git reset --hard 以摆脱这些更改。 好的!我想我应该备份我在这 5 次提交中所做的工作?我是直接发出git reset --hard还是使用git reset --hard origin master 您不需要在 5 次提交中备份任何内容。只要您不删除该信息的存储库。您的问题是您列出了正在更改的文件,这就是git status 向您展示的内容。如果您想保留文件进行另一次提交,如果您不需要更改,那么您可以执行git reset --hard 这将您的存储库的状态设置为您拥有的最新提交。 谢谢!有效 !!!!太感谢了 !只要我有足够的声誉,我就会投票给你的答案:) *【参考方案3】:

github 解决方案非常简洁。我在推送之前做了一些提交,所以很难撤消。 Githubs 解决方案是: 删除旧提交中添加的文件

如果大文件是在较早的提交中添加的,则需要将其从存储库历史记录中删除。最快的方法是使用 BFG(一种更快、更简单的 git-filter-branch 替代方案):

bfg --strip-blobs-bigger-than 50M
# Git history will be cleaned - files in your latest commit will *not* be touched

https://help.github.com/articles/working-with-large-files/

https://rtyley.github.io/bfg-repo-cleaner/

【讨论】:

【参考方案4】:

我使用的一个简单解决方案:

    git reset HEAD^ 尽可能多地撤消您的提交,它会保留您的更改和文件的实际状态,只需刷新它们的提交。

    一旦提交被撤消,您可以然后考虑如何以更好的方式重新提交文件,例如:删除/忽略大文件,然后添加您想要的内容,然后提交再次。或者使用 Git LFS 来跟踪那些巨大的文件。


编辑:如果您的提交需要身份验证(例如:用户名和电子邮件)并且您需要在提交后添加正确的凭据,则此答案也是可以接受的。您可以用同样的方法撤消操作。

问题:有人有办法只挑选不好的提交并直接更改它吗?我特别问的是,如果有人只需要像here 那样重新验证他的提交,但在不需要更改文件的情况下。仅提交进行身份验证。

【讨论】:

很好 - 这是一个非常不错的解决方案!为了速度,我建议在重置后将大文件添加到您的 .gitignore :) 使用 ~n insted of ^ 其中 n 是您领先的提交数,以防它超过一个提交。此外,git 似乎在识别 ^ 时遇到问题,具体取决于本地化,对我来说,它在法语命令提示符下不起作用,所以当它的 2 次提交时,我不得不使用 ~2。 这是一个很酷的答案。我不明白的一件事是^~ 的使用。我发现这篇文章非常有帮助:***.com/questions/2221658/… 对于其他有类似问题的人。【参考方案5】:

这是参考上面的BFG帖子,我会直接评论,但我不知道作为一个低声誉的新用户如何这样做。

您可能需要先执行“git gc”重新打包。

在我这样做之前,我在让 BFG 工作之前遇到了问题,如果您只在本地存储库中工作并且第一次准备将东西放在遥控器上,这似乎是一个常见问题。

相关的谷歌点击让我想到它:https://github.com/rtyley/bfg-repo-cleaner/issues/65

【讨论】:

【参考方案6】:

这对我有用:

    下载并安装 BFG Repo-Cleaner (BFG),可通过 here 获取。我的下载地址是bfg-1.13.0.jar。 将下载的 jar 文件(在我的情况下为 bfg-1.13.0.jar)移动到 $JAVA_HOME/lib 的潜在有用位置。这就是我所做的,因为我希望像这样的Java 特定库位于一个合理的位置,因为它们不像普通的 Windows 安装。您可能希望将 jar 文件简单地重命名为 bfg.jar 以保持简单 - 所以在下面,我使用 bfg.jar,实际上是指 bfg-1.13.0.jar。 运行java -jar $JAVA_HOME/lib/bfg.jar --delete-files <file_name> --no-blob-protection .;您应该将整个 <file_name> 替换为导致问题的特定文件名 - 请注意,文件的路径不是必需的,只有文件名本身。 运行 git reflog expire --expire=now --all && git gc --prune=now --aggressive 完成 BFG 清理工作 最后,运行 git push origin main --force 以完成推送所有未完成的本地提交。 如果您已经成功完成了到目前为止的所有操作,那么您的问题就解决了 今后,如果您希望避免此问题再次发生,请始终检查您是否无意中将目录中的非常大的文件添加到 Git。

【讨论】:

【参考方案7】:

我继续一遍又一遍地遇到这个问题,而且我似乎没有学会不这样做。这里提供的解决方案以前对我有用,但出于某种原因,这次不行,但这是有效的方法(来自https://medium.com/analytics-vidhya/tutorial-removing-large-files-from-git-78dbf4cf83a):

删除大文件

git rm --cached <filename>

然后,编辑提交

git commit --amend -C HEAD

然后你可以推送修改后的提交

git push

【讨论】:

我发现整个文件太大的问题令人困惑。感谢您的解决方案。对我来说,大尺寸来自嵌入在 jupyter 笔记本中的输出。首先必须在您的命令之前清除输出。不要像我一样忘记在git push之前为每个缩小的文件做一个git add &lt;filename&gt;【参考方案8】:

复制最新的 Repo 状态

cp -r original_repo repo_tmp

将原始仓库重置为提交大文件之前的状态

cd original_repo &amp;&amp; git reset --hard commit_before_large_file

从 repo_tmp 中移除 .git,所以我们只获取内容

cd .. &amp;&amp; rm -rf repo_tmp/.git

复制并替换 repo_tmp(最新的 repo 状态)到 original_repo 文件夹

cp -r repo_tmp original_repo

现在添加、提交和推送,一切顺利

git add . &amp;&amp; git commit -m "be gone large file" &amp;&amp; git push

【讨论】:

以上是关于当我的分支领先于 master 5 次提交时,如何在提交中删除太大的文件的主要内容,如果未能解决你的问题,请参考以下文章

当我尝试从终端更新分支时,会出现一个新窗口。如何进行?

如何围绕失败的合并分叉两个git分支

合并到 master 后,如何检查来自哪个分支的哪些提交以及从何处删除的合并?

github怎样清除历史提交,保留最新提交

Linux------Git-5

在重新提交许多提交时如何防止许多 git 冲突?