目录
前言
一些git命令的理解和分析,希望能让你有一个更清晰的认识!
一、移动
接触 Git 更高级功能之前,我们有必要先学习在你项目的提交树上前后移动的几种方法。
1.HEAD
HEAD 是一个对当前所在分支的符号引用 —— 也就是指向你正在其基础上进行工作的提交记录。HEAD 总是指向当前分支上最近一次提交记录。大多数修改提交树的 Git 命令都是从改变 HEAD 的指向开始的。HEAD 通常情况下是指向分支名的(如 bugFix)。在你提交时,改变了 bugFix 的状态,这一变化通过 HEAD 变得可见。
如果想看 HEAD 指向,可以通过 cat.git/HEAD 查看, 如果 HEAD 指向的是一个引用,还可以用 git symbolic-ref HEAD查看它的指向。
分离的HEAD:让其指向了某个具体的提交记录而不是分支名。在命令执行之前的状态如下所示:HEAD -> main -> C1 。HEAD 指向 main, main 指向 C1。执行命令之后变成HEAD -> C1。


注意:C1代表的是提交记录的哈希值,通过指定提交记录哈希值的方式在 Git 中移动不太方便。在实际应用时,并没有像本图例中这么漂亮的可视化提交树供你参考,所以你就不得不用 git log
来查查看提交记录的哈希值。
并且哈希值在真实的 Git 世界中也会更长(注:基于 SHA-1,共 40 位)。例如C1的提交记录的哈希值可能是 fed2da64c0efc5293610bdd892f82a58e8cbc5d8
。舌头都快打结了吧...
比较令人欣慰的是,Git 对哈希的处理很智能。你只需要提供能够唯一标识提交记录的前几个字符即可。因此我可以仅输入fed2
而不是上面的一长串字符。
2.相对引用
通过哈希值指定提交记录很不方便,所以 Git 引入了相对引用。这个就很厉害了! 使用相对引用的话,你就可以从一个易于记忆的地方(比如 bugFix
分支或 HEAD
)开始计算。
相对引用非常给力,这里我介绍两个简单的用法:
- 使用 ^ 向上移动 1 个提交记录
- 使用
~<num>
向上移动多个提交记录,如~3
2.1操作符 ^
先看看操作符 (^)。把这个符号加在引用名称的后面,表示让 Git 寻找指定提交记录的父提交。所以main^相当于main的父节点。main^^相当于main的第二个父节点。


这种方式是不是比输入哈希值方便多了?当然我们也可以将HEAD作为相对引用的参照。
2.2操作符 ~
如果你想在提交树中向上移动很多步的话,敲那么多 ^ 貌似也挺烦人的,Git 当然也考虑到了这一点,于是又引入了操作符 ~。该操作符后面可以跟一个数字(可选,不跟数字时与 ^ 相同,向上移动一次),指定向上移动多少次。咱们还是通过实际操作看一下吧!
如果我想用 ~<num>后退四步,Git checkout HEAD~4


3.强制修改分支位置
你现在是相对引用的专家了,现在用它来做点实际事情。我使用相对引用最多的就是移动分支。可以直接使用 -f 选项让分支指向另一个提交例如:
Git branch -f main HEAD~3
上面的命令会将 main 分支强制指向 HEAD 的第 3 级父节点提交。


思考:怎么移动下图一的HEAD,main
和 bugFix
到目标所示的位置图二?


答案:步骤一:git checkout HEAD~ 步骤二:git branch -f bugFix HEAD~ 步骤三:git branch -f main c6
二、撤销变更
在 Git 里撤销变更的方法很多。和提交一样,撤销变更由底层部分(暂存区的独立文件或者片段)和上层部分(变更到底是通过哪种方式被撤销的)组成。
主要有两种方法用来撤销变更一是git reset,还有就是git revert。接下来咱们逐个进行讲解。
1.git reset
git reset 通过把分支记录回退几个提交记录来实现撤销改动。你可以将这想象成“改写历史”。git reset 向上移动分支,原来指向的提交记录就跟从来没有提交过一样。


注:Git 把 main 分支移回到C1;现在我们的本地代码库根本就不知道有C2这个提交了。
(在reset后,C2所做的变更还在,但是处于未加入暂存区状态。)



也可以输入命令 git reset --hard [要回到那次提交的哈希值]

效果:注意无记录!!!!

2.git revert
git revert 不会改变原有的提交历史,而是通过创建新的提交来保留历史记录的同时撤销特定提交的效果。


通过上图可以看到在我们要撤销的提交记录后面居然多了一个新提交!这是因为新提交记录C2`引入了更改 —— 这些更改刚好是用来撤销 C2
这个提交的。也就是说C2`的状态与C1是相同的。revert 之后就可以把你的更改推送到远程仓库与别人分享啦。

小结:git reset 更多用于本地操作,可以重置工作目录和暂存区的状态,甚至删除提交。
git revert 用于创建新的提交来撤销之前的提交,适用于本地和远程仓库,保留历史记录。
【git reset 的参数是要回到哪次提交】 【git revert 的参数是要撤销哪次的提交】
总结
这是我在学习过程中的一些学习记录,分享出来希望可以对你有帮助吧!