git的一些概念

147 阅读3分钟

提交

一次提交其实就是一系列文件、元数据和父引用的快照,git对其进行了hash计算,得到一个16进制40个字符的字符串,用这个hash来代表这次提交(在.git文件夹下的object文件夹中,存在着hash值与快照的映射关系) 。由于每一次提交都带有父提交的引用,引用链也可以构建起来。

分支引用

当你创建一个分支的时候,会在.git/refs/heads/目录下新建一个文件,文件名就是分支的名称,文件内容是一个提交的hash值,所以分支引用只是一个提交的引用,但是由于引用链的存在,分支就可以是一系列的提交。当你在最新的提交下再次提交的时候,分支引用会更新

Head指针

Head指针可用于指向分支引用和具体的提交(所以git checkout 有切换分支和回退版本两个用途),因为分支引用会指向最新提交,也可以说head指向了最新提交。

理解了上面的内容后,再说一下git checkout命令和 git reset命令,这两个命令都可以用于回退版本

  1. git checkout

    git checkout 是修改了Head指针的指向,指向一个具体的hash值,然后,根据hash值取得文件快照,将工作区中的文件恢复到指定提交时(暂存区无更改时才会允许git checkout)。此时,处于头指针分离的状态,即Head指针并不指向某一个分支引用。我们可以说此时Head并不处于某一分支上,那么对应的push,pull,merge等对分支进行的操作都无法完成。同时,如果你想在回退的版本上进行某些操作,可以使用git checkout -b 创建一个新的分支,因为你的这些操作是无法修改当前分支的。

  2. git reset

    git reset和git checkout的不同点在于,git reset修改了分支引用的指向,为指定的hash值。也就是说,git reset是对分支进行了操作,而git checkout,可能仅仅只是回退查看一下,不影响分支。当我们对最近几次提交不满意的时候,就可以使用git reset退回,git reset有三个选项可以选择:

    -- soft --mixed --hard

    抛开死记硬背,不妨分析一下场景:

    1. 如果你觉得某次提交之后写的代码非常糟糕,那么,就可以使用git reset --hard,彻底地恢复到那一个版本。工作区和暂存区都被重置

    2. 如果你觉得文件的修改是正确的,但没必要提交那么多次,就可以使用--mixed和--soft,因为不修改工作区,那么此时提交的快照和仓库的区别是很大的,这些差异是在暂存区还是先为暂存呢,就是soft和mixed的区别了,不过我觉得这二者用起来区别不大。