Git学习--分支

分支简介

假设现在有一个工作目录,里面包含了三个将要被暂存和提交的文件。

暂存操作会为每一个文件计算校验和(SHA-1 哈希算法),然后会把当前版本的文件快照保存到 Git 仓库中(Git 使用 blob 对象来保存它们)

$ git add README test.rb LICENSE
$ git commit -m 'The initial commit of my project'

当使用 git commit 进行提交操作时,Git 会先计算每一个子目录(本例中只有项目根目录)的校验和,然后在 Git 仓库中这些校验和保存为树对象。

随后,Git 便会创建一个提交对象,它除了包含上面提到的那些信息外,还包含指向这个树对象(项目根目录)的指针。如此一来,Git 就可以在需要的时候重现此次保存的快照。

Git 仓库中有五个对象:三个 blob 对象(保存着文件快照)、一个树对象(记录着目录结构和 blob 对象索引)以及一个提交对象(包含着指向前述树对象的指针和所有提交信息)

105524_kO2n_2510955.png

图1 首次提交对象及其树结构

修改后再次提交,提交对象会包含一个指向上次提交对象(父对象)的指针

105715_zt2I_2510955.png

 图2 提交对象及其父对象

 Git 的分支,其实本质上仅仅是指向提交对象的可变指针

 

分支创建

它只是创建了一个可以移动的新指针。 比如,创建一个 testing 分支, 使用 git branch 命令:

$ git branch testing

110451_tqnE_2510955.png

两个指向相同提交历史的分支

名为 HEAD 的特殊指针,可以理解为当前分支的别名,git branch 只是创建一个新分支,并不会自动切换到新分支上去

 

110647_KdsE_2510955.png

HEAD 指向当前所在的分支

分支切换

$ git checkout testing

 

111246_adNm_2510955.png

 

 

 

 

 

 

 

HEAD 指向当前所在的分支

查看各个分支当前所指的对象

$ git log --oneline --decorate
f30ab (HEAD, master, testing) add feature #32 - ability to add new
34ac2 fixed bug #1328 - stack overflow under certain conditions
98ca9 initial commit of my project

会输出你的提交历史、各个分支的指向以及项目的分支分叉情况

$ git log --oneline --decorate --graph --all
* c2b9e (HEAD, master) made other changes
| * 87ab2 (testing) made a change
|/
* f30ab add feature #32 - ability to add new formats to the
* 34ac2 fixed bug #1328 - stack overflow under certain conditions
* 98ca9 initial commit of my project

 

 

分支新建与合并

任务:工作分支-->线上分支-->新建分支-->修改bug-->合并新分支和线上分支-->推送线上分支-->删除新建的分支-->回到工作分支

$ git checkout -b iss53
Switched to a new branch "iss53"
$ git branch iss53
$ git checkout iss53

112800_d0tH_2510955.png

创建一个新分支指针

开始在iss53分支修改

$ vim index.html
$ git commit -a -m 'added a new footer [issue 53]'

112905_hrnN_2510955.png

iss53 分支随着工作的进展向前推进

现在你接到那个电话,有个紧急问题等待你来解决。假设你已经把你的修改全部提交了,这时你可以切换回master 分支了:

$ git checkout master
Switched to branch 'master'

这个时候,你的工作目录和你在开始 #53 问题之前一模一样,现在你可以专心修复紧急问题了。 

建立一个针对该紧急问题的分支(hotfix branch),在该分支上工作直到问题解决:

$ git checkout -b hotfix
Switched to a new branch 'hotfix'
$ vim index.html
$ git commit -a -m 'fixed the broken email address'
[hotfix 1fb7853] fixed the broken email address
 1 file changed, 2 insertions(+)

113344_Lzfw_2510955.png

基于master 分支的紧急问题分支hotfix branch

然后将其合并回master 分支来部署到线上。 使用git merge 命令来达到上述目的:

$ git checkout master
$ git merge hotfix
Updating f42c576..3a0874c
Fast-forward
 index.html | 2 ++
 1 file changed, 2 insertions(+)

 

113652_YRUE_2510955.png

 

 

 

 

 

 

 

 

master 被快进到 hotfix

删除hotfix分支,因为你已经不再需要它了, master 分支已经指向了同一个位置。 你可以使用带-d 选项的git branch 命令来删除分支:

$ git branch -d hotfix
Deleted branch hotfix (3a0874c).

切回iss53继续开发

$ git checkout iss53
Switched to branch "iss53"
$ vim index.html
$ git commit -a -m 'finished the new footer [issue 53]'
[iss53 ad82d7a] finished the new footer [issue 53]
1 file changed, 1 insertion(+)

114101_Wk0c_2510955.png

 

 

 

 

 

继续iss53分支上的工作

注意:你在hotfix 分支上所做的工作并没有包含在iss53 分支中

合并iss53到master分支

$ git checkout master
Switched to branch 'master'
$ git merge iss53
Merge made by the 'recursive' strategy.
index.html |    1 +
1 file changed, 1 insertion(+)

 

master 分支所在提交并不是 iss53 分支所在提交的直接祖先,Git 不得不做一些额外的工作。 出现这种情况的时候,Git 会使用两个分支的末端所指的快照(C4 和 C5)以及这两个分支的工作祖先(C2),做一个简单的三方合并。

114500_2OJK_2510955.png

一次典型合并中所用到的三个快照

git 将此次三方合并的结果做了一个新的快照并且自动创建一个新的提交指向它。 这个被称作一次合并提交,它的特别之处在于他有不止一个父提交。

114605_r7dy_2510955.png

一个合并提交

删除iss53分支

$ git branch -d iss53

 

 

分支管理

git branch: 分支列表

git branch -v: 查看每个分支的最后提交

git branch --merged: 查看哪些分支已经合并到当前分支中

git branch --no-merged: 查看哪些分支没有合并到当前分支中

 

 

分支开发工作流

  • 长期分支:比如develop, next, 用来做后续开发或测试稳定性,一旦到达稳定状态,就合并到master分支

143100_wxxG_2510955.png

渐进稳定分支的流水线(“silo”)视图

 

  • 特性分支:一种短期分支,用来实现单一特性或短期工作,比如iss53和hotfix

 

远程分支

145558_PHZa_2510955.png

克隆之后的服务器与本地仓库

 

你在本地的 master 分支做了一些工作,同一时间,其他人推送提交到 git.ourcompany.com 并更新了它的 master 分支,那么你的提交历史将向不同的方向前进。 也许,只要你不与 origin 服务器连接,你的 origin/master 指针就不会移动

145805_6LvY_2510955.png

本地与远程的工作可以分叉

 

要同步你的工作,运行 git fetch origin 命令。 这个命令查找 “origin” 是哪一个服务器(在本例中,它是 git.ourcompany.com),从中抓取本地没有的数据,并且更新本地数据库,移动 origin/master 指针指向新的、更新后的位置

150013_kqZH_2510955.png

git fetch 更新你的远程仓库引用

 

跟踪分支

从一个远程跟踪分支检出一个本地分支会自动创建一个叫做 “跟踪分支”(有时候也叫做 “上游分支”)。 跟踪分支是与远程分支有直接关系的本地分支

git checkout -b [branch] [remotename]/[branch]

等同于:

git checkout --track [remotename]/[branch]

比如:

git checkout -b serverfix origin/serverfix

git checkout --track origin/serverfix

 

想为本地分支与远程分支设定不同的名字:

$ git checkout -b sf origin/serverfix
Branch sf set up to track remote branch serverfix from origin.
Switched to a new branch 'sf'

 

删除远程分支

$ git push origin --delete serverfix
To https://github.com/schacon/simplegit
 - [deleted]         serverfix

 

 

变基

整合分支有两种方法:merge(合并)及rebase(变基)

153303_Ao5c_2510955.png

分叉的提交历史

 

153407_PKkp_2510955.png

通过合并操作来整合分叉了的历史

 

变基:提取在 C4 中引入的补丁和修改,然后在 C3 的基础上应用一次。 使用 rebase 命令将提交到某一分支上的所有修改都移至另一分支上,就好像“重新播放”一样

$ git checkout experiment
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: added staged command

 

153549_fJni_2510955.png

将C4 中的修改变基到C3上

 

回到master, 快速合并

$ git checkout master
$ git merge experiment

 

154015_KwDV_2510955.png

master 分支的快进合并

 

 

 

参考资料:https://git-scm.com/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E7%9A%84%E6%96%B0%E5%BB%BA%E4%B8%8E%E5%90%88%E5%B9%B6

转载于:https://my.oschina.net/u/2510955/blog/836729

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值