在日常的开发中,我们经常使用Git来进行版本控制。有时候,我们可能会不小心将错误的代码 Push 到远程仓库,或者想要在本地回退到之前的某个版本重新开发。
或者像我一样,写了一些感觉以后很有用的优化方案push到线上,又接到了一个新的需求。但是呢,项目比较重要,没有经过测试的方案不能轻易上线,为了承接需求只能先把push上去的优化方案先下掉。
现在我的分支是这样的,我想要在本地和远程仓库中都恢复到help文档提交的部分。
注意
- 在执行这些操作之前,请确保完全理解它们的影响,特别是在多人协作的项目中。
- 对于受保护的分支(如主分支或发布分支),可能无法执行强制推送。需要根据你的项目设置或团队规范来处理这种情况。
- 使用强制推送会改变远程仓库的历史,可能会给团队成员带来困扰。在这样做之前,最好与团队成员沟通。
最简单粗暴的方法
IntelliJ IDEA方法
如果你的错误代码不是很多,那么你其实可以通过与你想要恢复到的commit进行对比,然后手动删除错误代码,然后删除不同的代码。
按住 ctrl 选择想要对比的两个commit,然后选择 Compare Versions 就能通过对比删除掉你想要删除的代码。
这个方案在代码很简单时时非常有效的,甚至还能通过删除后最新commit和想要退回的commit在Compare一下保障代码一致。
但是这个方法对于代码比较复杂的情况来说就不太好处理了,如果涉及到繁杂的配置文件,那更是让人头疼。
而且,这样还会保留错误提交的记录,对于有强迫症的我来说,有点接受不能。对此,git也有一套较为优雅的操作流程,同样能解决这个问题。
Git命令方法
在Git中,要比较两个commit之间的代码变动,可以使用 git diff
命令。这个命令允许你查看两个不同commit之间的差异。以下是一些常用的方法:
-
基本用法:
git diff <commit1> <commit2>
这里
<commit1>
和<commit2>
分别代表你想要比较的两个commit的哈希值。这里注意一下,在使用
git diff
命令比较两个commit时,commit1和commit2的顺序会影响显示的差异内容。命令git diff <commit1> <commit2>
的作用是显示从commit1
变化到commit2
时代码发生的变动。
- 如果你先指定较早的commit(
commit1
),然后指定较晚的commit(commit2
),你会看到在这两个commit之间所做的更改。 - 相反,如果你先指定较晚的commit作为
commit1
,然后指定较早的commit作为commit2
,你将看到要从较晚的commit回退到较早commit所需撤销的更改。
所以个人一般用法的话都是将较早的commit作为 commit1
,较晚的commit作为 commit2
,通常更符合查看代码变化的直观逻辑。
- 比较指定文件的变化:
这条命令将只显示指定文件在两个commit之间的差异。git diff <commit1> <commit2> -- <file_path>
IDEA 中 Git 较为优雅的方法
Reset Current Branch 到你想要恢复的commit记录
这个时候会跳出四个选项供你选择,我这里是选择hard。
其他选项的含义仅供参考,因为我也没有一一尝试过。
-
Soft:你之前写的不会改变,你之前暂存过的文件还在暂存。
-
Mixed:你之前写的不会改变,你之前暂存过的文件不会暂存。
-
Hard:文件恢复到所选提交状态,任何更改都会丢失。你已经提交了,然后你又在本地更改了,如果你选hard,那么提交的内容和你提交后又本地修改未提交的内容都会丢失。
-
keep:任何本地更改都将丢失,文件将恢复到所选提交的状态,但本地更改将保持不变。你已经提交了,然后你又在本地更改了,如果你选keep,那么提交的内容会丢失,你提交后又本地修改未提交的内容不会丢失。
然后,之前错误提交的commit就在本地给干掉了。但是远程仓库中的提交还是原来的样子,你要把目前状态同步到远程仓库。也就是需要把那几个commit删除的操作push过去。
打开push界面,虽然没有commit需要提交,需要点击Force Push,强推过去。
需要注意的是对于一些被保护的分支,这个操作是不能进行的。需要自行查看配置,我这里因为不是master分支,所以没有保护。
可以看到,远程仓库中最新的commit只有我们的help文档。在其上的三个提交都没了。
我还是想用Git命令来完成恢复
1. 重置当前分支到特定commit
首先,找到你想要恢复到的commit的哈希值。可以通过 git log
查看提交历史来找到这个哈希值。
然后,使用 git reset
命令来重置当前分支。这里有四种不同的模式可选:
-
Soft:
git reset --soft <commit-hash>
-
Mixed:
git reset --mixed <commit-hash>
(这是默认选项) -
Hard:
git reset --hard <commit-hash>
-
Keep:
git reset --keep <commit-hash>
2. 将更改推送到远程仓库
在重置后,本地分支的状态可能与远程仓库不同步。为了同步这些更改,需要使用强制推送。但请注意,这个操作对于团队协作和共享仓库来说可能是危险的,因为它会覆盖远程仓库的历史。
使用以下命令进行强制推送:
git push origin <branch-name> --force
或者,如果你使用的是Git版本2.5及以上,可以使用更安全的方式:
git push origin <branch-name> --force-with-lease
这个命令在强制推送之前会检查远程分支的状态,确保没有被其他人更新过。
*注意: 以上使用的是2023版IDEA,如果有出入的话可以考虑搜索使用git命令代替,毕竟通用性会更好一点,可能就是有点不直观。