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 记录没了

相关推荐
yuhaiqiang31 分钟前
为什么这道初中数学题击溃了所有 AI
前端·后端·面试
djk888834 分钟前
支持手机屏幕的layui后台html模板
前端·html·layui
紫_龙36 分钟前
最新版vue3+TypeScript开发入门到实战教程之watch详解
前端·javascript·typescript
默默学前端1 小时前
ES6模板语法与字符串处理详解
前端·ecmascript·es6
lxh01131 小时前
记忆函数 II 题解
前端·javascript
我不吃饼干1 小时前
TypeScript 类型体操练习笔记(三)
前端·typescript
火车叼位1 小时前
一次看懂 Git 仓库分叉、冲突已解决但仍在合并中的状态
git
华仔啊1 小时前
除了防抖和节流,还有哪些 JS 性能优化手段?
前端·javascript·vue.js
CHU7290352 小时前
随时随地学新知——线上网课教学小程序前端功能详解
前端·小程序
清粥油条可乐炸鸡2 小时前
motion入门教程
前端·css·react.js