git - 如何更改过去的提交以包含丢失的文件?

我已提交更改,忘记将文件添加到更改集。 在其他提交之后,我意识到该文件现在从HEAD^4提交中丢失。

如何重写先前的提交以包含丢失的文件?

kolrie asked 2019-08-11T03:44:55Z
4个解决方案
262 votes

我意识到人们可以google并来这里寻找一个更简单的答案:如果它只是最后一次提交怎么办?  (OP的问题是修复历史上的第4次提交)

在您提交并意识到您忘记立即添加某个文件的情况下,只需执行以下操作:

# edited file-that-i-remember.txt
git add file-that-i-remember.txt
git commit

# realize you forgot a file
git add file-that-i-forgot.txt
git commit --amend --no-edit

其中--no-edit将保留相同的提交消息。

十分简单!

Dr Beco answered 2019-08-11T03:46:00Z
54 votes

使用edit并为您要修改的提交设置edit选项。

请记住,您不应该以这种方式修改推送到远程存储库的提交。 在这种情况下,添加具有丢失文件的新提交会更好。

Rafał Rawicki answered 2019-08-11T03:45:14Z
9 votes

如果你没有推送这4个提交,你可以按如下方式进行:

为所有这些提交创建补丁文件:

git format-patch -4

请回退4次提交:

git reset --hard HEAD~4

添加丢失的文件:

git add missing-file

--amend提交:

git commit --amend

应用所有保存的补丁:

git am *.patch

如果你已推,你不应该使用这种方法。 相反,只是承认你的错误并在HEAD之上再创建一个修复此问题的提交。

mvp answered 2019-08-11T03:47:08Z
5 votes

虽然接受的答案是正确的,但它缺乏关于如何在rebase过程中执行编辑提交的详细说明。

  • 首先,开始一个rebase过程:

    git commit --amend
  • 将显示提交列表,通过将单词git commit --amend更改为edit来选择要编辑的提交并保存文件。

  • 在代码中进行必要的修改(记得为新文件调用git commit --amend

  • 完成所有修改后,发出git commit --amend - 这将修改标记为git rebase --abort的提交

  • 调用将完成该过程的git rebase --abort(如果有更多提交标记为git stash pop / git stash apply,则需要重复上述步骤)

重要笔记:

  • 请勿删除您不想编辑的标记为git rebase --abort的行 - 保留原样。 删除这些行将导致删除相关提交

  • 如果您的工作目录不干净,GIT会在重新定位之前强制您到git rebase --abort; 但是在rebase期间你可以git stash pop / git stash apply,以便将这些更改(即在开始rebase进程之前发生的更改)修改为标记为edit的提交

  • 如果出现问题并且您希望在完成之前还原在rebase过程中所做的更改(即您希望在启动rebase之前恢复到该点),请使用git rebase --abort - 另请阅读:如果--abort doesn&如何中止交互式rebase #39;工作?

  • 如在接受的答案中所述:

    请记住,您不应该以这种方式修改推送到远程存储库的提交。 在这种情况下,添加具有丢失文件的新提交会更好。

    答案原因在于Git Book(标题为" Rebasing的危险"):

    不要重新生成存储库外部的提交。

    如果你遵循这个准则,你会没事的。 如果你不这样做,人们会恨你,你会被朋友和家人嘲笑。

    当您重新设置内容时,您将放弃现有提交并创建相似但不同的新提交。 如果你将提交推送到某个地方而其他人将它们拉下来并依赖它们,然后你用git rebase重写这些提交并再次推送它们,你的协作者将不得不重新合并他们的工作,当你试图将事情变得混乱 把他们的工作拉回你的工作。

    [...]

dominik answered 2019-08-11T03:49:23Z
translate from https://stackoverflow.com:/questions/14369155/how-to-change-past-commit-to-include-a-missed-file