git 代码回滚到之前某个 commit 主要分为 2 个步骤,先是将本地代码分支回滚到指定版本或 tag 标记的提交 id,其次将本地回滚的代码推送到远程仓库,使远程分支回退到该历史版本。本地代码回滚使用 git reset 命令,同时作用远程仓库采用 git push 命令。
git reset 命令
本地代码回滚主要围绕着 git reset 命令,该命令会把版本库和工作目录改变为已知状态。具体来讲,git reset 调整 HEAD 引用指向指定的提交,默认情况下还会更新索引以匹配该提交。根据需要,git reset 命令也可以修改工作目录以呈现指定提交代表的项目修订版本。
git reset 命令有三个主要选项:`--soft`、`--mixed`、`--hard`。
- soft 提交
--soft
会将 HEAD 引用指向指定提交。索引和工作目录的内容保持不变。这个版本的命令有“最小”影响,只改变一个符号引用的状态使其指向一个新提交。- mixed 提交
--mixed
会将 HEAD 指向指定提交。索引内容也跟着改变以符合指定提交的树结构,但是工作目录中的内容保持不变。这个版本的命令将索引变成你刚刚暂存该提交全部变化时的状态,它会显示工作目录中还有什么修改。--mixed 是 git reset 的默认模式。- hard 提交
- 这条命令将 HEAD 引用指向给定提交。索引的内容也跟着改变以符合给定提交的树结构。此外,工作目录的内容也随之改变以反映给定提交表示的树的状态。当改变工作目录的时候,整个目录结构都改成给定提交对应的样子。做的修改都将丢失,新文件将被删除。在给定提交中但不在工作目录中的文件将恢复回来。
选项 | HEAD | 索引 | 工作目录 |
---|---|---|---|
--soft | 是 | 否 | 否 |
--mixed | 是 | 是 | 否 |
--hard | 是 | 是 | 是 |
本地代码回滚
首先通过 git log 查找要回退到的提交标记(commit id),该命令显示从最近到最远的提交日志;
$ git log
或者只显示提交的 commit id 和对应的注释的选项,如下:
$ git log --pretty=oneline
36915978c5b7e6cf4364b0b778409ba375e14289 all jar change to release
32989905ae07a92741cfedb0391544666df45885 del jacoco
......
其次,通过 git reset 回滚到指定 commit id;
$ git reset --hard <commit_id>
hard 选项,表示彻底将工作区、暂存区和版本库记录恢复到指定的版本库。
远程仓库代码回滚
将本地回滚的代码推送到远程仓库,这里需要加强制的选项 `-f` 或 `--force`;
$ git push -f origin <branch_name>
在强制推送本地回滚的代码到远程仓库时,如针对 master 分支操作很有可能提示未有强制推送的权限,如下提示:
git@MacBook-Pro xxx-xx (master) $ git ps origin head --force
Total 0 (delta 0), reused 0 (delta 0)
remote: GitLab: You are not allowed to force push code to a protected branch on this project.
To http://gitlab.xxx.com/xxxx/xxx-xx.git
! [remote rejected] head -> master (pre-receive hook declined)
error: failed to push some refs to 'http://gitlab.xxx.com/xxxx/xxx-xx.git'
以 gitlab 为例,一般 master 分支都会设置成保护分支,不允许 push --force,需要通过如下示图操作:
如上红圈示例,解禁点击路径为 Repository -> Protected Branches -> Unprotect, 解禁后可以使用强制 push 操作。