git 分支
1. git仓库的数据存储
假如我们一次提交了3个对象,git仓库中的数据如下:
Git 仓库中有五个对象:三个表示文件快照内容的 blob 对象;一个记录着目录树内容及其中各个文件对应 blob 对象索引的 tree 对象;以及一个包含指向 tree 对象(根目录)的索引和其他提交信息元数据的 commit 对象。
多次提交后,数据变为:
2. git 分支的本质
Git分支本质上是一个指向commit对象的可变指针。git使用master作为分支的默认名字。
可以使用git branch命令创建分支:
Administrator@6XIGRIJ0JJDRMSP MINGW64 /e/guotengfei/git/RAP (release)
$ git branch testing
git 中有个特别的指针HEAD,这是一个指向你正在工作中的本地分支的指针。
使用 git checkout 切换分支
Administrator@6XIGRIJ0JJDRMSP MINGW64 /e/guotengfei/git/RAP (release)
$ git checkout testing
Switched to branch 'testing'
Administrator@6XIGRIJ0JJDRMSP MINGW64 /e/guotengfei/git/RAP (testing)
切换分支不仅会把HEAD指针修改,还会把工作目录转换成该分支指向的快照内容。
由于 Git 中的分支实际上仅是一个包含所指对象校验和(40 个字符长度 SHA-1 字串)的文件,所以创建和销毁一个分支非常廉价。Git 鼓励开发者频繁使用分支,正是因为有着这些特性作保障。
3. 基本分支合并
3.1 分支创建、合并
为什么要频繁使用分支,先看个简单例子:
1. 开发某个项目。
2. 为实现某个新的需求,创建一个分支。
3. 在这个分支上开展工作。
假设此时,你突然接到一个电话说有个很严重的问题需要紧急修补,那么可以按照下面的方式处理:
1. 返回到原先已经发布到生产服务器上的分支。
2. 为这次紧急修补建立一个新分支。
3. 测试通过后,将此修补分支合并,再推送到生产服务器上。
4. 切换到之前实现新需求的分支,继续工作。
新建并切换分支使用 git checkout -b name.
切换分支需要注意:你的暂存区或者工作目录里,那些还没有提交的修改,它会和你即将检出的分支产生冲突从而阻止 Git 为你转换分支。转换分支的时候最好保持一个清洁的工作区域。
使用git merge name 命令进行分支合并。
git branch -d name 删除分支。
如图所示,合并两个分支,Git 会用两个分支的末端(C4 和 C5)和它们的共同祖先(C2)进行一次简单的三方合并计算。然后对三方合并的结果作一新的快照,并自动创建一个指向它的 commit(C6)。
3.2 冲突解决
假如合并过程中发生冲突,需要先解决冲突。任何包含未解决冲突的文件都会以未合并(unmerged)状态列出,可以使用git status查看。
解决冲突以后使用git add命令标记文件为已解决。最后用git commit来完成这次合并提交。
4. 分支管理
git branch 查看当前分支
Administrator@6XIGRIJ0JJDRMSP MINGW64 /e/guotengfei/git/RAP (testing)
$ git branch
release
* testing
Administrator@6XIGRIJ0JJDRMSP MINGW64 /e/guotengfei/git/RAP (testing)
$ git branch -v
release e45a5fe0 Merge branch 'master' into release
* testing e45a5fe0 Merge branch 'master' into release
要从列表中筛选出你已经(或尚未)与当前分支合并的分支,可以用 –merge 和 –no-merged 选项。
Administrator@6XIGRIJ0JJDRMSP MINGW64 /e/guotengfei/git/RAP (testing)
$ git branch --merge
release
* testing
Administrator@6XIGRIJ0JJDRMSP MINGW64 /e/guotengfei/git/RAP (testing)
$ git branch --no-merged
git branch -D testing D强制删除分支。
5. 分支式工作流
可以根据不同的稳定性创建不同层次的分支。
6. 远程分支
分支是一个索引,远程分支是对远程仓库状态的索引。我们用 (远程仓库名)/(分支名) 这样的形式表示远程分支。
clone 操作会自动在本地创建一个origin/master的远程分支和master本地分支。
git remote add 命令把另外的远程仓库加为当前项目的远程分支之一。
6.1 推送分支
git push [远程名] [本地分支]:[远程分支]
推送本地分支到远程仓库
或者使用git push [远程名] [本地分支]
别人从远程仓库会获取到这个远程分支,但需要创建自己的本地分支。
可以使用命令:
git checkout -b name origin/name
6.2 跟踪分支
从远程分支检出的本地分支叫做跟踪分支。clone时会自动创建master跟踪分支。可以使用
git checkout -b name origin/name
或者
git checkout –track origin/name
在跟踪分支里,git push 会自动推送数据,git pull 会获取所有远程索引,并合并到本地。
6.3 删除远程分支
git push [远程名] :[分支名]
删除远程分支。
7. 衍合
merge 和rebase 唯一的区别就是产生的提交历史不一样。
rebase原理是回到两个分支(你所在的分支和你想要衍合进去的分支)的共同祖先,提取你所在分支每次提交时产生的差异(diff),把这些差异分别保存到临时文件里,然后从当前分支转换到你需要衍合入的分支,依序施用每一个差异补丁文件。
merge:
rebase:
7.1 有趣的衍合
你可以在衍合分支以外的地方衍合。
使用 –onto选项可以把client分支衍合到master上。
git rebase –onto master server client
7.2 衍合的风险
永远不要衍合哪些已经推送到公共仓库的更新。