本文会从git中最重要的分支概念入手,帮助你们更好的理解git分支的本质,从而对操做分支时对其原理了然于心,最后顺便分享在团队内工做流常用的git rebase的两个小技巧。git
目录bash
- git简介
- 分支
- rebase的两个用法
git是个分布式和渐进式的版本管理工具。分布式是指代码能够克隆不少份,不像svn(集中式版本管理工具)集中对一份代码进行版本管理,而git容许你将项目fork成本身一份。而渐进式是指git会智能的diff代码的改动状况,但不是记录文件的具体变化,而是保存一系列不一样时刻的文件快照。分布式
为了更好的使用git去解决一些复杂的版本冲突问题,有必要先理解git的分支。工具
快照gitlab
其实要理解git的分支,首先要了解git是如何保存文件的
git以文件快照的方式保存文件的更改状况,而不是cope每一份代码
那么如何理解文件快照的?ui
快照,咱们能够把它抽象为照片,能够想象一下用相机拍下桌子上物体,照片记录着每一个时刻物体的位置和状态,git就是把这每一个照片保存起来,等须要的时候指定一张照片来把物体摆设成这个样子spa
暂存3d
在暂存时,git把每一个文件当作一个blob对象,把快照保存进blob对象里面,而后就加进暂存区域等待提交指针
提交
commit的时候,git会生成一个数对象来记录这个目录结构(包括子目录)和blob对象的索引,还会生成一个commit对象来保存一个指向这个树对象的指针和其余一些提交信息(msg,time,author,email)
有了这个指针,就能够方便追溯到此次commit的文件快照,来重现这个时刻的文件状态
以上的是首次提交的状况,在第二次提交时
在原有的状况下,git再生成一个指针去指向上一次的commit对象,咱们称之为父对象
分支指针
既然git是经过指针去追溯文件快照的,那么是否是能够建立多几个指针去多拿几张照片,进而多重现几个状态呢?
因此分支就是所谓的指针,那么git又是怎么知道我在哪一个分支上呢?
没错,再建立一个指针去指向这个分支指针,来表示我当前所在的分支。
可是冲突是如何产生的呢?
看个图就明白了
使用命令查看分支的指向状况,或者说项目的分叉状况
git log --oneline --decorate --graph --all
复制代码
1. 合并commit
你确定也试过这样的场景,leader交给你一个小需求,一个小时不到就解决了,提交一个commit,但过了一会,以为代码还有能够改进的地方,做为一个努力上进的人,你确定不会只求完成需求这么简单,因此再提了一版...
但这个几个commit都是为了同一个需求开发的,leader去review代码的时候,几个commit还好,但实际开发中有时是十几个commit,这样对于review代码和追踪版本时,就显的尤其困难了
因此须要将为同一个需求开发的这些commit合并成一个
git rebase -i HAED~n
复制代码
上面的n代指数字,表示包括当前之前的几个commit
这是会出现一个编辑界面
pick 5e187c7dbe8 add center style indent
pick 6d577eb3440 add center style
pick f9b9508a3ab add center style
pick 111ab9cc261 update templates
# Rebase 150a643..2fad1ae onto 150a643
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
复制代码
把第二到四行的pick更改成s,就会使用这个commit,而且合并前个commit
若出现冲突,解决冲突,应用最新的版本,使用
git add . //提交索引
git rebase --continue //继续rebase操做
复制代码
若在合并commit的过程当中想放弃,可使用命令
git rebase --abort
复制代码
此时会出现一个编辑窗口,保存退出就行
最后把本地推上远程
git push -f //必须带上-f,以本地覆盖远程
或者指定远程和分支
git push (origin master) -f
复制代码
由于本地的几个commit已经合并成了一个,而若远程还有这几个commit,须要以本地覆盖远程
2. 合并分支
有以下分支图
git merge dev
复制代码
此时分支图就变为
git rebase master
复制代码
git add .
git rebase --continue
复制代码
随时放弃
git rebase --abort
复制代码
在拉去远程更新时也可使用rebase
git pull --rebase
或者指定远程和分支
git pull upstream master --rebase
复制代码
ps:
假若经过git pull --rebase致使在gitlab上发merge request时,出现了其余人的本已经提交了的commit信息,不妨用使用
git reset --soft <commitID> //保留更改回退
复制代码
再次commit,在gitlab再发merge request,应该就干净了(只是本身的提交信息)
回到最初
解决git复杂问题的前提仍是得先看的明白git的分支图,清晰每条命令对git分支的影响。