Undo Commits
git的回退(Undo),通过git reset
and git revert
实现
git reset
作为版本控制系统,git拥有【回到过去】和【重返未来】的能力,使用的命令也相当相当简单,就是一句git reset
git reset命令可以实现在不同版本间穿梭跳越,分为 git reset --hard 和 git reset --soft
- git reset --hard commit_id
回退至commit_id指定的版本,回退时修改版本库+修改暂存区+修改工作区——全回退 - git reset --soft commit_id
回退至commit_id指定的版本,回退时修改版本库,但保留暂存区+保留工作区——仅版本库回退
git revert
git revert commit_id
git revert will create a new commit that will undo all of the work that was done in the commit you want to revert.
To undo commits that have already been pushed and shared with the team, we cannot use the git reset command. Instead, we have to use git revert.
当某些commit已经push到远端中央仓库并且被整个开发团队共享后(比如合并入master),要想取消这些commit,我们就不能用git reset
。为什么?
因为这些commit一旦push到远端中央仓库并合入master,别人就可能git pull拉到自己的本地仓库。假设:
- A push了一些commit并且合入origin/master
- 然后B通过git pull把origin/master拉下来并与本地master合并,然后在此基础上checkout新分支dev进行开发
- A发现之前的commit有bug,使用
git reset
取消这些commit并且git push --force
强制覆盖远端master - B的dev开发完毕,git push到远端中央仓库
这时,A 取消掉的commit会被B再次push上去,既不能真正实现undo的目的,也会让团队成员产生confuse
小结1:git reset
就像抹杀历史;而git revert
是在认可历史的基础上“拨乱反正”
小结2:不要去修改已被共享的代码的历史
实际上,对于已经被共享的代码,我们都不要去修改它们的历史,不要尝试git reset或者git rebase这些篡改历史的操作,因为:
- 一来,这样的篡改很可能是无效的。git是分布式的版本控制系统,你篡改了共享代码的提交历史,但这段提交历史被团队内多人保存着,他们的push会恢复这段提交历史
- 二来,commit的取消和他人对commit的恢复,会让代码的历史commit更加混乱不清晰
查找commit_id的两个命令
- git reflog
Git提供了一个命令git reflog,记录了导致仓库版本库发生变化的每一次命令,如git commit/git reset等 - git log
git log记录了每一次commit的日志