简体   繁体   English

具有大文件的 Git 工作流程

[英]Git workflow with large files

I know this has been asked and discussed earlier, but I couldn´t find the right workflow for this problem.我知道之前有人问过并讨论过这个问题,但我找不到解决这个问题的正确工作流程。

Let´s say I´m working on a new project that I want to push to GitHub.假设我正在开发一个我想推送到 GitHub 的新项目。 After a few commits and pushes that worked well, I continue coding and editing and at some point I add some big files larger than 100MB to my project (without knowing or keeping in mind that this will cause problems when I will try to push it in the next step).经过几次运行良好的提交和推送后,我继续编码和编辑,并在某些时候将一些大于 100MB 的大文件添加到我的项目中(不知道或记住这会在我尝试推送时导致问题)下一步)。

So I do:所以我这样做:

git add . 

and after that I do:之后我做:

git commit -m 'some commit message'

and finally:最后:

git push

And now I am in trouble, because I get the remote error: Large files detected.现在我遇到了麻烦,因为我收到远程错误:检测到大文件。

So what are my options here to 1. keep my project changes and my added files alive and 2. exclude the big files files from future commits.那么我在这里有什么选择 1. 保持我的项目更改和我添加的文件处于活动状态 2. 从未来的提交中排除大文件文件。

I have found the command to delete the last commit (where I added the big files among other things) with git revert … , but this is not want I want, because it also deletes all the work from my working directory.我找到了使用git revert …删除最后一次提交(我在其中添加了大文件等)的命令,但这不是我想要的,因为它还会从我的工作目录中删除所有工作。

For your immediate problem, you want to rebase/edit:对于您当前的问题,您想重新定位/编辑:

git rebase -i HEAD~1

Where "1" is the number of commits back your bigass commit is.其中“1”是您的 bigass 提交的提交次数。 For example, for 3 commits back, I might get an $EDITOR interface like:例如,对于 3 次提交,我可能会得到一个 $EDITOR 接口,例如:

pick d187a63 Some bigass file and other stuff
pick d1dff5c Use https for remote service
pick e8a29cd Add honeybadger

# Rebase e99b72e..c564a67 onto e99b72e (       3 TODO item(s))
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.

By manipulating the non-comment lines, git will apply corresponding manipulations to your commits.通过操作非注释行,git 将对您的提交应用相应的操作。 In your case, you want to change "pick" to "edit" for the bigass commit.在您的情况下,您希望将 bigass 提交的“pick”更改为“edit”。 Then you will be back on the command-line in a mid-rebase state where you can:然后,您将返回到处于中间变基状态的命令行,您可以:

git rm bigass.file              # remove the file from the commit 
git commit good.file other.file # make additional commit(s) w/ just the stuff you want
git rebase --continue           # wrap up rebase

To wrap up, account for all the uncommitted files (by removal, exclusion or inclusion) and git rebase --continue .最后,考虑所有未提交的文件(通过删除、排除或包含)和git rebase --continue

NOTE: You can also ignore generated files locally without affecting .gitignore , using .git/info/exclude .注意:您还可以使用.git/info/exclude在不影响.gitignore情况下忽略本地生成的文件。 You can use the same entries there that you would use in .gitignore , but they will never get pushed to remote or overwritten.您可以在那里使用您在.gitignore使用的相同条目,但它们永远不会被推送到远程或覆盖。 Beware: this can make you crazy if you ignore something incorrectly or forget about what you are ignoring!当心:如果您错误地忽略了某些内容或忘记了您忽略的内容,这会让您发疯!

More broadly, if you do intend to version large files, you may be interested to amend your workflow to use git-lfs (Large File Storage), addressing this exact problem.更广泛地说,如果您确实打算对大文件进行版本控制,您可能有兴趣修改您的工作流程以使用git-lfs (大文件存储)来解决这个确切的问题。 It stores content hash/pointers in git proper and the massive binaries in a cloud datastore.它将内容哈希/指针存储在 git 中,并将大量二进制文件存储在云数据存储中。 It has support from Github and Microsoft VSO (including free unlimited storage), among others.它得到了GithubMicrosoft VSO (包括免费无限存储)等的支持。

As I understand it, the last commit has a combination of changes plus one large file.据我了解,最后一次提交包含更改和一个大文件的组合。 If you revert that commit, that may make it look like the large file is gone, but its still present in the history.如果您恢复该提交,可能会使大文件看起来像消失了,但它仍然存在于历史记录中。 So if you pushed, you might still have a problem.所以如果你推,你可能仍然有问题。 If you want to remove the large file from your history but keep your other changes in that commit, you might do an interactive rebase of that last commit and edit it to remove the big file.如果您想从历史记录中删除大文件,但在该提交中保留其他更改,您可以对上次提交进行交互式 rebase 并编辑它以删除大文件。

This achieves the same effect as Joe A's answer except its a lot simpler and in my view it's a lot safer for someone unfamiliar with the area.这实现了与 Joe A 的答案相同的效果,除了它更简单,而且在我看来,对于不熟悉该地区的人来说,它更安全。

git reset --soft HEAD~
This will undo the commit but leave all the things that would have been committed as staged.这将撤消提交,但将所有本应提交的内容保留为暂存状态。
Then git rm the files that shouldn't have been committed and then re-commit.然后git rm不应该提交的文件,然后重新提交。
Now you should be able to push.现在你应该可以推送了。

Note there is nothing technically wrong with Joe's answer and I have upvoted it;请注意,Joe 的回答在技术上没有任何问题,我已经赞成; it's just overkill and overly complicated for such a simple problem.对于这样一个简单的问题来说,这只是矫枉过正,而且过于复杂。 However if your commit chain included n>1 commits Joe's answer would be your best option.但是,如果您的提交链包含 n>1 次提交,Joe 的答案将是您的最佳选择。 So this is more like a special case where you can do somethign safer since it was just your last operation that was problematic.所以这更像是一种特殊情况,你可以做一些更安全的事情,因为这只是你的最后一次操作有问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM