文档章节

Git详解之3 Git 分支

fokYaland
 fokYaland
发布于 2015/06/04 17:26
字数 2658
阅读 9
收藏 0
git
Git 中的分支,其实本质上仅仅是个指向 commit 对象的可变指针。Git 会使用  master  作为分支的默认名字。在若干次提交后,你其实已经有了一个指向最后一次提交对象的 master 分支,它在每次提交的时候都会自动向前移动。


创建一个新的分支指针。比如新建一个 testing 分支
git branch testing


它保存着一个名为  HEAD  的特别指针。请注意它和你熟知的许多其他版本控制系统(比如 Subversion 或 CVS)里的 HEAD 概念大不相同。在 Git 中,它是一个指向你正在工作中的本地分支的指针(译注:将 HEAD 想象为当前分支的别名。)。 运行git branch 命令,仅仅是建立了一个新的分支,但不会自动切换到这个分支中去 ,所以在这个例子中,我们依然还在 master 分支里工作

切换到其他分支,这样 HEAD 就指向了 testing 分支
git checkout testing


如果这时候进行一些修改,然后提交, 每次提交后 HEAD 随着分支一起向前移动



现在返回master分支
git checkout master


分支的新建与合并
首先,我们假设你正在项目中愉快地工作,并且已经提交了几次更新

现在,你决定要修补问题追踪系统上的 #53 问题,新建一个分支
git checkout -b iss53

这相当于执行下面这两条命令:
$   git branch  iss53
$   git checkout  iss53

接着你开始尝试修复问题,在提交了若干次更新后,iss53 分支的指针也会随着向前推进,因为它就是当前分支(换句话说,当前的 HEAD 指针正指向 iss53,见图 3-12):


现在你就接到了那个网站问题的紧急电话,需要马上修补。有了 Git ,我们就不需要同时发布这个补丁和 iss53 里作出的修改,也不需要在创建和发布该补丁到服务器之前花费大力气来复原这些修改。唯一需要的仅仅是切换回master 分支。

不过在此之前,留心你的暂存区或者工作目录里,那些还没有提交的修改,它会和你即将检出的分支产生冲突从而阻止 Git 为你切换分支。切换分支的时候最好保持一个清洁的工作区域。
git checkout master

接下来,你得进行紧急修补。我们创建一个紧急修补分支 hotfix 来开展工作,直到搞定
git checkout -b 'hotfix'



然后回到 master 分支并把它合并进来,然后发布到生产服务器
git checkout master
git merge hotfix
Updating f42c576..3a0874c
Fast forward
 README |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)
请注意,合并时出现了“ Fast forward”的提示。由于当前 master 分支所在的提交对象是要并入的 hotfix 分支的直接上游,Git 只需把master 分支指针直接右移。换句话说, 如果顺着一个分支走下去可以到达另一个分支的话,那么 Git 在合并两者时,只会简单地把指针右移,因为这种单线的历史分支不存在任何需要解决的分歧,所以这种合并过程可以称为快进(Fast forward)。


由于当前 hotfix 分支和 master 都指向相同的提交对象,所以hotfix 已经完成了历史使命,可以删掉了
$   git branch -d hotfix

回到之前未完成的 #53 问题修复分支上继续工作
git checkout iss53

在问题 #53 相关的工作完成之后,可以合并回 master 分支。实际操作同前面合并 hotfix 分支差不多,只需回到master 分支,运行 git merge 命令指定要合并进来的分支
$   git checkout master
$   git merge iss53
Merge made by recursive.
 README |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
请注意,这次合并操作的底层实现,并不同于之前 hotfix 的并入方式。因为这次你的开发历史是从更早的地方开始分叉的。由于当前 master 分支所指向的提交对象(C4)并不是 iss53 分支的直接祖先,Git 不得不进行一些额外处理。就此例而言,Git 会用两个分支的末端(C4 和 C5)以及它们的共同祖先(C2)进行一次简单的三方合并计算



这次,Git 没有简单地把分支指针右移,而是对三方合并后的结果重新做一个新的快照,并自动创建一个指向它的提交对象(C6)(见图 3-17)。这个提交对象比较特殊,它有两个祖先(C4 和 C5)。
值得一提的是 Git 可以自己裁决哪个共同祖先才是最佳合并基础;这和 CVS 或 Subversion(1.5 以后的版本)不同,它们需要开发者手工指定合并基础。所以此特性让 Git 的合并操作比其他系统都要简单不少。
有时候合并操作并不会如此顺利。如果在不同的分支中都修改了同一个文件的同一部分,Git 就无法干净地把两者合到一起(译注:逻辑上说,这种问题只能由人来裁决。)。如果你在解决问题 #53 的过程中修改了hotfix 中修改的部分,将得到类似下面的结果:
$   git merge iss53
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.

要看看哪些文件在合并时发生冲突,可以用 git status 查阅
E:\Repositories\GitHub\testing [master +0 ~0 -0 !1 | +0 ~0 -0 !1]>   git status
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#   (use "git push" to publish your local commits)
#
# You have unmerged paths.
#   (fix conflicts and run "git commit")
#
#   Unmerged  paths:
#   (use "git add <file>..." to mark resolution)
#
#       both modified:      tem.txt
#
no changes added to commit (use "git add" and/or "git commit -a")

任何包含未解决冲突的文件都会以未合并(unmerged)的状态列出。Git 会在有冲突的文件里加入标准的冲突解决标记,可以通过它们来手工定位并解决这些冲突。可以看到此文件包含类似下面这样的部分:
hello
<<<<<<< HEAD
master add
=======
new
>>>>>>> testing

解决冲突的办法无非是二者选其一或者由你亲自整合到一起,同时删除了 <<<<<<<,======= 和 >>>>>>> 这些行。
在解决了所有文件里的所有冲突后,运行   git add  将把它们标记为已解决状态

如果觉得满意了,并且确认所有冲突都已解决,也就是进入了暂存区,就可以用   git commit 来完成这次合并提交

分支的管理
给出当前所有分支的清单
E:\Repositories\GitHub\testing [master]>   git branch
* master
  testing

查看各个分支最后一个提交对象的信息,运行 git branch -v

要从该清单中筛选出你已经(或尚未)与当前分支合并的分支,可以用   --merge    --no-merged  选项
git branch --merged

利用分支进行开发的工作流程
长期分支
许多使用 Git 的开发者都喜欢用这种方式来开展工作,比如仅在 master 分支中保留完全稳定的代码,即已经发布或即将发布的代码。与此同时,他们还有一个名为develop 或 next 的平行分支,专门用于后续的开发,或仅用于稳定性测试 — 当然并不是说一定要绝对稳定,不过一旦进入某种稳定状态,便可以把它合并到master 里。这样,在确保这些已完成的特性分支(短期分支,比如之前的 iss53 分支)能够通过所有测试,并且不会引入更多错误之后,就可以并到主干分支中,等待下一次的发布。

本质上我们刚才谈论的,是随着提交对象不断右移的指针。稳定分支的指针总是在提交历史中落后一大截,而前沿分支总是比较靠前(见图 3-18)。



特性分支
在任何规模的项目中都可以使用特性(Topic)分支。一个特性分支是指一个短期的,用来实现单一特性或与其相关工作的分支。可能你在以前的版本控 制系统里从未做过类似这样的事情,因为通常创建与合并分支消耗太大。然而在 Git 中,一天之内建立、使用、合并再删除多个分支是常见的事。

我们在上节的例子里已经见过这种用法了。我们创建了 iss53 和 hotfix 这两个特性分支,在提交了若干更新后,把它们合并到主干分支,然后删除。该技术允许你迅速且完全的进行语境切换 — 因为你的工作分散在不同的流水线里,每个分支里的改变都和它的目标特性相关,浏览代码之类的事情因而变得更简单了。你可以把作出的改变保持在特性分支中几 分钟,几天甚至几个月,等它们成熟以后再合并,而不用在乎它们建立的顺序或者进度。

现在我们来看一个实际的例子。请看图 3-20,由下往上,起先我们在 master 工作到 C1,然后开始一个新分支 iss91 尝试修复 91 号缺陷,提交到 C6 的时候,又冒出一个解决该问题的新办法,于是从之前 C4 的地方又分出一个分支iss91v2,干到 C8 的时候,又回到主干 master 中提交了 C9 和 C10,再回到 iss91v2 继续工作,提交 C11,接着,又冒出个不太确定的想法,从 master 的最新提交 C10 处开了个新的分支dumbidea 做些试验。



现在,假定两件事情:我们最终决定使用第二个解决方案,即 iss91v2 中的办法;另外,我们把 dumbidea 分支拿给同事们看了以后,发现它竟然是个天才之作。所以接下来,我们准备抛弃原来的iss91 分支(实际上会丢弃 C5 和 C6),直接在主干中并入另外两个分支。最终的提交历史将变成图 3-21 这样:


请务必牢记这些分支全部都是本地分支,这一点很重要。 当你在使用分支及合并的时候,一切都是在你自己的 Git 仓库中进行的 — 完全不涉及与服务器的交互


本文转载自:http://blog.csdn.net/yanliang1/article/details/12035891

fokYaland
粉丝 4
博文 68
码字总数 3062
作品 0
东城
私信 提问
Git 分支详解

Git 分支 有人把 Git 的分支模型称为“必杀技特性”,而正是因为它,将 Git 从版本控制系统家族里区分出来。Git 有何特别之处呢?Git 的分支可谓是难以置信的轻量级,它的新建操作几乎可以在...

passionfly
2016/03/16
70
0
git 常用命令详解

最重要2命令: git clone git://github.com/schacon/grit.git 从服务器上将代码给拉下来 git pull 本地与服务器端同步 一、 Git 命令初识 在正式介绍Git命令之前,先介绍一下Git 的基本命令和...

1321385590
2017/11/14
0
0
git 使用详解(8)-- 分支HEAD

有人把 Git 的分支模型称为“必杀技特性”,而正是因为它,将 Git 从版本控制系统家族里区分出来。Git 有何特别之处呢?Git 的分支可谓是难以置信的轻量级,它的新建操作几乎可以在瞬间完成,...

shzwork
04/19
0
0
Git详解之三 Git分支

Git 分支 几乎每一种版本控制系统都以某种形式支持分支。使用分支意味着你可以从开发主线上分离开来,然后在不影响主线的同时继续工作。在很多版本控制系统中,这是个昂贵的过程,常常需要创...

小代码2016
2015/12/22
64
0
github使用常见问题

1.github本地使用多个key 本地多个key + 不管linux还是win,要在.ssh/下新建个config。 2. remote origin already exists fatal: remote origin already exists. 3. git push后提示 everythi......

im天行
2015/10/23
41
0

没有更多内容

加载失败,请刷新页面

加载更多

分布式场景下如何保证消息队列实现最终一致性

考虑一个分布式场景中一个常见的场景:服务A执行某个数据库操作成功后,会发送一条消息到消息队列,现在希望只有数据库操作执行成功才发送这条消息。下面是一些常见的作法: 1. 先执行数据库...

中关村的老男孩
29分钟前
4
0
招银网络面试题、考点、知识点总结(Java岗)

java基础 全是基础不用多说肯定考的多,尤其是招银 OOP特性/java语言特性:封装、继承、多态 多态具体的表现:多态应用举例、如何调用父类方法(super)、重写和重载(重写父类方法的规则、构...

戎码益深
34分钟前
2
0
Mybatis深入源码分析之SQLSession一级缓存原理分析

源码分析图

须臾之余
37分钟前
2
0
成年人社交中的10个潜规则

前阵子我建议大家有空的时候,一定要去看《红楼梦》这本书。 原因就是从这本书,可以学习到很多很多人情世故,人情世故在学校里,老师几乎都不会教,所以我们只能靠自己去学。 只有自己去学了...

ZhangLG
39分钟前
4
0
在PyCharm中使用Pylint

简介 pylint是一个用于检查python代码中的错误,尝试强制执行编码标准的工具。它还可以查找某些类型错误,可以建议如何重构特定块的建议,并可以向您提供有关代码复杂性的详细信息。 官网:w...

哼_哼
40分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部