zoukankan      html  css  js  c++  java
  • Git分支管理

    ​大纲:

    1.前言

    2.创建分支

    3.切换分支

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

    5.删除分支

    6.分支合并冲突

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

    8.分支管理策略

    9.团队多人开发协作

     

    2.创建分支

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

    创建分支:git branch dev

    显示分支:git branch -a

     

    git branch1

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

     

    Branch3

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

    创建并切换分支:git checkout -b dev

     

    git branch2

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

     

    3.切换分支

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

    切换分支:git checkout dev

     

    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 merge dev

     

    git branch5

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

     

    git branch6

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

     

    5.删除分支

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

    删除分支:git branch -d dev

     

    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内容并提交,如下图:

     

    Branch8g

    这种情况下,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.合并分支(普通合并)

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

    普通合并:git merge --no-ff -m "merge with no -ff" dev

     

    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).分支抓取

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

    生成公钥:

    [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服务器上:

    [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


    克隆远程版本库:

    克隆远程版本库:

    [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

    我们现在查看一下分支:

    [root@localhost project1]# git branch
    * master
    你同事要在dev分支上开发,就得创建与远程origin一样的dev分支到本地的仓库上,下面我们来创建一下:
    [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分支:

    [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 –> de

    你的同事向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。

     

  • 相关阅读:
    c#项目架构搭建经验
    c++ template怎么使用及注意事项
    c++怎么将一个类,拆分出接口类,和实现类
    c++l类
    错过C++
    Fixed 鸟粪一样的TreeView下的NodeMouseDoubleClick Bug
    Oracle 12C 新特性之表分区带 异步全局索引异步维护(一次add、truncate、drop、spilt、merge多个分区)
    Oracle 12C 新特性之在线重命名、迁移活跃的数据文件
    Oracle 12C 新特性之级联truncate
    Oracle 12C 新特性之扩展数据类型(extended data type)
  • 原文地址:https://www.cnblogs.com/wzyxidian/p/5516768.html
Copyright © 2011-2022 走看看