Git 分支管理详解

简介:

大纲:

1.前言

2.创建分支

3.切换分支

4.合并分支(快速合并)

5.删除分支

6.分支合并冲突

7.合并分支(普通合并)

8.分支管理策略

9.团队多人开发协作

10.总结

注,测试机 CentOS 5.5 x86_64,Git 服务器版本:git version 1.8.2.1,客户端版本:git version 1.9.2.msysgit.0。所有软件请到这里下载:http://msysgit.github.io/


1.前言

在上一篇博客中我们主要讲解了Git 远程仓库,相信大家对远程的Git仓库有一定的了解,嘿嘿。在这一篇博客中我们来在大家讲解一下Git 分支管理,这可以说是Git的又一大特点。下面我们就来学习一下Git分支管理吧。


我们先来说一个简单的案例吧,你们团队中有多个人再开发一下项目,一同事再开发一个新的功能,需要一周时间完成,他写了其中的30%还没有写完,如果他提交了这个版本,那么团队中的其它人就不能继续开发了。但是等到他全部写完再全部提交,大家又看不到他的开发进度,也不能继续干活,这如何是好呢?


对于上面的这个问题,我们就可以用分支管理的办法来解决,一同事开发新功能他可以创建一个属于他自己的分支,其它同事暂时看不到,继续在开发分支(一般都有多个分支)上干活,他在自己的分支上干活,等他全部开发完成,再一次性的合并到开发分支上,这样我们既可知道他的开发进度,又不影响大家干活,是不是很方便呢?


大家可能会说了,你Git的分支功能人家SVN也有啊,也没什么特殊的嘛。但我想说你那个创建和切换速度怎么样呢?嘿嘿,我想说谁用谁知道啊!但Git呢,无论你创建还是切换或者删除都很快哦!


分支本质上其实就是一个指向某次提交的可变指针。Git 的默认分支名字为 master 。而我们是怎么知道当前处于哪个分支当中呢?答案就是在于 HEAD 这个十分特殊的指针,它专门用于指向于本地分支中的当前分支。我们可以简单理解为:commit <- branch <- HEAD (注,本来我们详细说一下HEAD的,这个东西真不好说,goole了一下也没几个大神说这个,嘿嘿。下面我就通过讲解帮助大家理解,简单的说HEAD就是指向于本地分支中的当前分支,如下图:) 下面我们来创建分支。


2.创建分支

当我们需要调试某个Bug或者尝试添加或修改程序中的某个模块,而又不能影响主分支的开发时。就可以通过创建分支来满足需求。创建分支相当于是创建一个新的分支指针指向当前所在的提交。我们在Commit3上创建dev分支:

git branch1

如下图所示,dev分支指向Commit3。

Branch3

从上图可知,虽然我们创建了一个新分支,但是 HEAD 仍然指向 master 。如果希望在创建分支的同时切换到新分支上,我们可以通过以下命令实现:

git branch2

git checkout命令加上-b参数表示创建并切换分支上。


3.切换分支

切换当前分支我们可以用以下命令实现:

git branch3

git branch -a 命令可以查看所有分支,现在我们HEAD指针便指向dev分支,大家可以在上图中看到dev分支上有个*号。

Branch4

下面我们修改一下readme.txt中的内容,并在dev分支上提交一下。如下图:

git branch4

用流程图演示上述过程如下:

git branch8

现在我们在dev分支上完成工作,现在到master分支上。如下图:

Branch5

流程图表示如下:

git branch7

切换回master分支后,再查看一个readme.txt文件,如下图:

Branch6

大家可以看到我们刚才增加的一行内容不见了,嘿嘿。因为那个提交是在dev分支上,而master分支没有变化。好了,下面我们来演示一下合并分支。


4.合并分支(快速合并)

现在,我们把dev分支的工作成果合并到master分支上,如下图:

git branch5

git merge 命令用于合并指定分支到当前分支。合并后,再查看readme.txt的内容,就可以看到,和dev分支的最新提交是完全一样的。如下图:

git branch6

大家注意到上面的Fast-forward信息,Git告诉我们,这次合并是“快进模式”,也就是直接把master指向dev的当前提交,所以合并速度非常快。当然,也不是每次合并都能Fast-forward,我们后面会将其他方式的合并。合并完成后,就可以放心地删除dev分支了。


5.删除分支

下面我们来演示一下删除分支,如下图:

git branch9

大家在实际操作中可以发现在我们创建、合并、删除分支的速度非常快吧,这和直接在master分支上工作效果是一样的,但过程更安全,更可靠。下面我们来简单的总结一下:

  • 查看分支 git branch -a

  • 创建分支 git branch name

  • 切换分支 git checkout name

  • 创建并切换 git checkout -b name

  • 合并某分支到当前分支 git merge name

  • 删除分支 git branch -d name


6.分支合并冲突

下面我们来演示一下不同分支修改同一个文件产生冲突问题,下面我们来创建一个新的分支,继续开发新功能:

Branch7

现在我们将分支切换到master分支上修改readme.txt内容并提交,如下图:

Branch8

这种情况下,Git无法执行“快速合并”,只能试图把各自的修改合并起来,但这种合并就可能会有冲突,如下图:

git branch10

果然冲突了,Git告诉我们readme.txt文件存在冲突,必须手动解决冲突后再提交。下面我们用git status查看一下状态:

git branch11

下面我们来查看一下readme.txt中的内容,如下图:

branch9

Git用<<<<<<<,=======,>>>>>>>标记出不同分支的内容,让我们选择要保留的内容,下面我们修改一下readme.txt,再次提交。如下图:

branch10

好了,到这我们的分支合并冲突就讲解完成了,下面我们来删除分支。如下图:

branch11

最后,我们可以用 git log --graph --pretty=oneline --abbrev-commit 命令,查看一下分支合并。


7.合并分支(普通合并)

分支合并分为快速合并与普通合并两种模式,普通合并,合并后的历史有分支记录,能看出来曾经做过合并,而快速合并就看不出来曾经做过合并。下面我们来演示一下普通合并,

branch12

大家可以看到我们这次合并用的普通模式合并,--no-ff参数表示禁用快速合并。下面我们用git log命令查看一下合并历史:

branch13

注,合并分支时,加上--no-ff参数就可以用普通模式合并,合并后的历史有分支记录,能看出来曾经做过合并,而fast forward合并就看不出来曾经做过合并。如下图:

1).快速合并

f1

2).普通合并

f2


8.分支管理策略

下面我们来说一下一般企业中开发一个项目的分支策略:

  • 主分支 master

  • 开发分支 develop

  • 功能分支 feature

  • 预发布分支&#160; release

  • bug 分支 fixbug

  • 其它分支 other


1).主分支 master

代码库应该有一个、且仅有一个主分支。所有提供给用户使用的正式版本,都在这个主分支上发布。

merge1

Git主分支的名字,默认叫做Master。它是自动建立的,版本库初始化以后,默认就是在主分支在进行开发。


2).开发分支 develop

主分支只用来分布重大版本,日常开发应该在另一条分支上完成。我们把开发用的分支,叫做Develop。

merge2

这个分支可以用来生成代码的最新代码版本。如果想正式对外发布,就在Master分支上,对Develop分支进行"合并"(merge)。


3).功能分支 feature

功能分支,它是为了开发某种特定功能,从Develop分支上面分出来的。开发完成后,要再并入Develop。

merge3

功能分支的名字,可以采用feature-*的形式命名。


4).预发布分支&#160; release

预发布分支,它是指发布正式版本之前(即合并到Master分支之前),我们可能需要有一个预发布的版本进行测试。预发布分支是从Develop分支上面分出来的,预发布结束以后,必须合并进Develop和Master分支。它的命名,可以采用release-*的形式。


5).bug 分支 fixbug

bug分支。软件正式发布以后,难免会出现bug。这时就需要创建一个分支,进行bug修补。修补bug分支是从Master分支上面分出来的。修补结束以后,再合并进Master和Develop分支。它的命名,可以采用fixbug-*的形式。

merge4


6).其它分支 other

还有就是其它分支了,大家可以根据需要创建即可……


9.团队多人开发协作

在上面的章节中我们讲解了Git的分支管理策略,一般开发团队中有这样几个分支,master、develop、feature、release、bug、other分支,或者你还有其它分支,那有博友会问了,你讲了那么多分支,都在本地放着我们怎么查看和推送分支到远程服务器上呢?嘿嘿,我们说大家别急我们在这一章节中就来重点讲解,在团队多人协作中的分支推送与抓取。


1).查看远程仓库分支

查看远程仓库的信息,如下图:  
remote1

大家可以看到git remote命令可以查看远程仓库,加-v选项可以查看详细信息。上面显示了你抓取和推送的origin(源)信息。 当你从远程仓库克隆时,实际上Git自动把本地的master分支和远程的master分支对应起来了,并且远程仓库的默认名称是origin。


2).分支推送

下面我们来演示一下将本地分支推送到远程的仓库中,如下图:

remote2

大家可以看到,我们的本地master分支与远程的master分支已同步。下面我们来演示一下同步dev分支,如下图:

remote3

有博友会问了,我本地有很多分支,有哪些分支需要推送到远程仓库中呢?一般是这样的,

  • master 分支是主分支,要时刻与远程同步,一般我们发布最新版本就用master分支

  • develop 分支是开发分支,团队中所有人都在这个分支上开发,所以也需要与远程同步

  • bug 分支一般只在本地使用来修复bug,一般不需推送远程仓库中

  • feature 分支是否需要推送到远程,要看是不是有几个人合作开发新功能,如果你是一个开发,那就留在本地吧

  • release 分支一般是系统管理,推送或抓取的分支一般与开发人员无关

  • other 分支大家按需求分配


3).分支抓取

现在你一同事在电脑上克隆一份仓库,我们来演示一下。

生成公钥:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
[root@localhost ~] # ssh-keygen -t rsa  
Generating public /private  rsa key pair.  
Enter  file  in  which  to save the key ( /root/ . ssh /id_rsa ): 
 
   
Enter passphrase (empty  for  no passphrase): 
 
   
Enter same passphrase again: 
 
   
Your identification has been saved  in  /root/ . ssh /id_rsa .  
Your public key has been saved  in  /root/ . ssh /id_rsa .pub.  
The key fingerprint is:  
60:a6:f3:71:d1:1e:0f:5f:3f:0c:6f:a3:61:4c:28:c0 root@localhost.localdomain  
The key's randomart image is:  
+--[ RSA 2048]----+  
|& #160;&#160;&#160;&#160;&#160; ..&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; |  
|& #160;&#160;&#160;&#160;&#160;&#160; E..&#160; .&#160;&#160;&#160; |  
|& #160;&#160;&#160;&#160;&#160; + ..+. o.&#160; |  
|& #160;&#160;&#160;&#160; + . o.=o.+. |  
|& #160;&#160;&#160; o . S . o+ *.|  
|& #160;&#160;&#160;&#160; o o&#160;&#160;&#160; . + o|  
|& #160;&#160;&#160;&#160;&#160; .&#160;&#160;&#160;&#160;&#160; .&#160;&#160; |  
|& #160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; |  
|& #160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; |  
+-----------------+  
[root@localhost ~]
 
   
[root@localhost ~] # cd .ssh/  
[root@localhost . ssh ] # cat id_rsa.pub 
 
   
ssh -rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAx /ms/8BGBrG2FwHNySjFsVdpldArSzS6CkrdFeqJd0YAZfo/e2RwyZ9HkBqp3xcBZxCRdifnPbfSHdACLbVALfw2Dj6s0jJmdg3AHth13hF1qeljlQarXTTkheHNuFhi3OF/MVKZXJh0jRT2xU9UL4GRrtodOmclU6DelBFbqlw7yCj0TFXZSZk3UmHPHG3I2E3il/7jWdqw0qsys85rUL/Ugs50RUcFn53avqUiAYSU +neXiLmHmshCLVpdbDiOxRjfFPVjTgLh88hDLwkcYL4Lrzc5My3glgiEjrSn43WxDdbOiGUyZz1TdJKNngq7OJK+SuA /FkMEA +pXoTIAwQ== 
root@localhost.localdomain


将生成的公司增加到git服务器上:

1
2
3
[root@ test  ~] # cat /data/git/.ssh/authorized_keys  
ssh -rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAwMU4FKB6NRc3XSoIunWsdvVVuSoncbVb5Al6lB3ciswBVd++YmJFhqwkITNGccrO5sycROs9+Fbjgd6oBSzNuaBtCIbwNNsEyM /henTl2euI3XsnJQ/ITr6c/q0P3WoGl4E2QFQ2kZqs +1eDC0CgHcBrqvFv1Jr414sVYK9lfZwIF+jDdtaBOrSJuq1Agx9pGUFUEB4tQfkXxsWm /MvOmKAVvduKDE1eenUEL9zzyeELPcSXLe3NOoTjZhkX6EEXxQR1ZiZRFywLpfM4qopZ10to2KIUyVtzw6hx6V3cg7kn40lYVW0EAMATw9dVldwcRUI +kJzJSKUTKDVSwY3/+Q== root@CHENMINGQIAN  
ssh -rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAx /ms/8BGBrG2FwHNySjFsVdpldArSzS6CkrdFeqJd0YAZfo/e2RwyZ9HkBqp3xcBZxCRdifnPbfSHdACLbVALfw2Dj6s0jJmdg3AHth13hF1qeljlQarXTTkheHNuFhi3OF/MVKZXJh0jRT2xU9UL4GRrtodOmclU6DelBFbqlw7yCj0TFXZSZk3UmHPHG3I2E3il/7jWdqw0qsys85rUL/Ugs50RUcFn53avqUiAYSU +neXiLmHmshCLVpdbDiOxRjfFPVjTgLh88hDLwkcYL4Lrzc5My3glgiEjrSn43WxDdbOiGUyZz1TdJKNngq7OJK+SuA /FkMEA +pXoTIAwQ== root@localhost.localdomain

克隆远程版本库:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[root@localhost . ssh ] # cd /data/  
[root@localhost data] # ls  
lost+found  
[root@localhost data] # git --version  
git version 1.7.1  
[root@localhost data] # git clone git@192.168.18.201:/data/git/project1.git  
Initialized empty Git repository  in  /data/project1/ .git/  
The authenticity of host  '192.168.18.201 (192.168.18.201)'  can't be established.  
RSA key fingerprint is 3b:52:6b:ea:4d:50:7c:b2:9e:66:e4:0e:2e:21:98:be.  
Are you sure you want to  continue  connecting ( yes /no )?  yes  
Warning: Permanently added  '192.168.18.201'  (RSA) to the list of known hosts.  
remote: Counting objects: 20,  done .  
remote: Compressing objects: 100% (12 /12 ),  done .  
remote: Total 20 (delta 4), reused 0 (delta 0)  
Receiving objects: 100% (20 /20 ),  done .  
Resolving deltas: 100% (4 /4 ),  done .  
[root@localhost data] # ls  
lost+found& #160; project1  
[root@localhost data] # cd project1/  
[root@localhost project1] # ls  
readme.txt

我们现在查看一下分支:

1
2
3
[root@localhost project1] # git branch 
   
* master

你同事要在dev分支上开发,就得创建与远程origin一样的dev分支到本地的仓库上,下面我们来创建一下:

1
2
3
4
5
[root@localhost project1] # git checkout -b dev origin/dev  
Branch dev  set  up to track remote branch dev from origin.  
Switched to a new branch  'dev'  
[root@localhost project1] # git branch  * dev  master  
[root@localhost project1] #

现在你同事就可以在dev分支上开发了,下面我们新建一些文件并提交到远程dev分支:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[root@localhost project1] # touch index.html  
[root@localhost project1] # vim index.html
This git  test  index.html!
[root@localhost project1] # git add index.html 
[root@localhost project1] # git commit -m "add index.html"  
[dev 6e47de0] add index.html   
Committer: root <root@localhost.localdomain> 
Your name and email address were configured automatically based  on your username and  hostname .Please check that they are accurate.  
You can suppress this message by setting them explicitly:
git config --global user.name  "Your Name"  
  git config --global user.email you@example.com
If the identity used  for  this commit is wrong, you can fix it with:
git commit --amend --author= 'Your Name <you@example.com>'
1 files changed, 1 insertions(+), 0 deletions(-)   create mode 100644 index.html  
[root@localhost project1] # git config --global user.name "leo"  
[root@localhost project1] # git config --global user.email "leo@jjhh.com"  
[root@localhost project1] # git commit -m "add index.html"  
# On branch dev  # Your branch is ahead of 'origin/dev' by 1 commit. 
#  nothing to commit (working directory clean)  
[root@localhost project1] # git status  
# On branch dev  # Your branch is ahead of 'origin/dev' by 1 commit.  
#  nothing to commit (working directory clean)
[root@localhost project1] # git push origin dev  
Counting objects: 4,  done .  Delta compression using up to 4 threads.  
Compressing objects: 100% (2 /2 ),  done .  Writing objects: 100% (3 /3 ), 305 bytes,  done .  
Total 3 (delta 0), reused 0 (delta 0)  To git@192.168.18.201: /data/git/project1 .git  
58f4fae..6e47de0; dev –> dev

你的同事向origin/dev分支提交了一个index.html页面,现在你也在修改这个文件,并提交:

remote4

推送失败,因为你同事的最新提交和你推送的提交有冲突,Git提示我们,先用git pull把最新的提交从origin/dev抓下来,然后在本地合并解决冲突,再推送:

remote5

git pull 失败了,原因是没有将dev分支与远程origin/dev分支进行链接,Git提示我们设置dev和origin/dev的链接:

remote6

下面我们再来git pull一下试试:

remote7

git pull 成功,但是合并有冲突需要手动解决,解决的方法和分支管理中的解决冲突完全一样。解决后提再push:

remote9

remote8

remote10

好了,这样的我们的远程推送与抓取就讲解完成了,下面我们来总结一下。


10.总结

一般在团队中多人开发模式是这样的:

  • 首先,可以试图用git push origin branch-name推送自己的修改

  • 如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并

  • 如果合并有冲突,则解决冲突,并在本地提交

  • 没有冲突或者解决掉冲突后,再用git push origin branch-name推送就能成功

如果git pull提示“no tracking information”,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream branch-name origin/branch-name。


好了,到这里我们的Git分支管理就讲解到这里了。最后,希望大家有所收获^_^……


















本文转自陈明乾51CTO博客,原文链接:本文转自陈明乾51CTO博客,原文链接:,如需转载请自行联系原作者,如需转载请自行联系原作者

相关文章
|
9月前
|
存储 安全 开发工具
深度解决 Git “fatal: refusing to merge unrelated histories” 错误解析什么是历史分支优雅草卓伊凡
深度解决 Git “fatal: refusing to merge unrelated histories” 错误解析什么是历史分支优雅草卓伊凡
783 4
深度解决 Git “fatal: refusing to merge unrelated histories” 错误解析什么是历史分支优雅草卓伊凡
|
6月前
|
开发工具 git
Git版本控制工具合并分支merge命令操作流程
通过以上步聚焦于技术性和操作层面指南(guidance), 可以有效管理项目版本控制(version control), 并促进团队协作(collaboration).
1466 15
|
开发工具 git
图解Git——分支的新建与合并《Pro Git》
在Git开发中,新建与合并分支是常见的操作。以实际开发为例:为实现新需求创建分支`iss53`进行开发;遇紧急Bug时,切换至线上分支创建`hotfix`修复并合并回线上分支,再切换回`iss53`继续工作。完成`iss53`后,切换到`master`合并。若出现冲突,使用`git status`查看,手动编辑解决冲突后标记为已解决并提交。图形化工具如`git mergetool`也可辅助解决冲突。
332 9
|
开发工具 git 开发者
图解Git——分支简介《Pro Git》
Git 分支是其核心特性之一,允许开发者从主开发线分离工作,避免干扰主线。传统版本控制系统创建分支效率低,而Git的分支创建和切换非常轻量高效。
706 9
|
开发工具 git 开发者
vscode+git解决远程分支合并冲突
通过这些详细步骤,您可以掌握如何使用VSCode和Git高效地解决远程分支合并冲突,提高开发效率和代码质量。希望这些内容对您的学习和工作有所帮助。
2990 86
|
安全 开发工具 git
图解Git——分支管理《Pro Git》
分支管理是 Git 中的重要机制,支持并行开发和清晰的工作流。常用命令包括:`git branch` 列出所有分支,`git branch -v` 查看最后一次提交,`git branch --merged` 和 `git branch --no-merged` 分别查看已合并和未合并的分支。创建新分支用 `git branch &lt;branch-name&gt;`,删除分支用 `git branch -d`(已合并)或 `-D`(强制删除)。建议定期清理已完成任务的分支,保持代码库整洁,并使用有意义的分支命名规范。注意强制删除未合并分支时可能丢失数据。
361 5
|
存储 项目管理 开发工具
图解Git——分支开发工作流《Pro Git》
分支开发工作流利用Git的分支功能,支持灵活的项目管理。长期分支如`master`和`develop`分别保存稳定和开发中的代码;短期主题分支用于开发单一特性或修复问题,完成后合并到主分支。此模式确保代码稳定性,支持并行开发、便于审查和灵活调整。建议维护明确的长期分支,保持主题分支短小精悍,并定期清理无用分支。配置上可保护关键分支,遵循命名规范。
547 7
|
存储 缓存 Java
图解Git——远程分支《Pro Git》
远程分支是 Git 中用于管理分布式协作的关键概念。远程引用指向远程仓库中的分支和标签,常用 `git ls-remote` 或 `git remote show` 查看。日常开发中,通常使用远程跟踪分支(如 `origin/main`)与远程分支交互,简化远程仓库状态的管理和使用。远程跟踪分支记录远程分支的状态,但本身只读。
361 6
|
开发工具 git
git学习四:常用命令总结,包括创建基本命令,分支操作,合并命令,压缩命令,回溯历史命令,拉取命令
这篇文章是关于Git常用命令的总结,包括初始化配置、基本提交、分支操作、合并、压缩历史、推送和拉取远程仓库等操作的详细说明。
386 1
git学习四:常用命令总结,包括创建基本命令,分支操作,合并命令,压缩命令,回溯历史命令,拉取命令
|
开发工具 git 开发者
关于git 解决分支冲突问题(具体操作,包含截图,教你一步一步解决冲突问题)
本文通过具体操作和截图,详细讲解了如何在Git中解决分支冲突问题,包括如何识别冲突、手动解决冲突代码、提交合并后的代码,以及推送到远程分支。
4256 3
关于git 解决分支冲突问题(具体操作,包含截图,教你一步一步解决冲突问题)