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

kol*_*rie 94 git git-commit

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

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

Dr *_*eco 268

我意识到人们可以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
Run Code Online (Sandbox Code Playgroud)

哪里--no-edit将保留相同的提交消息.

十分简单!

  • 这就是答案. (19认同)
  • 值得一提的是,如果提交没有被推到遥控器上. (5认同)
  • 谢谢,但不能是:OP要求`HEAD ^ 4`.它的确如此,只是作为参考的附录.;) (4认同)
  • 是的,在评论中值得一提的是:用于**push**之前。感谢您指出这一点。 (2认同)
  • 一个通知是`--amend`之前和之后的提交有[不同的哈希](http://stackoverflow.com/questions/3926768/amend-a-commit-that-wasnt-the-previous-commit) (2认同)

Raf*_*cki 53

使用git rebase --interactive HEAD~4和设置edit您要修改的提交选项.

请记住,您不应该以这种方式修改推送到远程存储库的提交.在这种情况下,最好添加一个缺少文件的新提交.

  • 我认为这些说明不够详细.在我第一次被告知"无法重组:您的索引包含未提交的更改"时尝试它.我已经"添加"了丢失的文件,所以我做了一个以"xxx"作为消息的提交.然后我做了rebase命令,并将"xxx"提交从"pick"更改为"edit".然后我做了"git rebase --continue".现在,当我查看历史记录时,我将"xxx"作为最新提交,并且我想要添加它们的早期提交不变!我想知道我的错误在哪里? (7认同)
  • 压缩最后一次提交不会将文件放在HEAD~4中. (2认同)
  • git 添加已编辑的文件;git commit -m "废话"; git rebase -i HEAD~5; // 因为现在添加了新提交,所以我们需要使用 5 而不是 4 进行变基。现在将“Blah”提交移动到第二行并将其从“Pick”更改为“s”(壁球),这将使用 HEAD 压缩提交~ 5 因为命令是从上到下执行的 (2认同)

mvp*_*mvp 10

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

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

git format-patch -4
Run Code Online (Sandbox Code Playgroud)

请回退4次提交:

git reset --hard HEAD~4
Run Code Online (Sandbox Code Playgroud)

添加丢失的文件:

git add missing-file
Run Code Online (Sandbox Code Playgroud)

承诺--amend:

git commit --amend
Run Code Online (Sandbox Code Playgroud)

应用所有保存的补丁:

git am *.patch
Run Code Online (Sandbox Code Playgroud)

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

  • 这些说明似乎很冗长,但非常简单易懂.谢谢.(我只想添加最后一步:`rm*.patch`) (2认同)

dom*_*nik 7

尽管接受的答案是正确的,但是它缺少有关如何在变基过程中执行编辑提交的详细说明。

  • 首先,开始一个变基过程:

    git rebase --interactive HEAD~4
    
    Run Code Online (Sandbox Code Playgroud)
  • 将显示提交列表,通过将单词更改为pick来选择要编辑的提交edit并保存文件。

  • 在代码中进行必要的修改(记住要调用git add新文件)

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

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

重要笔记:

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

  • stash如果您的工作目录不干净,GIT会在重新设置基础之前强制您执行;但是git stash pop / git stash apply,您可以在重新设置基准期间将这些更改(即,在开始重新设置基准之前隐藏的更改)修改为标记为edit

  • 如果出了什么问题,并且您想在完成变基过程之前还原更改之前所做的更改(即,您想在开始变基之前还原到该点),请使用git rebase --abort-也请阅读:如果--abort不起作用,如何中止交互式变基?工作吗?

  • 如公认的答案所述:

    请记住,您不应以这种方式修改推送到远程存储库的提交。在这种情况下,最好添加一个缺少文件的新提交。

    问题的答案在《Git书》中(标题为“变基的危险”的段落):

    不要对存储库外部存在的提交进行基准化。

    如果您遵循该准则,就可以了。如果您不这样做,那么人们会讨厌您,并且您会受到朋友和家人的嘲笑。

    在对内容进行重新编排时,您将放弃现有的提交并创建相似但不同的新提交。如果您将提交推送到某个地方,而其他人则将其拉下并基于它们进行工作,然后再使用git rebase重写这些提交,然后再次将其上推,那么您的协作者将不得不重新合并其工作,并且当您尝试执行以下操作时,事情将会变得混乱将他们的工作拉回到您的工作中。

    [...]