源栈培训:项目管理:Git分支和工作流

更多
2019年05月15日 20点26分 作者:叶飞 修改

为了理解分支,我们可以思考这样一个场景(单人开发):

  1. 2020年6月1日:项目上线。然后,你继续进行一个大的feature开发,把代码弄得“有点乱”
  2. 2020年6月3日:在已上线的产品上发现了一个亟需处理的bug

这时候,你怎么办?

  • 在现有的代码上直接修复bug,需要等手头的feature完成才行
  • 回退到项目上线时的版本,会丢失已完成的部分feature代码

为了解决这个问题,最好是在发布项目的时候,就在源代码上建一个分支(branch)


新建和切换

在VS的Team Explorer中:Branches - New Branch:

勾选Checkout,创建分支之后就会理解切换到新建的分支release上。



master分支

git仓库自动创建的一个master分支,我们通常会用该分支作为“主”分支:即大家共用的、主力维护着的分支。

但实际上,git中各个分支是“平等”的,master作为主分支只是约定俗成,没有什么特殊含义或强制性……


当前分支

git上所有提交,都是提交到当前分支

所以一定要注意随时查看,VS上有两个地方非常方便:

  • VS右下方:

  • Team Explorer - Branches中粗体

选择(双击)相应的branch,可以进行切换(checkout)

在进行commit时,也能看到当前分支:

演示:分别在master和release上进行若干次commit,这些提交

  • 在工作区
  • 和History中


    注意History后面 - 标明了分支

都互不影响。


merge

把release分支上新提交的内容,复制到master分支上,这就是merge。

注意

  • merge是“单向”的不是“同步”的,从release到master,只会将release上新提交的内容复制到master上,会将master的内容复制到release。
  • History的graph栏“分支图片”只有当:
    1. 显示的是整个git仓库的提交记录
    2. 分支已经被merge之后
    才会显示出来。

    从graph也可以看出:分支本身没有“主/从”。



delete

branch被merge之后,可以删除。删除branch不会删除branch上的提交。



conflict

一般情况下,git会智能merge,进行增删。

但是,当两个分支相同的位置都出现了不同的更改,git就无法自动merge,会报出conflict,要求我们resolve:

  • 文本
  • GUI


背后原理

和其他版本控制工具不同,无论是再仓库还是工作区,git都没有真正的为每个分支创建“副本”。

换言之,无论多少个分支,git中只有一个连贯的提交记录。



HEAD

git使用HEAD来确定当前活跃(正在被使用)的分支

工作区总是“对标/比较/一致”HEAD指向的提交


新建分支



每一个分支都是一个“指针”

实际上是创建一个新的“指针”,指针指向(当前分支中的)最后一次提交



不会让HEAD改变指向,改变HEAD的指向需要checkout。



切换分支

每一次,实际上就是 ???

(checkout)


checkout实际上是将HEAD指向新的分支

checkout会更新工作区文件


提交

一次提交,本质上是一条内容更改的记录,但该条记录同时记录着它的上一次。

即:让当前分支指向此次(最近的)提交


  • 在不同的分支上进行提交
  • 会演化出“分叉”






  • git log 添加参数 --decorate --graph --all 可以显示具体分支情况

演示:略

合并(merge)


远程分支

复习:clone到本地

自动给远程仓库命名为origin,并在本地创建远程的活跃分支(不一定是master哟),同时创建若干指向远程分支的指针:origin/master、origin/release……

在以前学习的同步命令后面加上非默认的远程分支:

git fetch [remote] [branch]    #仅仅是fetch,不会更新本地
git merge [remote]/[branch]    #注意是路径形式
git pull  [remote] [branch]    #pull = fetch + merge
git push [remote] [branch]     #推送到远程(需要先在本地创建)
演示:略

说明:

  • git push时可以指定远程的分支:
    1. 如果不指定,默认同本地分支名
    2. 如果远程上没有这个分支,自动创建一个
  • push到远程仓库的分支不能正在被checkout
  • 如果 git fetch 不指定分支,将获取所有分支信息/数据
  • git merge可以将远程分支合并到本地分支(不需要同名)


理解:

  • 远程分支存储在本地
  • 除非fetch,本地保存的远程分支不会改变
  • 以前的远程操作使用的是默认的远程分支





工作流

Git超级轻便的分支功能,为工作流带来超多选择,常见的分支名称有:

  • master:长期/共有/主流的develop分支
  • release:用于发布的分支,
  • hot bug fix):一般只打补丁
  • feature:开发各种新feature
  • ……


Git开发模式

常用的(以Github为例)有两种:

  • collaborators:
    1. 服务器上只有一个公用repository,向所有developer开放读/写权限
    2. 所有developers都向自己本地repository commit,
    3. 然后直接往公用repository上push
    这里要注意:先pull再push
  • fork:
    1. 服务器上有一个权威(官方)repository,repository向所有人开放读权限,禁止写权限
    2. 所有developer在服务器上有自己的fork(如果得到认可,fork其实也可以成为权威……
    3. 可以向自己的fork push,但无法向权威repository 直接push
    4. 向别人的repository/fork提交内容,只能发出一股pull request,请求他人pull,然后由他人push

优缺点分析:

  • collaborators:方便。但是不便于代码质量控制,什么内容都可以往repository里提……通常是“信得过”的团队内部成员才能成为collaborator
  • fork:不方便。但是自主性/控制性高,通常用于并不熟悉的分散的开源开发中……



团队开发(尤其是开源项目)

  • 我愿意其他(不特定的)人参与项目开发,但我不愿意他们直接提交代码
  • 我愿意使用这个源代码,但我还想自己做一些定制开发给自己用,但同时还想一直跟着源代码“进化”
  • ……

事实上,方便快捷的分支功能,才是git的核心优势!





作业

  • 使用VS git完成:
    1. 新建两个分支,如:hotfix和t1
    2. 切换到hotfix,在hotfix上进行若干提交
    3. 修改hotfix上再上一次的提交后重新提交
    4. 讲hotfix上的修改合并到master上
    5. 删除hotfix分支
    6. 将上述修改全部push到远程仓库,确保远程仓库和本地具有相同的分支
    7. 在远程仓库新建一个分支faq
    8. 在本地跟踪远程分支faq
    9. 在远程和本地faq上交错的提交更改,然后merge
  • 使用VS和github
    1. 将其他某个同学添加成collaborator,让其能够直接push到你的repository
    2. 在github上fork一个项目成员的repoistory
    3. 克隆到本地,review其代码,进行一处修改(bug fix/refactor/feature等均可),提交推送
    4. 发起 一个 pull request
    5. 当其他项目成员发起pull request时,检查并完成其请求




  1. 彻底删除hotfix上最近的一次提交


源栈 bootstrap JavaScript
赞: 667 踩: 0

打赏
已收到打赏的 帮帮币

你的 打赏 非常重要!
为了保证文章的质量,每一篇文章的发布,都已经消耗了作者 1 枚 帮帮币
没有“帮帮币”,作者无法发布新的文章。

全系列阅读
评论 / 0

编程基础


项目管理相关

需求发布、开发规划、部署、测试,源代码版本管理(git)等……

逸闻史话

认识计算机

编程语言

数据结构和算法

Web开发基础

全部
关键字



帮助

反馈