Git 如何更改过去的提交以包含丢失的文件?
我已提交更改,但忘记将文件添加到更改集中。在其他提交之后,我意识到文件现在从Git 如何更改过去的提交以包含丢失的文件?,git,git-commit,Git,Git Commit,我已提交更改,但忘记将文件添加到更改集中。在其他提交之后,我意识到文件现在从头^4提交中丢失了 如何重写以前的提交以包含丢失的文件?为要修改的提交使用并设置编辑选项 请记住,不应以这种方式修改推送到远程存储库的提交。在这种情况下,最好添加一个缺少文件的新提交 为了更清楚地说明这一点,首先使用git stash隐藏任何当前更改。然后,git-rebase——交互式头~4。您可以在文本编辑器中获得以下内容(请注意,您将获得5次提交,按降序排列): 将更改条目的前缀从pick修改为edit。这将是操
头^4
提交中丢失了
如何重写以前的提交以包含丢失的文件?为要修改的提交使用并设置编辑
选项
请记住,不应以这种方式修改推送到远程存储库的提交。在这种情况下,最好添加一个缺少文件的新提交
为了更清楚地说明这一点,首先使用
git stash
隐藏任何当前更改。然后,git-rebase——交互式头~4
。您可以在文本编辑器中获得以下内容(请注意,您将获得5次提交,按降序排列):
将更改条目的前缀从pick
修改为edit
。这将是操作的编辑321e122…
git-rebase
按顺序遍历条目。因为我们只更改了一个条目,所以您只能更改一个条目。现在,使用git add
添加您的文件,并使用git commit--amend
修改这些添加的文件的当前提交
最后,
git-rebase--continue
移动到下一个文件。由于只有一个提交,因此重基已完成如果您尚未推送这4个提交,则可以按如下方式执行:
为所有这些提交创建修补程序文件:
git format-patch -4
倒带4次:
git reset --hard HEAD~4
添加缺少的文件:
git add missing-file
用提交它--修改:
git commit --amend
将所有保存的修补程序应用回:
git am *.patch
如果您已按下,则不应使用此方法。相反,只要承认你的错误,在头上再做一次承诺就可以解决这个问题。我意识到人们可以通过谷歌搜索到一个更简单的答案:如果这只是最后一次承诺呢?
(OP的问题是修复历史上的第四次提交)
如果您提交并意识到忘记立即添加某些文件,只需执行以下操作:
# 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
其中--没有编辑将保留相同的提交消息
轻松点 尽管接受的答案是正确的,但它缺少关于如何在重新基址过程中执行编辑提交的详细说明
- 首先,启动一个重设基础的过程:
git rebase --interactive HEAD~4
- 将显示提交列表,通过将单词
pick
更改为edit
选择要编辑的提交并保存文件
- 对代码进行必要的修改(请记住为新文件调用
git add
)
- 完成所有修改后,发出
git commit--amend
-这将修改标记为edit
- 调用
git-rebase——继续
,这将完成该过程(如果有更多的提交标记为edit
,则需要重复上述步骤)
重要注意事项:
- 不要删除标记为不想编辑的
拾取
行-保持原样。删除这些行将导致删除相关提交
- 如果您的工作目录不干净,GIT会强制您在重定基址之前
隐藏;但是,您可以在重新基础期间git stash pop/git stash apply
,以便将这些更改(即在开始重新基础过程之前隐藏的更改)修改为标记为edit
- 如果出现问题,并且您希望在重新基础过程完成之前还原所做的更改(即,您希望还原到启动重新基础之前的点),请使用
git-rebase--abort
-另请阅读:
- 正如公认的答案所说:
请记住,不应以这种方式修改推送到远程存储库的提交。在这种情况下,最好添加一个缺少文件的新提交
答案是(题为“重新定价的风险”的段落):
不要对存储库外部存在的提交重新设置基础
如果你遵循这个指导方针,你会没事的。如果你不这样做,人们会恨你,你会被朋友和家人嘲笑
当您重新设置内容的基础时,您放弃了现有的提交,并创建了相似但不同的新提交。如果您将提交推到某个位置,而其他人将其向下拉并基于它们进行工作,然后您使用git rebase重写这些提交并再次将其向上推,那么您的合作者将不得不重新合并他们的工作,当您尝试将他们的工作拉回到您的工作中时,事情将变得一团糟
[……]
这里有一种非交互式的
重设基础的方法
这需要一个额外的提交(因此不会像OP所要求的那样“重写以前的提交”),但我发现它更容易记住
初始状态:
* e834111 (HEAD -> master) do something that depends on file x
* 6dde62a do stuff, forget to add file x
...
步骤1-在提交时签出应包含该文件的新临时分支(git checkout-b temp 6dde
):
步骤2-添加
缺少的文件并提交
:
* 50d1412 (HEAD -> temp) add file x
| * e834111 (master) do something that depends on file x
|/
* 6dde62a do stuff, forget to add file x
...
第3步-签出原始分支并将其重新设置为temp
:
* dd6f2dd (HEAD -> master) do something that depends on file x
* 50d1412 (temp) add file x
* 6dde62a do stuff, forget to add file x
...
步骤4-删除临时分支(git分支-d temp
)
注意:这也可以在不创建临时分支的情况下完成,例如使用git checkout 6dde
,然后是commit
和rebase
到分离的磁头上。您是否将这4个提交推到了?@mvp nope,它们仅在我的本地git存储库中。如果您想一步一步地执行此操作,那么在修改后选择提交比将其导出为补丁更容易。这是一个品味问题。我更喜欢git格式的补丁
/gitam
。最重要的是,如果你把事情搞砸了,它会给你更多的信心——在物理文件中保存为补丁的提交是你最好的安全网。真正的信心在于,在git存储库上操作时,你永远不会删除任何东西。旧提交可用
* 50d1412 (HEAD -> temp) add file x
| * e834111 (master) do something that depends on file x
|/
* 6dde62a do stuff, forget to add file x
...
* dd6f2dd (HEAD -> master) do something that depends on file x
* 50d1412 (temp) add file x
* 6dde62a do stuff, forget to add file x
...