Git本地版本回退------Git reset

26 阅读3分钟

1. 前置配置:

$ git init // 初始化仓库
Initialized empty Git repository in /home/hanli/Desktop/.git/
$ vim arithmetic.cpp //编写一个c++程序并保存
$ cat arithmetic.cpp //
#include <iostream>using namespace std;
​
int add(int num1, int num2);
​
int main(void) {
    int num1 = 20;
    int num2 = 10;
    cout << "num1 + num2 =" << add(num1, num2) << endl;
    return 0;
}
​
int add(int num1, int num2) {
    return num1 + num2;
}
​
$ git add arithmetic.cpp    // 添加到暂存区
$ git commit -m "have an addition function"     //添加到本地仓库
[master (root-commit) 5b1aaa8] have an addition function
 1 file changed, 16 insertions(+)
 create mode 100644 arithmetic.cpp

这里已经添加了一个有加法运算的源文件到本地仓库,后面我们依次添加减法乘法,除法运算功能到源文件中,依次添加到本地仓库中。

$ cat arithmetic.cpp
#include <iostream>
​
using namespace std;
​
int add(int num1, int num2);
int sub(int num1, int num2);
int mul(int num1, int num2);
int divide(int num1, int num2);
​
int main(void) {
    int num1 = 20;
    int num2 = 10;
    cout << "num1 + num2 =" << add(num1, num2) << endl;
    cout << "num1 - num2 =" << sub(num1, num2) << endl;
    cout << "num1 * num2 =" << mul(num1, num2) << endl;
    cout << "num1 / num2 =" << divide(num1, num2) << endl;
    return 0;
}
​
int add(int num1, int num2) {
    return num1 + num2;
}
​
int sub(int num1, int num2) {
    return num1 - num2;
}
​
int mul(int num1, int num2) {
    return num1 * num2;
}
​
int divide(int num1, int num2) {
    return num1 / num2;
}
​

2.版本回退

此时我们算术程序中一共有四个版本被提交到本地仓库了,分别是:

  1. 版本一:have an addition function
  2. 版本二:have an subtraction function
  3. 版本三:have multiplication function
  4. 版本四:have division function

2.1 git log

但在实际工作中,我们无法记住这么多次修改提交,所以需要git进行协助。

git log 是 Git 中查看提交历史的核心命令,能展示仓库的提交记录(作者、时间、提交信息、哈希值等),支持多维度筛选、格式化输出,是定位版本、排查问题、追溯代码变更的关键工具。

  • 核心语法

    git log [选项] [参数]
    
  • 默认行为:不加任何选项时,按提交时间从新到旧显示所有提交,每条记录包含:提交哈希(完整40位)、作者(姓名 + 邮箱)、提交时间、提交说明。

  • 参数:可指定分支/文件/提交范围 (如 git log master 查看 master 分支历史,git log arithmetic.cpp查看某个文件提交历史)

默认用法:

$ git log
commit d8a32f247c0c7c1eed45fea5bf13739af0f02956 (HEAD -> master)
Author: hanli <hanli@163.com>
Date:   Thu Dec 4 14:10:22 2025 +0800
​
    have division functioncommit 3c74936b09f81de426a462efa08f7b874c9f90f8
Author: hanli <hanli@163.com>
Date:   Thu Dec 4 14:07:52 2025 +0800
​
    have multiplication functioncommit 9ab8020e5be6115f3da7a4e78b5b16df54a0ead3
Author: hanli <hanli@163.com>
Date:   Thu Dec 4 13:59:56 2025 +0800
​
    have an subtraction functioncommit 5b1aaa8e70ab0d2ca9e525419a5d93803d04723c
Author: hanli <hanli@163.com>
Date:   Thu Dec 4 13:54:15 2025 +0800
​
    have an addition function

我们也可以简化输出,添加参数--pretty=oneline

$ git log --pretty=oneline
d8a32f247c0c7c1eed45fea5bf13739af0f02956 (HEAD -> master) have division function
3c74936b09f81de426a462efa08f7b874c9f90f8 have multiplication function
9ab8020e5be6115f3da7a4e78b5b16df54a0ead3 have an subtraction function
5b1aaa8e70ab0d2ca9e525419a5d93803d04723c have an addition function

如果还是感觉到哈希值太长了,直接缩短到7位,添加参数 --oneline

$ git log --oneline
d8a32f2 (HEAD -> master) have division function
3c74936 have multiplication function
9ab8020 have an subtraction function
5b1aaa8 have an addition function

2.2 git reset

在进行版本回退之前,需要主要到HEAD,简单了解一下,HEAD 是 Git 里的当前工作区指针,本质是一个 “引用”(可以理解成 “快捷方式”),它始终指向你当前工作目录所基于的那个提交。

如果想指向上一个版本用HEAD^,上上一个版本用HEAD^^,网上N个版本就是HEAD~N

git reset 是 Git 中重置当前分支提交历史、移动 HEAD 指针的核心命令,核心作用是修改 HEAD 指向的提交,同时可选择重置工作区、暂存区的状态。

  • 基础语法:

    git reset [--soft | --mixed | --hard] [目标提交/分支/标签]
    
    • 「目标提交」:可以是提交哈希(如 3c74936)、分支名(如 master)、相对引用(如 HEAD~1,表示 HEAD 上移 1 个提交);
    • 省略目标提交时,默认以 HEAD 为基准(通常配合参数撤销最近的暂存操作);
    • --soft/--mixed/--hard:核心参数,决定重置的 “深度”(默认是 --mixed)。
  • 三种核心模式:

    1. 软重置:git reset --soft <目标提交>

      1. 行为:

        1. 仅移动HEAD指针到目标提交;
        2. 暂存区、工作区完全不变(所有修改任保留在暂存区)。

        简单来说,就是“只返回提交记录,不返回代码修改”-----相当于撤销了git commit操作,但git add的结果还在。

      2. 示例:

        • 提交后发现提交信息写错,想要重新提交:

          git reset --soft HEAD~1  # 回滚最近1次提交(保留暂存区)
          git commit -m "修正后的提交信息"  # 重新提交
          
        • 合并多个连续的小提交为一个“整洁提交”。

          $ git log --oneline // 查看提交信息,发现有问题,重新修改提交
          d8a32f2 (HEAD -> master) have division function
          3c74936 have multiplication function
          9ab8020 have an subtraction function
          5b1aaa8 have an addition function
          ​
          git reset --soft HEAD~2
          git git commit -m "add multiplication and division function"
          ​
          $ git log --oneline
          40d3b12 (HEAD -> master) add multiplication and division function
          9ab8020 have an subtraction function
          5b1aaa8 have an addition function
          

          此时我们已经将两个小提交合并成一个提交了

    2. 混合重置(默认):git reset [--mixed] <目标提交>

      1. 行为:

        • 移动 HEAD 指针到目标提交;
        • 重置暂存区(与目标提交的暂存区保持一致);
        • 工作区不变(修改仍保留,只是从 “已暂存” 变回 “未暂存”)。

        简单来说,“反悔提交 + 反悔git add",撤销 git commitgit add, 但代码修改还在工作区,可重新编辑后再add/commit

      2. 示例:

        • 提交后发现漏加文件/改错题,想重新整理暂存区:

          git reset HEAD~1  # 等价于 --mixed,回滚提交+清空暂存区
          # 重新修改代码、git add 所需文件
          git commit -m "补充修改后的提交"
          
        • 撤销误操作的 git add(不加目标提交,仅重置暂存区):

          git reset  # 把所有已add的文件变回未暂存状态
          git reset <文件名>  # 仅撤销单个文件的git add
          
    3. 硬重置:git reset --hard <目标提交>

      1. 行为:

        • 移动 HEAD 指针到目标提交;
        • 重置暂存区 + 工作区(完全匹配目标提交的状态);
        • 工作区中未提交的修改会被彻底删除(无法恢复,慎用)。

        简单来说,“一键回滚到历史状态”—— 代码、提交记录完全回到目标提交的样子,当前所有未提交的改动都消失。

      2. 示例:

        • 测试代码改乱了,想彻底放弃所有未提交修改,回到最近一次提交:

          git reset --hard HEAD  # 重置到当前HEAD指向的提交
          
        • 彻底回滚到某个稳定版本(如 9ab8020):

          git reset --hard 3c74936
          
  • 实操:

    1. 我们现在要撤销最近的一次提交,回到只有加减法的版本:

      $ git log --oneline //读取log
      40d3b12 (HEAD -> master) add multiplication and division function
      9ab8020 have an subtraction function
      5b1aaa8 have an addition function
      ​
      $ git reset --hard 9ab8020 // 我这里用哈希值,你可以用HEAD^
      HEAD is now at 9ab8020 have an subtraction function
      
    2. 此时你有想要有乘除功能了,但是运行git log会发现之前版本不见了。

      $ git log --oneline
      9ab8020 (HEAD -> master) have an subtraction function
      5b1aaa8 have an addition function
      

      只要是该提交曾经被记录过,可以通过git reflog 找回

      git reflog  # 查看HEAD的所有操作记录,找到误删前的提交哈希
      git reset --hard <误删前的提交哈希>  # 恢复到该状态
      

2.3 总结

需求场景命令
撤销最近 1 次提交(保留暂存区)git reset --soft HEAD~1
撤销最近 1 次提交(保留工作区)git reset HEAD~1(默认 --mixed)
放弃所有未提交修改,回到当前版本git reset --hard HEAD
回滚到指定提交(清空所有改动)git reset --hard 3c74936
撤销单个文件的 git addgit reset <文件名>
撤销所有 git add 的文件git reset