git基本操作学习
厘清一些概念
什么是分支?
对于日常开发而言,我们说分支的时候,脑海里是根节点到某叶子节点的一条路径,是那条线。实际上git里面并没有“线”的概念,或者说,从来没有说去操作一条线。
个人理解:分支是一个指针,指向某个节点的一个指针。这里说的节点就是每一次提交记录。
分支不是路径,只是简单地指向某个提交纪录。
基本操作
创建分支
使用git branch <分支名>
创建一个分支,上文说过分支是一个指向某节点的指针,那么这句指令执行之后,新建的分支指向的是哪个节点呢?
- 创建前
- 创建后(
git branch newB
)
显然,新分支指向的提交记录和创建时“我”所在的分支一致。*号表示当前所在分支是master而不是newB
切换分支
分支是可以移动、变更的,但是在进行这些操作前,先要切换到该分支上。
git checkout <分支名>
分支的移动
最常见的移动分支操作就是git commit
,执行这个指令,当前分支就会移动到新增的一个提交记录上。
虽然分支只是一个节点的指向,但平常看来就像是从根节点到任意一个节点的路径一样,这就是因为如果只是用git commit
来移动,那么每个分支走过的路径都是独一无二的。
master和newB都在C1节点的时候进行了一次提交,各自产生并指向了一份记录,节点分别为C2、C3
分支的合并
merge
git merge <目标分支名>
--目标分支将要合并到当前分支
把 bugFix 合并到 master 里,首先要处于master分支上,然后合并指令git merge bugFix
可以再把 master 分支合并到 bugFix:
git checkout bugFix;git merge master
这里可以看到和上一步是没变化的,这是因为上一步 bugFix 已经合并到 master 里了,这时候的master指向C4节点,C4是C2和C3的子节点,意味着master是在bugFix基础上的变动,是bugFix子分支,已经包含/覆盖了父分支bugFix。
把子分支合并到父分支上,实际上只是简单地将父分支移动到子分支指向的节点了而已。
rebase
git rebase <目标分支名>
--把当前分支的工作移动到目标分支后面,移动之后看起来是按顺序开发的一条分支
git rebase master
之后:
提交树上自由移动
什么是head?
前文说道分支本质就是一个指针,指向提交记录,这里的head也一样,8指向提交记录或者分支,标记的是“我”的位置。
head指向分支的时候,该分支就是当前分支,head跟随分支移动而移动,
但head是可以在提交记录上自由移动的,不一定要跟随分支。
HEAD分离
当我们git checkout 某分支
的时候,实际上是HEAD指针指向了那个分支,这样看起来好像HEAD总是和某个分支粘在一起,可以git checkout 某提交
来分开head和某分支:
(*号表示HEAD指向该分支,也就是“我”所在的位置)
git checkout C1
切换到某提交后,分支上的*号就不见了,因为HEAD当前指向的是C1这个提交
理解:指向某提交节点的可视为指针,分支就是一种指针;当HEAD指向节点时,HEAD也是一种指针当HEAD指向分支时,HEAD就是指针的指针.
相对引用
- 通过
git log
查看提交记录 - 要写某个节点的哈希值码时不需要全写,只需写前几个字符
- 使用
^
向上移动 1 个提交记录。例:git checkout master^
- 使用
~<num>
向上移动多个提交记录,如~3
强制修改分支:git branch -f master 分支2
会将master强制向分支2提交。
撤销变更
- git reset
后面跟的是历史提交记录,执行之后分支就会回退到该提交的位置 例:git reset HEAD^
- git revert
撤销当前记录,但不是回退,而是向前做一个提交,这个提交与上一个节点相同,但是在提交树上面是一个新的节点。该指令不可操作远程分支。
进阶操作
复制工作
rebase相当于剪贴整个分支的工作到另一个分支上。
cherry-pick这个指令可以复制任意个节点的工作提交到当前节点上。
git cherry-pick C2 C4
一些简写:
git st # git status
git ci # git commit
git br # git branch
git co # git checkout
git mg # git merge
git line # git log --oneline