Git Reset:撤销与回溯,解读5种模式的妙用

git 上常用的常规场景的 commit 和 reset --hard 用来提交和撤销提交,当遇到比较复杂的场景,常规的指令可能就不能满足需求了

1. git reset 的5种模式

在执行撤销操作时,指令 git reset 是git最常用的命令之一,也是最危险最容易误用的命令

git reset HEAD^|<commit_id>

撤销 commit 和 add 的,但保留修改内容的记录

HEAD^ 的代表上一个版本,也可以写成 HEAD~1。如果进行了 2 次 commit,想都撤回,可以使用 HEAD~2

<commit_id> 代表某个版本的 commit_id,可通过 git log 或在 git 平台的 history 中查看

此时若需要重新提交,则需要重新执行 git add 和 git commit

git reset --soft HEAD^|<commit_id>

撤销 commit 提交,保留代码的修改和 add 的内容,目标版本可以是 HEAD 也可以使用 commit_id

若需要重新提交,则只需要重新执行 git commit

git reset --mixed HEAD^|<commit_id>

是 git reset 的默认模式,等同于 git reset,撤销 commit 和 add 记录,保留文件的修改记录,若需要再次提交,需要重新执行git add 和 git commit

git reset --hard HEAD^|<commit_id>

强制撤销 commit 和 add 记录,并撤销工作区对文件的修改,完全撤销到目标版本,是经常出现误操作指令

若对未push 的commit 进行撤销,则在当前版本下完全找不到撤销的 commit 的文件修改了,并且通过git log 也无法找到被撤销的记录了

git reset --merge HEAD^|<commit_id>

该指令在 git 版本 > 1.6.1 上生效

撤销合并(git merge)/修订(git commit)/变基(git rebase)操作,在需要提供ORIG_HEAD(git log 获取的 commit_id)

在执行撤销合并/ 变基时,效果等同于撤销合并(git merge --abort)/撤销变基(git rebase --abort)

在执行修订,效果等同于强制撤销(git reset --hard <commit_id>)

以撤销合并为例,当合并时遇到冲突并进行解决时,修改后重新提交 commit 但未执行 push 提交

此时若想要撤销合并使用 git merge --abort 将无法生效

可使用 git reset --merge <commit_id> 来进行撤销

git reset --keep HEAD^|<commit_id>

重置分支到指定的提交,保留当前工作目录和暂存区的更改。

介于git reset --hard 与 git reset --soft 之间的一个状态,保留当前做的未提交的更改,但不保留撤销之后提交的内容

当当前修改与撤销之后提交的内容有冲突时,该指令将无法执行


git 子模块

子模块创建可参考文档 Git中submodule的使用

在使用 git 子模块的场景下,执行reset 时会考虑到会不会同步执行撤销子模块的提交,此时会有两个属性用于针对子模块的场景

git reset --recurse-submodules

当使用子模块时,--recurse-submodules选项允许在重置时同时重置子模块的状态。这对于确保主项目和子模块之间的一致性非常重要。

git reset --no-recurse-submodules

与前一个选项相反,--no-recurse-submodules选项在重置时不会影响子模块的状态。

2. git commit 提交

git commit --amend

如果只是想修改commit的提交的 message 内容,在 vim 编辑器上进行修改

3. 查找提交的历史条目

git log

最常用的一种查看 git 提交历史的命令,可以获取有关仓库中提交的详细信息,包括提交者、提交日期、提交消息以及每个提交的哈希值

git reflog

查看本地仓库中的引用日志(reference log)。引用日志记录了分支、HEAD 和其他引用的变化历史,包括提交、重置、合并等操作。即使在分支指针发生变化后,你仍然可以通过 git reflog 查看引用的历史状态。

如在 git reset --hard / git merge --abort / git rebase --abort 之后,在 git log 中已经无法查看未 push 的 commit 记录了,但是可以通过 git reflog 中查看到并进行后续操作

reflog 保留与清理

git 提交历史是基于内容的,每个提交都会永久保留,但引用日志(reference log)不会。引用日志在 Git 仓库中保留一段时间,直到达到一定的条件后被清理。默认情况下 git 会保留 reflog 90天,上限条数250条,当达到任意上限时,较旧的记录会被自动清理。

若需要设置过期时间,可配置 gc.reflogExpire参数,设置"now"使所有引用日志立即过期,而"never"则完全不过期

arduino 复制代码
git config gc.reflogExpire 60.days // 设置60天过期

若需要设置上限条数,可配置 core.logAllRefUpdates,设置为负数可以不限制记录的上限数量

arduino 复制代码
git config core.logAllRefUpdates -1 

此文背景:改了一堆代码,执行了 commit 但忘记 push 之后,执行了 git reset --hard 想看历史代码,回头发现 commit 记录没了

相关推荐
学习使我快乐0118 分钟前
JS进阶 3——深入面向对象、原型
开发语言·前端·javascript
bobostudio199519 分钟前
TypeScript 设计模式之【策略模式】
前端·javascript·设计模式·typescript·策略模式
黄尚圈圈1 小时前
Vue 中引入 ECharts 的详细步骤与示例
前端·vue.js·echarts
浮华似水2 小时前
简洁之道 - React Hook Form
前端
正小安4 小时前
如何在微信小程序中实现分包加载和预下载
前端·微信小程序·小程序
_.Switch6 小时前
Python Web 应用中的 API 网关集成与优化
开发语言·前端·后端·python·架构·log4j
一路向前的月光6 小时前
Vue2中的监听和计算属性的区别
前端·javascript·vue.js
长路 ㅤ   6 小时前
vite学习教程06、vite.config.js配置
前端·vite配置·端口设置·本地开发
长路 ㅤ   6 小时前
vue-live2d看板娘集成方案设计使用教程
前端·javascript·vue.js·live2d
Fan_web6 小时前
jQuery——事件委托
开发语言·前端·javascript·css·jquery