欢迎来到HDUISA wiki,如果这是你的第一次到来,请点击此处注册

本篇并不是『从零开始』系列,请自行掌握最基础的用法。 本篇讲的是关于 git reset, git checkout, git revert 的区别与使用场景。 -- Aklis

0x00 时光机

在某些场景下,这仨都有着"撤消"的功效,撤消自己的更改,恢复原来的状态之类的。但怎么会有三个方法来解决一个问题呢,我们需要知道在什么情况下选择最优雅的那个。

历史记录 也就是 commit history, 查看方式为git log 最上面的是最新的一次commit

缓存区 也就是 staged snapshot, 查看方式为git status

代码仓库 Working Directory 当前文件的实际状态,对,直接ls/cat看。

HEAD (大写)回去看git基础教程,表示当前分支。 具体分支下的head(小写)指所在分支的

0x01 git checkout

切换HEAD,对于初步了解git的同学来说,它就是用来切换分支的,这是它的一个功能。这里会对它工作的本质进行介绍。

git checkout 目标分支名

这是最常用的命令之一,切换到目标分支

.git/HEAD 会跟着变更。 比如原来在master分支的 ref: refs/heads/master 会变成 ref: refs/heads/dev

git checkout commit_d

又因为git checkout 会丢弃缓存区和仓库文件的更改,所以没有commit之前使用checkout都会警告。

0x02 git reset

reset 重设

命令解释起来就是将当前分支的末端,指向某个commit。 因为是末端,所以提交修改之后(commit)

reset 有三种,分别是--soft, --mixed(缺省), --hard

总结 - soft 只改变 HEAD。 - mixed 改变 HEAD 且会将目标commit的内容放入缓存区,当前文件不会有变化。 - keep 这个就相当于mixed+git add - hard 丢弃现有的缓存区和未添加修改,完完全全地变成目标commit。

git reset --hard commit_id

最简单粗暴,立杆见影。

git reset 31dd52c 

31dd52c 的内容就放到了缓存区(staged)中,文件不会有变化。 一般配合HEAD使用,撤消之前git add的内容。

命令 参数 说明
git reset Commit 丢弃(一般为私有)分支上的commit或者当前更改
git reset File 从缓存区中剔除一个文件
git checkot Commit 我切我切我切切切分支或者查看旧版本
git checkout File 丢弃当前文件的更改
git revert commit 回滚(场景多为公有分支)

0x03 git revert

revert 回复

就是回复用的,也是推荐的方式,无痛安全。 写代码写着想要回滚到之前某一个commit(时间点),然后生成一个新的commit。也就是并不破坏原来的历史,也就是 不改变 之前的commit history。

[此处应有一张图] 原来的历史记录

git revert git status 可以看到能被自动合并的,被回复的文件已经加入到了缓存区。 如果有冲突就解决冲突,commit。

[此处应有一张图] git commit之后历史记录

和git reset 到先前的历史不同,不会删除之后的节点。

0x04 场景

场景一 学长,我把之前的一个功能重写了,但是一些commit,我已经推到Github上了。

答:这个时候你就要用git revert了,它不会破坏原来的commit,完全不会。

场景二 学长,我想要只是看看这个程序的历史版本,并不想作什么修改……

答:

某一个版本tag

git checkout tag

某一次提交

git checkout commit

往前n个版本

git checkout HEAD~n

场景三 学长,我本来想写个功能的,但我弃疗了……

答: git checkout

打印/导出