(译)第二部分:什么是merge?

内容提要

第一部分我们创建了一个小的demo仓库,它拥有着一个feature1分支,而且这个分支已经准备好要merge到master分支中了。

此时,我们可以选择merge或者rebase feature1分支到master分支。关于rebase将会在第三部分进行介绍。现在我们来看一下,采用merge的方式到底发生了什么。把分支合并到一起是非常直接的。首先需要将切换到要合并进去的分支,在这里,因为我们要将feature1合并到master分支,所以需要切换到master分支。

我切换到master分支,然后将feature1分支合并进去。回过头来再看一下这之中发生了什么,为什么Source Tree生成的图形是这个样子的。

还记得第一部分Commit 3Commit 4引用着同一个先前commit吗?Commit 2是这两个commit共同的祖先,因为Commit 3是在另一个分支上创建的,而Commit 4是在master分支上创建的,所以它完全不知道Commit 3的存在。在feature1上我们添加了更多的commit。Commit 5直接引用了Commit 3,因为Commit 4只在master分支上有效,Commit 6直接引用了Commit 5

当我们将feature1合并到master中,它并不是通过某种方式神奇地把这些commit都移到master分支上。实际上,它创建了一个包含了feature1分支上所有的变更的全新commit。这个commit叫Merge branch ‘feature1‘,就像这样:

如果你注意到上图中的commit差异,就会看到我添加到index.txt中二了吧唧的这几行。你应该会注意到这几行是通过各个commit分开地添加进去的。然而,现在你看到的是所有的这些改变都在单一的一个差异中。

Git所做的只是把feature1中所有的commit的所有差异汇聚到一个单一的commit中。这个新的commit干了一些我们之前没有讨论过的事。从上图可以看到它拥有2个祖先,也就拥有着从Commit 4Commit 6过来的两条线。为什么呢?commit可以保存多个先前commit的索引。我现在才来讲这个话题是因为我不想太早地引起混淆。

当一个commit被创建的时候,它所引用的之前commit数量可以是一个,多个,甚至没有。通常只有仓库中第一个commit才会没有先前commit,而merge commit一般都拥有超过一个的先前commit。

如果你还记得第一部分的话,分支,其实实际上只是一个指向一个指定commit的指针而已。

你可能会注意到feature1仍然指向了Commit 6,而master分支指向了新的merge commit,很简单,因为我们是将feature1 合并到master。如果我们将分支切换到feature1,然后再把master合并进来,那么Git所做的就是一个fast-forward marge(快进合并),这会把feature1的指针指向最新的commit。

如果我们完全删除了feature1分支,你可能会以为粉色的线消失,但是你错了。

记住,Source Tree和其他的Git可视工具是通过遍历你的commit,用索引的commit hash连接各个commit来生成图形的。分支只是一个指向指定commit的指针。当你从一个远程仓库拉取更新(pull)时,Git所做的是:

  • 1.下载所有你本地机器上没有的commit
  • 2.合并丢失的commit到你的本地仓库,或是通过一个merge commit,或是通过一个fast-forward merge,前提是你在最后一次拉取更新后没有做任何的修改。
  • 3.把你的本地分支指向最新的commit。

如果你曾经混淆过masterorigin/master指针,那现在你应该知道它们是是啥了。origin/master告诉你你的origin远程master分支指向哪。如果我给这个demo仓库添加了一个远程仓库叫origin,然后在本地仓库上做了一些commit,Git的历史可能会像这样:

你会看到master分支指向了最新的commit,而origin/master指向了前一个merge commit。Source Tree甚至提示我们说有一个commit可以推送(push)到远程仓库。如果我们推送上去,Git将会上传丢失的commit,然后更新你的远程分支指针,此时origin/master已经和你的本地master分支指向了相同的commit。

希望你现在对Git的合并功能有了更好的理解。跳到第三部分让我们深究下rebase,看看它和merge有什么区别吧唧。

英文地址:http://codetunnel.com/merge-vs-rebase-part-2-what-is-a-merge/

时间: 2024-11-20 19:10:49

(译)第二部分:什么是merge?的相关文章

Android 布局巧用之include、merge、ViewStub

原文链接:https://mp.weixin.qq.com/s/bTA2gztUzqvqER2rz56RRQ 相信大家经常听到include.merge.ViewStub这样的标签,官方也提到这三种布局可用于布局的优化.今天就介绍下这三种布局的使用,记录下来,便于后续app中的使用. include布局重用 app开发过程中,会遇到不同页面里有相同的布局,这时我们可以将这些通用的布局提取出来到一个单独的layout文件里,再使用<include>标签引入到相应的页面布局文件里,主要通过incl

数据结构 - 归并排序(merging sort)

归并排序(merging sort): 包含2-路归并排序, 把数组拆分成两段, 使用递归, 将两个有序表合成一个新的有序表. 归并排序(merge sort)的时间复杂度是O(nlogn), 实际效果不如快速排序(quick sort)和堆排序(heap sort), 但是归并排序是稳定排序, 而快速排序和堆排序则不是. 代码: /* * main.cpp * *  Created on: 2014.6.12 *      Author: Spike */ /*eclipse cdt, gcc

学习RxJS: 导入

引子 新手们在异步编程里跌倒时,永远会有这么一个经典问题:怎么在一次异步调用里return一个结果啊? 老司机说要用回调函数,然后有条件判断的嵌套回调(回调地狱)问题来了: 老司机推荐用事件,然后异步流程里有顺序依赖: 老司机推荐用Promise,然后有顺序依赖的流程里,居然还想订阅事件: 老司机建议试试协程,谁知对方想要合并两个异步调用: -- 以上,是异步编程里要面对的一些难题,也是ReactiveX API 所致力解决的 是什么 知道有 ReactiveX 这么一回事, 源于一位巨硬铁粉的

Struts2之控制标签

Struts2的控制标签,主要用于完成流程控制,以及对ValueStack中的控制,控制标签可以完成输出流程的控制,例如循环.分支等操作,也可以完成对集合的合并.排序等操作. 1.常用的控制标签有:if.elseif.else.iterator.append.merge.generator.subset.sort等. 下面分别对这些控制标签进行介绍,并介绍如何使用这些控制标签: (1).if.elseif.else标签:if标签用来控制基本的条件处理流程,通常和else标签或者elseif标签连

转百度前辈的Trados使用心得

我用Trados的时间不长,可以说是一个新手.但我在较短的时间内就已经初步掌握这个工具,说明它并不是那么神秘,并不是那么深不可测.这里,我说一说学习它的一点体会.在我转发的文章中有的内容,我就少讲一些.别人没有提到,或者没有强调的部分,我就多说一说. 1.Trados不是一种机器翻译软件,而是一种翻译记忆软件 提起翻译软件,不少人就会联想到金山快译.东方快车等翻译软件.尽管这些软件有一定的市场,也有人把它们吹得神乎其神,但我对它们并不看好.这些翻译软件的特点是将英语或者汉语输进它的输入界面,马上

数据结构 - 归并排序(merging sort) 详解 及 代码

归并排序(merging sort) 详解 及 代码 本文地址: http://blog.csdn.net/caroline_wendy 归并排序(merging sort): 包含2-路归并排序, 把数组拆分成两段, 使用递归, 将两个有序表合成一个新的有序表. 归并排序(merge sort)的时间复杂度是O(nlogn), 实际效果不如快速排序(quick sort)和堆排序(heap sort), 但是归并排序是稳定排序, 而快速排序和堆排序则不是. 代码: /* * main.cpp

HibernateTemplate的原理与hibernate三态

由于HibernateTemplate的原理与JdbcTemplate的原理类似,现在先讨论JdbcTemplate,在使用JDBC的时候,总是要处理繁琐的细节,例如Connection.statement的获得,SQLException的处理,Connection.Statement的关闭等问题. 使用Spring提供的org.springframework.jdbc.core.JdbcTemplate类被设计成线程安全,当中提供的一些操作方法封装了类似以上的流程. 要建立JdbcTempla

Collections.sort in JDK6:MergeSort

本文是对JDK6中Collections.sort方法的源码解析,也可以看作是对Comparison method violates its general contract!的后续分析.在JDK6中,该方法底层使用的是经过优化后的归并排序,废话不多说,直接看源码. public static <T> void sort(List<T> list, Comparator<? super T> c) { Object[] a = list.toArray(); Array

git个人使用总结(命令版)

一.基础命令 快照类操作:add.status.diff.commit.reset.rm.mv 分支类基本操作:branch.checkout.log.stash 分享及更新项目基本操作:pull.push 组合场景操作: 获取代码:创建仓库(UI).clone 提交代码:add.status.diff.commit.reset 分享代码:branch.push 更新代码:stash.rebase.pull 阅读他人代码:checkout.log 贡献代码:fork.merge request