git给我最大的感觉就是复杂.
为了做到版本控制的能力, 一个文件有三个对应的数据结构, working tree, index, commited. 已经极大地增加了理解的难度.
而一个 git仓库, 有些文件被纳入管理, 有些又不被纳入管理. 在版本切换的时候, 很容易中枪误操作.
除此之外, commit history就像一条时间线, 可是这条时间线居然可以中途分叉出去, 并且和别人的时间线交互,
错综复杂的时间线与分支, 本地与远程, 交织在一起, 使人感到极其混乱.
而git命令同样晦涩难懂, pull fetch , checkout reset revert ,大量语义相近的命令混杂其中,
一个命令随着参数的改变居然可以具有不同的行为.
本文试图理清最令我含糊的两个命令 reset 和checkout, 并指出其模糊之处.
git checkout有两种截然不同的功能, 容易混淆
- 切换branch
- restore 工作区
'git checkout ' 可以切换branch
git checkout branch1 切换到已存在的branch
git checkout -b branch1 新建一个branch并切过去
git checkout 6e9e50e<一个之前的commit-id> 新建一个detach状态的branch
'git checkout -- ' 可以恢复工作区
git checkout -- * 从index中恢复所有文件到工作区
git checkout -- file.c 从index中恢复file.c到工作区
git checkout 与 git reset 都具有版本回退的功能, 容易混淆
git checkout 是从index层面回退, 不涉及commit history
git reset 是从commit层次回退
git reset --soft HEAD^ 默认的行为方式, 仅仅变更HEAD, 不变动 index 和working tree.
git reset --hard HEAD^ HEAD, index, working tree 全部改变