1.merge

在上篇介绍分支的时候有简单的说了一下分支的创建和合并,当时合并就是写的merge,这是依据两个不同分支的最后一次提交的commit对象c5,c7和两个分支的交叉点的commit对象c3进行一次简单的三方合并,终于得到一个新的commit来作为终于的提交commit对象c8,指针指向c8,并且c4,c5,c6,c7是存在于本地仓库的历史版本号,我们能够通过日志查看找到这两个commit,相同也能够恢复到这两个版本号。也就是以下这个图:

上图是将test分支合并到master分支,然后我们来实现一次,假如如今已经到了c3,我新建一个分支test,然后先用master分支改动我的test.txt文件并提交反复两次,得到c4和c5,然后再切换到test分支相同对test.txt改动并提交两次,得到c6和c7,然后切换到master分支运行合并操作,这时会提示有冲突,最后我们解决冲突了再提交:

冲突:

日志:

2.rebase

rebase称为衍合,这是个什么概念呢,例如以下图,当我们把test衍合到master的时候,是将c5,和c6中发生的变化打成补丁然后再c8的基础上做改动的,假设这个时候遇到冲突,就必需要我们自己决绝好冲突之后,加入到暂存区然后再继续合并,c5的变化补丁在c8上发生变化之后得到c5'这个commit对象,而c6的变化补丁再在c5'上改动得到c6',然后指针指向c6',这个过程我们称之为衍合,并且这个过程都是在一个*(no branch)分支上做的,这个后面会说到。并且有一个要注意的地方,假设git运行git gc或者我们手动运行git gc,那么c5和c6就不再存在于我们的本地仓库,我们就再也找不回这两个commit了,这个过程就是一个线性的过程,在test运行完之后,再在test的基础上运行master的操作。以上就是rebase和merge的差别所在。

和merge一样,我们实际来做一次,如果如今我们已经在c4了,这时候创建test分支,全部改动操作和merge一样,然后我们用rebase这样的方式来把test衍合到master上:

冲突:

日志:

3.*(no branch)

在运行命令git branch查看分支的时候,假设出现*(no branch),则表示不在不论什么分支上进行工作。出现这样的情况我也是在几次不经意之间,用git checkou回溯版本号的时候,用git pull或者merge和rebase的时候会出现*(no branch)。眼下我在rebase的时候都是在*(no branch)上进行的,当衍合完毕后自己主动切到master上,我认为这是个正常现象,可是其它几种方式就不正常了,详细原因我也不是非常清楚。

因为*(no branch)表示不在不论什么分支上进行,而有时我们不知道自己是在*(no branch)上进行操作的,并且可能我们已经进行非常久的开发工作了,已经提交好几个版本号的代码了,突然运行git branch发如今*(no branch)上,是不是一件非常恐怖的事啊。

当然经过提交的版本号数据都会以快照的方式被记录在commit对象存在.git文件夹的objects子文件夹里,那么当我们发现是在*(no branch)时应该怎么解决呢。有两种情况。

第一种情况是我们还没离开*(no branch),这个时候,我们能够运行git checkout -b mybranch命令,这个时候会创建新分支mybranch,并将*(no branch)里面的数据都checkout到mybranch分支上,然后我们再在mybranch上开发,终于合并到master上。

另外一种情况就不乐观了,我们已经离开*(no branch)了,然后发现用git log都找不到之前的提交了,当然了,在*(no branch)上提交的,在别的分支上怎么找的到在它上面提交的数据呢。只是或许还有救,假设git还没有运行git gc,那么我们能够通过运行git reflog找到在*(no branch)上提交的数据,然后依据找到的commit的id来恢复该数据,这也是最后唯一的希望了,假设git已经运行了git gc或者你手贱自己运行了git gc,那么就真的不能在一起愉快的玩耍了。

所以在运行过git checkout恢复过曾经的数据或者是做过合并分支的操作,那么不要吝啬你们的git branch,敲这个命令又不要钱,却能让你之后的提交高枕无忧。

4.总结

merge的合并是三方合并,并且历史版本号都在本地方库中,可是却比較繁琐,并且开发的过程是个网状结构,假设创建的分支比較多,进行的merge也比較多,那么就算我们在纸上画它的提交历史都会画的手疼,可是rebase就不一样,它是依据另外一个分支的改动内容进行打补丁然后在前一个分支的最后提交上进行改动,并且将另外一个分支的提交历史删除,这样就是一个线性的过程,非常清晰。所以在推送到远程仓库之前尽量多用rebase来衍合分支,可是假设将一个commit推送到远程仓库之后,就不要再对它进行衍合操作了,由于这种话,它非常可能在你的某次衍合过程中被删除,那么再推送到远程仓库就会造成非常大的损失。切记,rebase虽好可不要贪杯。rebase除了 --continue外,还有 --skip 和 --abort 操作,其中skip会忽略自己的提交,而更新为远程仓库版本;abort会放弃本次合并操作,回到rebase之前的状态。

关于git merge,rebase合并的差别,以及*(no branch)的处理。的更多相关文章

  1. git merge / rebase 分支的新建与合并

    merge https://git-scm.com/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E7%9A%84%E6%96%B0%E5% ...

  2. git merge远程合并

    当某个分支上的开发工作完成后需要将其合入主分支master 但是在提交合并前我们自己最好做一次衍合,目的是检测是否有冲突的风险,如果有应该在本分支先解决冲突然后在提交合并. 否则解决冲突的工作就全部转 ...

  3. git merge rebase的区别及应用场景

    前两天和同事交流发现他在日常开发中跟上游保持同步每次都是用git pull操作,而我一直习惯git fetch然后rebase,发现这两种操作后的log是有些区别的.他每次pull操作之后都会自动生成 ...

  4. Git merge rebase cherry-pick 以及 游离commit 的测试

    Microsoft Windows [版本 10.0.17134.345] (c) Microsoft Corporation.保留所有权利. C:\Users\zhangyang\Desktop\b ...

  5. git merge,rebase和*(no branch)

    上一篇:http://blog.csdn.net/xiaoputao0903/article/details/23933589,说了git的分支,相关的使用方法没说到可是仅仅要google就能搜出一大 ...

  6. git merge 和 git rebase 小结

    Git merge是用来合并两个分支的. git merge b # 将b分支合并到当前分支 同样 git rebase b,也是把 b分支合并到当前分支 ---------------------- ...

  7. Git merge 与 git rebase的区别

    Git merge的用法: git merge Dev // Dev表示某分支,表示在当前分支合并Dev分支 git merge -m  "Merge from Dev"  Dev ...

  8. Git merge && git rebase的用法

    Git merge的用法: git merge Dev // Dev表示某分支,表示在当前分支合并Dev分支 git merge -m  “Merge from Dev”  Dev //-m可以加上m ...

  9. git merge和git rebase

    转载于http://blog.csdn.net/wh_19910525/article/details/7554489 git merge是用来合并两个分支的. git merge b # 将b分支合 ...

随机推荐

  1. 从运维的角度理解Iaas、Paas、Saas云计算

    平时我们的运维工作,大致就是了解需求.申请服务器.配置网络.服务器软件安装.应用部署.数据存储.系统调优.平台维护等 按照Iaas.Paas.Saas的三层来分工我们平时的任务: 最底层的Iaas层提 ...

  2. React 组件框架

  3. JAVAEE期末项目------文章发布系统

    项目文档和代码的GitHub地址:https://github.com/xiangbaobaojojo/- 1.项目介绍 (计科四班  蔡春燕 20150141401)和我 陈香宇(计科四班  201 ...

  4. git:distributed is the new centralized-part1

    PART 1 梗概 git文件流转有三个工作区域:工作目录(working directory).暂存区域(staging area).本地仓库(repository).文件处于上述三个工作区域的状态 ...

  5. jupyter 中markdown使用

    jupyter使用还是很方便的,尤其是喜欢MarkDown功能,在安装插件后可以非常清晰的看到整个文档的基本结构,下面介绍下MarkDownd的使用: 1.MarkDown必须是在命令模式是下使用的, ...

  6. 把一个给定的值存储到一个整数中指定的几个位《C与指针5.8.5》

    编写一个函数,把一个给定的值存储到一个整数中指定的几个位.它的原型如下: int store_bit_field(int original_value, int value_to_store, uns ...

  7. autofac使用总结

    转摘自:http://niuyi.github.io/blog/2012/04/06/autofac-by-unit-test/ 注册部分: AutoFac是.net平台下的IOC容器产品,它可以管理 ...

  8. Python学习之路基础篇--06Python基础+dict的学习

    字典和列表其实差不多,所说3.6 之前的版本字典是没有顺序的.是Python中唯一的映射数据类型,key 是可哈希(不可变数据类型),如元组.bool.int 和 str:value 是任意数据类型. ...

  9. python_ 函数

    函数是啥? 函数能提高应用的模块性,和代码的重复利用率 函数特点? 1 代码块以 def 关键词开头,后接函数名和圆括号() 2 任何传入参数和自变量必须放在圆括号中间 3 函数以冒号开始,并且缩进 ...

  10. java jdk jre

    Java11新特性: https://www.cnblogs.com/eric-shao/p/10025180.html java的一些基本概念——java11.jdk.jre.jvm: https: ...