简体   繁体   English

我可以返回并从以前的 git 提交中删除特定文件吗?

[英]Can I go back and remove particular files from previous git commits?

I have 5 files in my project.我的项目中有 5 个文件。 I've done 10 commits, and in each commit, I modified and staged each file.我已经完成了 10 次提交,在每次提交中,我修改并暂存了每个文件。 Is it possible to change each of those commits to include all but the first of those 5 files?是否可以更改每个提交以包含这 5 个文件中的第一个之外的所有文件?

Yes, it is more than possible.是的,这是不可能的。 I'll give you four ways to rewrite history to remove a file from it...我会给你四种重写历史记录的方法,以从中删除文件......

⚠️ If you need to eliminate a file from git history for security reasons, you should instead follow the steps in Remove sensitive files and their commits from Git history . ⚠️ 如果出于安全原因需要从 git 历史记录中删除文件,则应按照从 Git 历史记录删除敏感文件及其提交中的步骤操作。

interactive rebase交互式变基

If you're not yet a git pro, I recommend that you use this method, even though there are more manual steps.如果您还不是 git pro,我建议您使用此方法,即使有更多手动步骤。

Since you want to rewrite 10 commits, you can do this:既然你想重写 10 个提交,你可以这样做:

git rebase -i HEAD~10

This will open up a "todo list" that will list commits starting from HEAD~10 , which will be the last 10 commits.这将打开一个“待办事项列表”,它将列出从HEAD~10开始的提交,这将是最后 10 次提交。 If you leave the file as is and close it, git rebase will replay those 10 commits in the order shown, and nothing will have changed.如果您保留文件并关闭它, git rebase将按照显示的顺序重放这 10 次提交,并且不会有任何更改。 But by editing the todo list, you have total control over what happens.但是通过编辑待办事项列表,您可以完全控制发生的事情。 You can reorder any line and thus reorder the commits.您可以重新排序任何行,从而重新排序提交。 You can delete a line or replace pick with skip to skip a commit.您可以删除一行或用skip替换pickskip提交。 Or you can replace "pick" with another instruction.或者您可以用另一条指令替换“pick”。 All this is explained in the todo file itself, so you don't have to memorize all the options.所有这些都在 todo 文件本身中进行了解释,因此您不必记住所有选项。

In your case, you want to amend each commit to remove the one file.在您的情况下,您希望修改每个提交以删除一个文件。 Replace each pick with edit or just e .edit或只是e替换每个pick Close the file.关闭文件。 Git rebase will then replay those commits, but will stop after each one and allow you to amend it. Git rebase 然后会重放这些提交,但会在每次提交后停止并允许您修改它。

On the first one you will git rm the file you want removed, and then git commit --amend .在第一个上,您将git rm要删除的文件,然后git commit --amend The new first commit will no longer include the file.新的第一次提交将不再包含该文件。 You can now move on to the next one.您现在可以继续下一个。

ℹ️ During an interactive rebase, you can always type git status and it will show you the current state of your rebase, and give you hints about what you probably want to do next. ℹ️ 在交互式 rebase 期间,您始终可以输入git status ,它会向您显示 rebase 的当前状态,并提示您下一步可能想要做什么。

To move on to the next commit: git rebase --continue .继续下一次提交: git rebase --continue Rebase will try to replay the next commit but will stop because of a conflict: On your new rewritten branch the file does not exist anymore, but on the second commit that is being replay, the file got modified. Rebase 将尝试重放下一次提交,但会因冲突而停止:在您的新重写分支上,该文件不再存在,但在正在重放的第二次提交中,该文件已被修改。

You resolve the conflict in this case by just deleting the file again and then git add .在这种情况下,您只需再次删除文件然后git add .解决冲突git add . to update the staging index with this chosen conflict resolution.使用此选择的冲突解决方法更新暂存索引。 Then git rebase --continue to tell rebase to retry committing the second commit and then move on to the third.然后git rebase --continue告诉 rebase 重试提交第二次提交,然后继续进行第三次提交。

ℹ️ If at any time you think you've made a mistake, or change your mind, run git rebase --abort and everything will be restored to where you were before. ℹ️ 如果在任何时候您认为自己犯了错误,或者改变了主意,请运行git rebase --abort ,一切都会恢复到您之前的状态。

The same conflict will happen again for all the remaining commits, and you do the same thing for all of them:对于所有剩余的提交,相同的冲突将再次发生,并且您对所有提交都执行相同的操作:

  • delete the file删除文件
  • git add . to record your resolution记录你的决心
  • git rebase --continue to move on. git rebase --continue继续前进。

When the rebase is done, your current branch HEAD will now point to a new series of 10 commits without the file you wanted removed.当 rebase 完成后,您当前的分支HEAD现在将指向一个新的 10 个提交系列,而没有您想要删除的文件。 The original commits will still exist, but if no refs are pointing to them they will eventually get pruned from the git database.原始提交仍然存在,但如果没有引用指向它们,它们最终将从 git 数据库中删除。

squash the 10 commits into one commit without the file将 10 个提交压缩为一个没有文件的提交

You can skip having to amend 10 commits if you squash them into 1. If you don't need the history to reflect 10 separate edits, if you don't care if the history just had one commit with all the combined changes, then this is the ticket for you:如果您将 10 个提交压缩为 1,则可以跳过修改它们。如果您不需要历史记录来反映 10 个单独的编辑,如果您不关心历史是否只有一个包含所有组合更改的提交,那么这个是给你的票:

git reset HEAD~10

This will move HEAD of the current branch back 10 commits.这会将当前分支的HEAD移回 10 个提交。 All the changes you made in those 10 commits will still be in the worktree, but no longer commited into git.您在这 10 次提交中所做的所有更改仍将在工作树中,但不再提交到 git 中。 You can now delete the file you don't want and git add .您现在可以删除不需要的文件和git add . the rest, and commit.剩下的,然后提交。 OR , if you don't want to delete the file just keep it out of git, just git add <the other 9 files> and commit.或者,如果您不想删除文件,只需将其保留在 git 之外,只需git add <the other 9 files>并提交即可。

git filter-branch git 过滤器分支

This is the advanced user way.这是高级用户方式。 It is more automated.它更加自动化。 But I recommend all non git-gurus to use git rebase above because it a great way to become a guru.但我建议所有非 git-guru 使用上面的git rebase ,因为这是成为大师的好方法。

The git docs for filter-branch has instructions for removing a file from every commit, so just follow those. filter-branchgit 文档有从每次提交中删除文件的说明,所以只需遵循这些说明。

git-filter-repo git-filter-repo

I've never used git-filter-repo (yet), but it comes very recommended (apparently by the git maintainers).我从未使用过git-filter-repo (还),但它非常推荐(显然是 git 维护者)。 It is essentially a more user friendly version of git filter-branch .它本质上是一个对用户更友好的git filter-branch版本。 @LeGEC provided the specific command in a comment so I'm adding it here: @LeGEC 在评论中提供了特定的命令,所以我在这里添加它:

git filter-repo --invert-paths --path file/to/ignore

Good luck!祝你好运!

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

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