Git13 撤销提交
Git中撤销提交的各种方法。
Git中进行撤销操作
Git强大的撤销、版本回退功能,让我们在开发的过程中能够随意的回到任何一个时间点的状态
撤销工作区的代码
在未提交之前,想将代码恢复到一开始的状态,可以使用
1 | git checkout -- <file> |
命令来撤销工作区的代码修改
在Webstorm中,对应的命令就是revert命令(新版本中改为了rollback命令)
撤销add到暂存区的代码
add到暂存区的代码想要撤销分为两个步骤:
- 将暂存区的代码撤销到工作区
- 将工作区的代码撤销(具体操作和撤销工作区的代码相同)
撤销暂存区的代码到工作区,使用的命令是:
1 | git reset HEAD |
reset会将当前head的内容重置,不会留任何痕迹。
利用Reset撤销本地代码
提交到本地仓库的代码一样也可以撤销,我们可以利用git reset --mixed <版本号>命令来实现版本回退,该命令中的版本号有几种不同的写法:
- 可以使用
HEAD^来描述版本,一个^表示前一个版本,两个^^表示前两个版本,以此类推。 - 也可以使用数字来代替
^,比如说前100个版本可以写作HEAD~100。 - 也可以直接写版本号,表示跳转到某一个版本处。我们每次提交成功后,都会生成一个哈希码作为版本号,所以这里我们也可以直接填版本号,哈希码很长,但是我们不用全部输入,只需要输入前面几个字符即可,就能识别出来。
在Wetstorm中对应的命令是Git - Repository RESET Head,输入对应的版本号就可以退回到当时的版本状态
git reset有三种模式:
git reset - mixed:此为默认方式,将本地版本库的头指针全部重置到指定版本,且会重置暂存区,即这次提交之后的所有变更都移动到未暂存阶段git reset - soft: 回退到某个版本,本地版本库的头指针全部重置到指定版本,且将这次提交之后的所有变更都移动到暂存区git reset - hard:不仅仅是将本地版本库的头指针全部重置到指定版本,也会重置暂存区,并且会将工作区代码也回退到这个版本
利用revert撤销本地代码
1 | git revert <commidId> |
利用reset是直接改写之前的历史,传入的commitId意味着,这之后的commit都直接被消除。
revert则不同,传入的commitId意味着,重新生成一次提交,将commitId对应的coomit修改会commit之前的状态。即利用了一次新的commit来回滚之前的操作。
上面的这种写法每次只能处理一个commit,如果想要处理多个commit,可以按照下面的写法:
1 | git revert <olderCommitId>^..<newerCommitId> |
举个例子,commit的历史下如下:
1 | A -> B -> C -> D |
如果想要revert的commit是B、C、D的话,除了一个一个来,可以这样:
1 | git revert B^..D |
这样commit的历史就变成了
1 | A -> B -> C -> D -> D' -> C' -> B' |
如果想把这三次coommit用一次提交来revert,可以这样:
1 | git revert -n B^..D |
reset和revert的应用场景
- 如果回退的代码以后还需要,那么最好使用
revert - 如果分支错误,以后在不需要了,也不想保留记录,使用
reset - 如果合并了
a/b/c/d四个分支,只希望撤销b分支,保留c和d分支,那么不能使用reset,需要revert b这样可以实现
撤销远程仓库代码
如果代码已经提交到了远程仓库,那么在使用reset本地撤销提交之后,在向远程仓库push的时候,本地的分支是落后于远程分支的,那么push会被拒绝,需要使用--force命令:
1 | git push origin dev --force |
这种情况对于一些多人合作开发的上游分支来说,是危险且很可能被禁止的,所以需要如果代码已经提交到了远程仓库的情况下,更推荐使用revert命令来撤销本地提交,继而变相的撤销远程仓库的代码。
因为revert是利用新的『相反』的提交,撤销了之前的代码,是一次新的commit,所以可以直接推送到远程仓库,从而撤销远程仓库的代码。