美文网首页
分支管理

分支管理

作者: 李浩然_6fd1 | 来源:发表于2019-05-21 00:10 被阅读0次

    分支的用处:
    就是你与你的同事一起完成一个项目时,你可以自己创建一个分支,这个分支你可以什么时候写代码或者提交都可以,处理完成后你可以将这个分支汇到大的分支上
    个人理解,创建一个分支后,其实就是将工作区的内容复制一封到了另一个区域,比如之前存在主分支叫master,现在复制了一份内容后,存在另一个分支,叫dev,这个分支的内容和主分支一样,可以在dev分支上改动自己想做的内容,然后改动完成后,将其合并到主分支master上

    一、创建与合并分支:
    首先我们创建一个名字叫dev的分支,然后切换到dev分支(cd进入当前learngit文件夹内):


    图片.png

    git checkout命令加上-b参数表示创建并切换,相当于以下两条命令:
    git branch dev
    git checkout dev

    然后,用git branch命令查看当前分支:


    图片.png

    git branch命令会列出所有分支,当前分支前面会标一个*号,目前的分支就是dev。

    然后,我们就可以在dev分支上正常提交,比如对readme.txt做个修改,加上一行:
    Creating a new branch is quick.
    然后提交:


    图片.png

    现在,dev分支的工作完成,我们就可以切换回master分支:


    图片.png

    切换回master分支后,我们再去查看下readme.txt文件,刚才添加的内容不见了!
    因为那个提交是在dev分支上,而master分支此刻的提交点并没有变

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


    图片.png

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

    合并完成后,就可以放心地删除dev分支了:


    图片.png

    删除后,查看branch,就只剩下master分支了:


    图片.png

    因为创建、合并和删除分支非常快,所以Git鼓励你使用分支完成某个任务,合并后再删掉分支,这和直接在master分支上工作效果是一样的,但过程更安全。

    小结
    Git鼓励大量使用分支:

    查看分支:git branch
    创建分支:git branch <name>
    切换分支:git checkout <name>
    创建+切换分支:git checkout -b <name>
    合并某分支到当前分支:git merge <name>
    删除分支:git branch -d <name>

    二、解决冲突
    我认为的冲突就是:新创建分支后,对两个分支的同一个内容修改保存后,用git add 和 gitcommit提交后,当融合一个分支的时候,会出现冲突,因为两个分支的同一个内容都改了。
    上一个实例:
    准备新的feature1分支,继续我们的新分支开发:


    图片.png

    修改readme.txt最后一行,改为:
    Creating a new branch is quick AND simple.
    这样readme.txt的内容就变为了:


    图片.png

    然后在feature1分支上提交:


    图片.png

    然后切换到master分支:


    图片.png

    在master分支上把readme.txt文件的最后一行改为:
    Creating a new branch is quick & simple.
    这样master分支上的readme.txt文件就变成了:


    图片.png

    提交:


    图片.png

    现在,master分支和feature1分支各自都分别有新的提交,变成了这样:


    图片.png

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


    图片.png
    果然冲突了!Git告诉我们,readme.txt文件存在冲突,必须手动解决冲突后再提交。git status也可以告诉我们冲突的文件:
    图片.png

    我们可以打开readme.txt文件来看下现在是什么内容:


    图片.png

    Git用<<<<<<<,=======,>>>>>>>标记出不同分支的内容,我们修改如下后保存:


    图片.png

    再提交:


    图片.png

    用带参数的git log也可以看到分支的合并情况:


    图片.png

    最后,删除feature1分支:


    图片.png

    工作完成。

    小结
    当Git无法自动合并分支时,就必须首先解决冲突。解决冲突后,再提交,合并完成。
    解决冲突就是把Git合并失败的文件手动编辑为我们希望的内容,再提交。
    用git log --graph命令可以看到分支合并图。

    三、分支管理策略
    通常,合并分支时,如果可能,Git会用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息。
    如果要强制禁用Fast forward模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。

    下面我们实战一下--no-ff方式的git merge:
    首先,仍然创建并切换dev分支:


    图片.png

    修改readme.txt文件,并提交一个新的commit:


    图片.png
    图片.png
    以上是我们在dev分支上的操作;下面我们切换回master分支:
    图片.png

    准备合并dev分支,请注意--no-ff参数,表示禁用Fast forward:


    图片.png
    因为本次合并要创建一个新的commit,所以加上-m参数,把commit描述写进去。
    合并后,我们用git log看看分支历史:
    图片.png
    可以看到,不使用Fast forward模式,merge后就像这样:
    图片.png

    分支策略
    在实际开发中,我们应该按照几个基本原则进行分支管理:
    首先,master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;
    那在哪干活呢?干活都在dev分支上,也就是说,dev分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev分支合并到master上,在master分支发布1.0版本;
    你和你的小伙伴们每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。

    小结
    Git分支十分强大,在团队开发中应该充分应用。
    合并分支时,加上--no-ff参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而fast forward合并就看不出来曾经做过合并。

    四、Bug分支
    假如你现在正在dev分支上干活,但是接到通知在master分支上有一个bug需要处理。因为dev分支上的活还没有干完,无法提交,但是master分支上的bug需要马上处理。
    这个就是这节所需要掌握的内容:隐藏现有工作区还未提交的内容,然后去其他分支处理bug:创建新的分支,在新的分支上解决内容,然后融合到master分支上。
    举一个实例:
    比如,我们在dev分支上修改readme.txt,添加保存了最后一句话:


    图片.png

    这个时候因为还没有干完活,没有git add作提交,
    这个时候我们git status,可以看到readme.txt属于未提交的状态;我们用git stash将这个工作区的内容隐藏起来:


    图片.png
    这个时候再来用git status来查看下:
    图片.png
    可以看到工作区是干净的,因为我用git stash隐藏了起来

    现在来修复bug。我们知道了bug在分支master上,那么我们就在master分支上修复,就从master分支上创建临时分支:


    图片.png

    现在修复bug,需要把“Git is free software ...”改为“Git is a free software ...”,然后提交:


    图片.png
    修复完成后,切换到master分支,并完成合并:
    图片.png

    这样的话bug就处理好了,分支issue-101融合到master上了,
    接着我们去dev分支上干完剩下的活。我们转到dev分支上,然后git status查看下情况:


    图片.png
    这个是和我们一开始隐藏后查看的情况一样,工作区还是干净的,我们用git stash list来查看下是什么情况:
    图片.png
    工作现场还在,Git把stash内容存在某个地方了,但是需要恢复一下,有两个办法:
    一是用git stash apply恢复,但是恢复后,stash内容并不删除,你需要用git stash drop来删除;
    另一种方式是用git stash pop,恢复的同时把stash内容也删了。

    我们使用 git stash pop 来试下:


    图片.png

    我们再来用git stash list来查看下是否有隐藏的内容:


    图片.png
    可以看到已经没有隐藏的内容了。
    我们再来打开readme.txt来看下内容:
    图片.png

    这个就是一开始干活自己编辑的内容,现在看到这个,就说明隐藏的内容已经回来了。

    小结
    修复bug时,我们会通过创建新的bug分支进行修复,然后合并,最后删除;
    当手头工作没有完成时,先把工作现场git stash一下,然后去修复bug,修复后,再git stash pop,回到工作现场。

    五、Feature分支
    假如你创建一个Feature分支,在上面开发了一个功能,完了以后等到想合并Feature分支到dev分支上的时候,这个时候突然改变需求:需要删除Feature分支。
    这个就是这节需要掌握的内容:强行删除一个没有被合并过的分支。

    软件开发中,总有无穷无尽的新的功能要不断添加进来。
    添加一个新功能时,你肯定不希望因为一些实验性质的代码,把主分支搞乱了,所以,每添加一个新功能,最好新建一个feature分支,在上面开发,完成后,合并,最后,删除该feature分支。
    现在,你终于接到了一个新任务:开发代号为Vulcan的新功能。
    于是准备开发:


    图片.png

    开发的文件是vulcan.txt:


    图片.png
    然后我们git add和git commit提交:
    图片.png
    切回dev分支,准备把feature-vulcan分支合并到dev分支上:
    图片.png
    但是,还没合并的时候,现在不需要合并了,且需要销毁feature-vulcan分支:
    图片.png

    但是我们看到,用我们之前学过的git branch -d 是销毁不掉的,提示是feature-vulcan这个分支还没有被完全合并,我觉得这样提醒是合理的,因为我们创建了这个feature-vulcan分支,如果就这样常规动作就销毁这个分支,我们很容易就在融合这个分支前就销魂这个分支而导致数据丢失,这个算是提醒,而且也说了,如果真的想删除,运行git branch -D,
    现在我们强行删除:


    图片.png
    小结
    开发一个新feature,最好新建一个分支;
    如果要丢弃一个没有被合并过的分支,可以通过git branch -D <name>强行删除。

    六、多人协作
    这一章讲述的是关于在项目中工作的有关情景,包括推送本地仓库到远程仓库,还包括当你和你的同事都在相同的分支上完成项目,然后推送到远程的时候,遇到了冲突
    这一节所必须掌握的内容是:1、推送本地仓库到远程仓库;2、抓取分支

    当从远程仓库克隆时,实际上就是把本地的master分支和远程仓库的master分支对应起来,且,远程仓库的默认名称是origin。
    要查看远程库的信息,用git remote:


    图片.png

    或者用git remote -v显示更详细的信息:


    图片.png
    上面显示了可以抓取(fetch)和推送(push)的origin的地址(这个地址是我在前面学习的课程中建立的)。如果没有推送权限,就看不到push的地址。

    推送分支
    推送分支,就是把该分支上所有的本地提交推送到远程库。推送时,要指定本地分支,这样Git就会把你指定的本地分支推送到远程库中对应的远程分支上:


    图片.png

    按我的理解,这条指令中,origin是远程仓库的名字,master是本地仓库的名字。所以在这条指令中,必须要有远程仓库和本地仓库,这样才可以对应起来,把本地仓库的内容推到远程仓库中去。
    我的远程仓库在GitHub上,可以看到,更新已经推上去了:


    图片.png
    但是,并不是一定要把本地分支往远程推送,那么,哪些分支需要推送,哪些不需要呢?
    master分支是主分支,因此要时刻与远程同步;
    dev分支是开发分支,团队所有成员都需要在上面工作,所以也需要与远程同步;

    bug分支只用于在本地修复bug,就没必要推到远程了,除非老板要看看你每周到底修复了几个bug;
    feature分支是否推到远程,取决于你是否和你的小伙伴合作在上面开发。

    抓取分支
    多人协作的时候,大家都会往远程仓库中的master和dev分支上推送各自的修改,
    现在,模拟一个你的小伙伴,可以在另一台电脑(注意要把SSH Key添加到GitHub)或者同一台电脑的另一个目录下克隆,
    现在我就在同一台电脑上,找下别的目录(C:\Users\Administrator\gitskills),来克隆一下来自远程端的内容到这个别的目录中:


    图片.png

    去相关的目录下,可以看到learngit文件夹已经到了gitskills中(之前gitskills中只有README.md文件)。
    中间出现了一个小插曲:
    在上面我们用git remote -v来查看远程仓库的具体信息,我们看到的是github.com后面是/,但是,我使用了这个/,git竟然找不到远程仓库:


    图片.png
    可以看到,上面两个截图的远程地址,差别只是在一个是冒号,另一个是/。/这个无法使用,所以我们今后只能用github.com后面是冒号。
    当你的小伙伴从远程库clone时(也就是我在同一个电脑的另一个目录下模拟的),默认情况下,你的小伙伴只能看到本地的master分支。不信可以用git branch命令看看:
    图片.png
    这段按我的理解是,master分支是本地目录默认的,所以也就只能看到master分支。

    现在,你的小伙伴要在dev分支上开发,就必须创建远程origin分支到本地,于是他用这个命令创建本地dev分支:


    图片.png

    这之中出现了一个小问题,廖老师的网站是这样写的:


    图片.png
    所以一开始我也是这样写的,但是怎么创建都创建不了:
    图片.png

    后来我想,其实我也想到我在GitHub上没有origin/dev分支,我想我有learngit仓库,我也就又试了下这个:


    图片.png
    也是出现了相同的结果。后来我就想,我在远端只有一个origin,我就只写了这个,没有在后面带上斜杠以及任何东西,就创建成功了,我想廖老师所说的那样的情况,是因为廖老师origin上有dev分支。

    然后,小伙伴就可以在dev上继续修改(在此添加了新的内容env.txt),保存,然后,把dev分支push到远程:


    图片.png

    这样我的小伙伴已经推送完了他的修改。现在就该我了,我就在我之前所在的目录(learngit)中,做一个同样的修改(增加env.txt):


    图片.png
    修改完成后,我也做同样的提交并且推送:
    图片.png

    我试了好几次,都是推送成功,不知道怎么才能做出因冲突而推送失败的操作。
    那就继续按着老师所说的内容继续下去:
    推送失败,因为你的小伙伴的最新提交和你试图推送的提交有冲突,解决办法也很简单,Git已经提示我们,先用git pull把最新的提交从origin/dev抓下来,然后,在本地合并,解决冲突,再推送:

     git pull
    There is no tracking information for the current branch.
    Please specify which branch you want to merge with.
    See git-pull(1) for details.
       git pull <remote> <branch>
    If you wish to set tracking information for this branch you can do so with:
       git branch --set-upstream-to=origin/<branch> dev
    

    git pull也失败了,原因是没有指定本地dev分支与远程origin/dev分支的链接,根据提示,设置dev和origin/dev的链接:

     git branch --set-upstream-to=origin/dev dev
    Branch 'dev' set up to track remote branch 'dev' from 'origin'.
    

    再pull:

     git pull
    Auto-merging env.txt
    CONFLICT (add/add): Merge conflict in env.txt
    Automatic merge failed; fix conflicts and then commit the result.
    

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

     git commit -m "fix env conflict"
    [dev 57c53ab] fix env conflict
    
     git push origin dev
    Counting objects: 6, done.
    Delta compression using up to 4 threads.
    Compressing objects: 100% (4/4), done.
    Writing objects: 100% (6/6), 621 bytes | 621.00 KiB/s, done.
    Total 6 (delta 0), reused 0 (delta 0)
    To github.com:michaelliao/learngit.git
       7a5e5dd..57c53ab  dev -> dev
    
    

    因此,多人协作的工作模式通常是这样
    首先,可以试图用git push origin <branch-name>推送自己的修改;
    如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并;
    如果合并有冲突,则解决冲突,并在本地提交;
    没有冲突或者解决掉冲突后,再用git push origin <branch-name>推送就能成功!
    如果git pull提示no tracking information,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream-to <branch-name> origin/<branch-name>。
    这就是多人协作的工作模式,一旦熟悉了,就非常简单。

    小结
    查看远程库信息,使用git remote -v;
    本地新建的分支如果不推送到远程,对其他人就是不可见的;
    从本地推送分支,使用git push origin branch-name,如果推送失败,先用git pull抓取远程的新提交;
    在本地创建和远程分支对应的分支,使用git checkout -b branch-name origin/branch-name,本地和远程分支的名称最好一致;
    建立本地分支和远程分支的关联,使用git branch --set-upstream branch-name origin/branch-name;
    从远程抓取分支,使用git pull,如果有冲突,要先处理冲突。

    以上是我看廖雪峰老师的网站,然后做的学习摘抄,无意侵犯老师作品,如有侵犯,我会删除。

    相关文章

      网友评论

          本文标题:分支管理

          本文链接:https://www.haomeiwen.com/subject/xmvvaqtx.html