将远程回滚到之前的提交

21
作为一个初级的Git用户,我因为一次复杂的合并而感到不知所措,并且可能做错了什么。结果导致我的源文件里充斥着一大堆垃圾代码冲突解决代码。提交记录显示添加了很多看起来像 <<<<<<< HEAD>>>>>>> a7b4de79431c2e73d28621c72c8d14820df1a24b 的行。该提交已经被推送到远程的原始代码库中,所以我无法使用修补提交的方式解决问题。
我想将远程代码库回退到上一个良好的提交记录:4a3ba7b0e56cf0be80274c1f879029220a889bde,并且(如果可能的话)销毁这个错误的提交:d004651972cbc35f70ee5a2145b6e03169c77279
我尝试过:
git checkout 4a3ba7
git push -f

并收到以下错误消息:fatal: 您当前不在任何分支上。

3个回答

28

checkout 命令可以将当前工作目录移动到之前的提交记录,但它不会修改分支内容。如果需要将分支回滚到旧的提交记录,您需要使用 reset 命令,并将其推送到远程仓库。

git checkout ...
git reset --hard 4a3ba7
git push -f

话虽如此,如果您已经使用push -f仅更改最近的提交记录,那么您应该能够使用--amend

git checkout ...
// Fix the file
git commit --amend
git push -f

如果在4a3ba7之后提交了至少一些你想要的更改,那么你也可以这样做:

git checkout ...
git reset 4a3ba7
git add -p
// Use the interactive prompt to choose the parts you want
git commit
git push -f

更新

您的错误remote: error: denying non-fast-forward refs/heads/master是因为您使用的git服务器Assembla默认情况下不允许重写历史记录。参考此答案以解决该问题:撤消对Assembla的git推送


错误:无法将一些引用推送到 ... 更新被拒绝,因为您当前分支的顶端落后于其远程对应物。 - Jesse Hallam
@Kivin 你运行了哪些命令?你的存储库中是否有其他分支?只要你在那里有“-f”,我就不会期望出现这种情况。 - loganfsmyth
远程和本地仅有一个分支为主分支。我只运行了你回答中的第一段代码块:checkout master, reset --hard 4a3ba7, push -f。目前,我在标准输出上得到以下结果: http://pastebin.com/ZKR6gF7n - Jesse Hallam
@Kivin 你正在推送到哪个服务器?听起来这个服务器设置了不允许重写历史记录。如果是这样的话,那么你可以创建一个新的提交来修复合并冲突,而不是试图从历史记录中完全删除它。 - loganfsmyth
我正在推送到assembla.com。如果我无法销毁错误提交,那么我可以重写其提交消息以更好地反映其坏处吗?我如何使我的本地仓库处于匹配4a3的状态并进行提交? - Jesse Hallam

14

您不需要在本地检出文件以倒回远程分支; 您只需使用

git push -f origin 4a3ba7b0:master

在执行操作之前,请务必仔细检查您的日志记录,因为此推送将会覆盖远程数据。

如果您遇到权限错误,则可能在远程存储库中设置了receive.denyNonFastForwardstrue;您必须更改它才能在任何情况下进行倒带。


5
我认为这是更好的答案。当你重写远程历史记录时,不应该在本地副本上胡乱操作。 - backus

3
你可以进行一个
git reset --hard *commithash* 

但是请注意:这可能会导致修改的数据丢失!(你已经被警告了:))

错误:无法将一些引用推送到 ... 更新被拒绝,因为您当前分支的顶端落后于其远程对应物。 - Jesse Hallam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接