Git commit-id

commit-id

姑且这么称呼每一个 commit 所独有的 id 为 commit-id 。所以 commit-id 都是用来唯一标识每一个 commit 的,使用 git log 命令可以看到一大堆 hash 化的 commit-id 。

现在我们定义每个 commit-id 所对应的文件区的代码( 用代码为了好理解 ) 改动为 δ( 建议读成 delta )。后面所有操作都是基于 commit-id 操作的,所以大家要清楚 Git 的原子粒度最细就到 commit-id 了。

::: tip
总有人纠结同一次 commit 里的两个文件改动,由于后悔想分别进行 xxx 处理怎么办?只能凉拌,没有可能的!因为 Git 管理的粒度不到这里)。
:::

HEAD

Git 操作时要有 HEAD 概念。可以理解成 HEAD 就是一个指针,指向一个 commit-id 。就算你以为你的 HEAD 指向的是一个 branch ,其实底层也是指向的这个 branch 的最后、也就是的最新的那一个 commit-id 。

所以这里要清楚的一点是,HEAD 并非只能指向一个 branch(它的尾部 commit-id),它其实可以指向任何一个 commit-id 。

checkout 命令

git checkout 应该是 Git 里最复杂的命令,因为会根据后面加的参数的不同,它的底层行为会有很大的差异。这里只提下最简单的。

检出操作,或者理解成查看操作。

git checkout 是检出到某一个分支的意思,执行这个操作以后你的 HEAD 指针就会指向 分支下最后、也就是最新的那个 commit-id 上去,并且你的工作目录( 代码 )也会变成这个 commit-id 状态下的模样。

事实上 git checkout 后面可以加很多别的内容。比如,直接加某个 commit-id:git checkout

这样的意思就是让你的 HEAD 指向某一个 commit-id( 当然你的工作区也会相应刷新 ),这种情况下你不属于任何分支,所以可以理解成 HEAD 处于一种游离态。假如这时你慌了,想回到一个常规状态:

  • 可以选择 git checkout 来切换回任何一个分支;

  • 也可以选择 git branch 来强势地说:“我不后悔!就拿现在这个游离态作为基态建立一个新的伟大分支——newBranchName!”

从此不再游离。

希望你读到这里能够深有体会,因为很多复杂的事情都会建立在各种 checkout 之上。

reset 命令

假如你有连续 4 个 commit:commit-id1commit-id2commit-id3commit-id4 。当你后悔搞了 commit-id3commit-id4 ,你可以反悔并且悄悄: git reset commit-id2 。意思就是说:“我后悔了,悄悄把我后面的脚印擦掉吧,只留到 commit-id2”。

这样操作以后执行 git log 就不会看到你后面 commit-id3commit-id4 的痕迹( 表面上看不到,Git 会给你留途径让你看到痕迹,这里不继续延伸了 )。当然了建议 git reset 后面加一个 --hard 参数让你改写历史的时候工作区也跟上一起刷新,最后推荐的命令是 git reset --hard commit-id2

revert 命令

假如你有连续 4 个 commit:commit-id1 、commit-id2 、commit-id3 、commit-id4 。当你后悔搞了 commit-id3 之后,你可以反悔并公开:git revert commit-id3

这样操作以后你的 commit 树就变成了 commit-id1,commit-id2,commit-id3,commit-id4,commit-id5 这个样子,如果 commit-id3 体现在工作区的变动是 δ 的话,commit-id5 体现在工作区的变动就是 -δ ,是 commit-id3 的反向变动。也就是说 commit-id5 是对 commit-id3 的一种抵消。

reset 与 revert 对比

可见 revert 是有痕迹的反悔,相对于 reset 来说,revert 的后悔不仅没有减少 commit 数量,反而会增加之。

::: tip 友情提示
在没有把本地库和远程库和多人协作搞透彻前,reset命令慎用哦,这里就不再深挖了,有兴趣的老爷们可以另行提问。
:::

还有一个最重要的区别就是:reset 是 “ reset 到 xxx ”;revert 是 “ revert 掉 xxx ”。也就是说:

  • reset 处理的是一个区间,是从 HEAD 到你指定的 commit-id 之间的所有 commit-id 全部抹除,所以很省力;
  • revert 一次命令只能处理一个 commit-id ,所以对于大区间来说会比较费劲。

revert 最主要的一件事情要理解:假如你站在大楼的 10 层,想把第 8 层和第 9 层干掉的话,那么先 revert 第 9 层,再 revert 第 8 层,原因自己分析吧。。

你可能感兴趣的:(Git commit-id)