码迷,mamicode.com
首页 > 其他好文 > 详细

分布式版本控制系统Git------分支管理与合并(merge与rebase)

时间:2016-04-26 22:14:47      阅读:253      评论:0      收藏:0      [点我收藏+]

标签:

零、需要使用到的命令:

       git branch                                  查看当前分支。
       git branch <name>                    创建一个名为<name>的分支。
       git checkout <name>                切换到名字为<name>的分支。
       git checkout -b <nama>             创建一个名为<name>的分支并且切换到此分支(等于git branch <name>命令 + git checkout <name>命令)。
       git merge <name>                     把一个名为<name>的分支合并到当前分支。
       git branch -d <name>                删除一个名为dev的分支。

       git merge   <分支名>                 把<分支名>合并到当前分支
       git rebase   <分支名>                把<分支名>合并到当前分支(与merge不同)

       git fetch<主机名> <分支名>       将版本库中的内容取回本地
       git pull <远程主机名> <远程分支名>:<本地分支名>                        将版本库中的内容取回本地并和<本地分支名>合并(merge合并方式)。
       git pull --rebase<远程主机名> <远程分支名>:<本地分支名>         将版本库中的内容取回本地并和<本地分支  名>合并(rebase合并方式)。 
        
       git stash                                        备份当前工作区的内容至git栈,再从最近的一次commit提交覆盖到当前工  作区。
       git stash list                                 显示当前git栈所有的备份
       git stash pop                                从git栈中恢复一次内容至工作区,默认是恢复最近的一次
       git stash clear                               清空git栈。
        

一、简单介绍一下分支的基本操作。

        先看看分支创建  ->  切换  ->  提交  ->  合并  ->  删除的基本套路吧。
        使用上面的几个命令可以实现最基础的分支操作。
        1.创建分支 git branch name
技术分享

技术分享
        2.查看当前所有分支 git branch
技术分享

技术分享
        当前有两个分支,分别是master和gzl
        3.切换分支 git checkout name
技术分享

        git提示当前已经切换到分支gzl
        4.在分支上修改文件或者添加一个新的文件,在分支上进行一个commit。
技术分享

技术分享
        5.回到master分支 git checkout master
技术分享

技术分享
        这个时候的打开master分支的test.txt文件看看
技术分享技术分享
        发现test.txt文件回到了没有更改的之前的内容。这是因为我们修改是在gzl分支的,而不是master分支。可以将分支看成一个个平行空间,你在其中修改并不会影响到其他分支的内容。
        6.合并gzl分支的内容到master分支 git merge gzl
技术分享
技术分享
        这里采用的Fast-forward合并方式,即快速合并。也就是说,只是把master指向了gzl分支。
        7.删除gzl分支  git branch -d gzl
技术分享
技术分享
        再用git branch 命令查看,发现只剩下了master分支了。
技术分享
技术分享

        Fast forward模式:如果顺着一个分支走下去可以达到另外一个分支的话,那么git合并的时候,就只要简单的把master指针往后移。因为这种单线的操作不需要合并不同的分支,所以不会产生分歧,所以称为Fast forward模式。
        普通模式:在一个commit节点发生分支,有两个不同的分支,如果想要合并这两个分支,这个时候不能室友Fast forward模式。往往需要手动修改产生冲突的文件,然后在进行一次commit。

二、合并分支的两种方式

            前面使用的是git的merge合并方式,分支还有一种合并方式叫做rebase衍合。
            rebase衍合与merge合并最终的结果其实是一样的,但是执行的过程却是不相同的。

            merge方式(合并):

            技术分享
            看看官方文档里面的示例图,master分支合并experiment分支,将会产生一个新的C5快照,而且只要你不删除experiment分支它就会一直存在。C5分支就像C4和C3两根绳子连在一起样子,这样C5既有了C4的内容,也有了C3的内容
                

            rebase方式(衍合):


            rebase流程

       (以下图是已经rebase之后的结果图):

                1.首先切换到C4所在的experiment分支。
                2.从C4开始向前找,直到找到和master分支最近的一个相同commit快照,C4和C4之前的所有commit快照生成patch文件
                3.强制转化到master分支,从C2开始,将上面生成的patch文件,从C2开始往下一个一个打上patch文件
                4.最后生成新的C4‘commit快照,它之前所在的分支experiment也随着它的改变指向了master的上游。最后可以使用Fast forward方式让master分支和experiment保持一致。

           注意: rabase在第三步之中会发生冲突。
            在这种情况,Git会停止rebase并会让你去解决 冲突;在解决完冲突后,用"git-add"命令去更新这些内容的索引(index), 然后,你无需执行 git-commit,只要执行:
            git rebase --continue
            这样git会继续应用(apply)余下的补丁。
            在任何时候,你可以用--abort参数来终止rebase的行动,并且"mywork" 分支会回到rebase开始前的状态。
            git rebase --abort

            技术分享

                rebase的优势和劣势


        可以看到当使用rebase方式的时候,产生了C4‘快照,这个快照和merge方式得到的快照是一样的。可是不一样的地方还有有的。
                1.experiment分支从独立的分支,到和master分支相同的上游去了。
                2.C4快照消失了。
        乍一看没什么,可是仔细想想,如果你在C4修改了一次重要的操作,可是使用rebase方式合并之后,你的C4却丢失,那么会造成不可忽略的影响。
        通过查看文档,rebase方式有优势也有劣势:

优势:

        采用rebase方式合并的快照,在主分支上看起来就像是一条平行线一样整洁干净,让人一目了然,这样管理人员就不需要花费时间去整理分                                                                                              分支了。                

劣势:

        就像上张图那样,采用rebase方式合并之后,以前的分支的快照都会消失。引用文档的概括的一句话------

                Do not rebase commits that exist outside your repository.
        为什么会这样,文档上的例子很生动,我大概翻译一下:
        如果你rebase一个文件,放弃了目前的修改,然后创建了一个新的看起来相同可是内容却不同的 快照一 。如果你将这个快照放到网上或者其他地方,别人pull下了它,然后按照这个为基准进行工作。这个时候你又重写了它并且使用了git rebase方法把它上传到了网上称为  快照二,你的同事将会被这个新的快照搞得头昏眼花。因为他们是基于你第一次快照来进行开发的,可是你使用rebase命令之后,你的快照一将会消失,那么你同事做的事情就会白费。

        那么如果你面临这样的情况,改怎么办呢?别担心,还是有机会挽回损失的。
        如果你面临这样的困难,那么你所面临的第一个挑战就是分辨出哪些是你写的,哪些是你同事写的。
        原来commit 对象除了SHA-1计算校验之外,Git还基于你引进的补丁计算了一种校验码,叫做“patch-id”。
        如果你从你同事那里拉下重改的代码是基于最新的一次提交,Git也能也能够成功的解决而且申请它回到一个新的分支上。
        使用git rebase teamone/master命令。
                1.找到唯一工作在分支上的commit快照。
                2.找到没有合并的commit快照。
3.找到没有被改写的commit快照加入目标分支。
4.应用这些commit快照在master分支和teamone分支。
        但是它只工作在旧commit快照C4和新快照C4’有着差不多的补丁,否则衍合就不能够分辨C4‘是C4的复制快照。这样的话就会添加一个新的C4 ‘‘的补丁文件(这将会导致衍合失败,而且这样的话会导致一些不可预料的变化)。
        你也可以用git pull --rebase命令来代替平常的git pull命令        
        最后附上git文档里面的最后一段,关于什么时候使用rebase和merge
技术分享

 三、git pull 和 git pull --rebase

        先说说git pull命令。
        git push是把本地文件上传至远程库的命令。那么自然而然就有把远程库的文件拉下来放到本地工作区的命令,这个命令就是git fetch命令。git fetch所做的只是把远程库的文件获取到本地。
git pull = git fetch + git merge。
如果后面加上--rebase参数。git pull --rebase命令
        表示把你的本地当前分支里的每个提交(commit)取消掉,并且把它们临时 保存为补丁(patch)(这些补丁放到".git/rebase"目录中),然后把本地当前分支更新 为最新的"origin"分支,最后把保存的这些补丁应用到本地当前分支上。
        其实git pull --rebase = git fetch  + git rebase。
        浏览了一些博客,发现大多数博主都有个提醒的地方:尽量少使用git pull或者git pull --rebase命令,多使用git fetch命令 + git pull命令或者git fetch命令 + git rebase命令。因为逐步执行可以保证文件的安全性。直接git pull会隐藏一些细节,或许这些细节就是你所需要的。
        而到底是使用git pull还是使用git pull --rebase,其实也就是面临是选择git merge还是git rebase合并一样的情景。git merge可以保存所有的commit记录方便之后的使用,而git rebase是为了有一条清晰明朗的主线,避免无谓的commit。存在即为合理,两种不同的方式各有优点,就看实际情况到底如何使用了。

四、无大脑的简单问题测试

                       

        问题一:git merge 分支的时候,合并冲突。

情景再现:在分支修改了某个文件之后,回到master分支想要将两个分支合并。因为某个文件内容不一样,出现了
技术分享
技术分享
        git告诉你合并失败因为有一个未合并的文件。这个时候应该在工作区打开文件,手动修改,在使用add,commit命令,最后使用git merge命令最后才能成功的合并。
        盗取廖雪峰老师的图来解释一下应该会更清楚点:
                1.你修改了两个不同分支相同的文件,这个文件在不同分支内容是不同的,不能使用快速合并了。
技术分享
                2.这个时候你手动修改了这个文件,使用git merge命令发现出现下面的提示。
技术分享
技术分享
        解决方法:手动修改未合并的文件,再次add,commit。合并之后相当于多了一次提交。改变图如下:
技术分享
        结论:如果merge的时候使用的是Fast forward模式,git只是将mater的分支移到另外一个分支上。如果没有使用Fast forward模式(普通模式),Git会产生一个新的commit。Fast forward模式合并之后是没有分支记录的,普通模式是用分支记录的。

        问题二:git pull的时候合并冲突

        你工作做到一半,突然有个bug要放下手上的活儿去解决bug。可是直接pull会丢失你这几天的辛辛苦苦工作。下面几个步骤搞定。
1.git add *        把所有值钱工作的文件放入暂存区。
2.git  stash        将文件放入git栈备份
3.git pull origin 将远程库代码拉下来(避免冲突了)
4.git stash pop  将git栈的备份文件拿出来
5.git merge        合并文件
   
以上是我的一些总结,如果有什么错误的地方欢迎大家指正!
             



分布式版本控制系统Git------分支管理与合并(merge与rebase)

标签:

原文地址:http://blog.csdn.net/aroundme/article/details/51223687

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!