Git学习之Merge命令,HEAD应用的理解

今天在学习Git的分支合并时,对merge命令的具体处理方法产生了思考:

分支主要有3种:

直接合并(straight merge):把两条分支上的历史轨迹合并,交汇到一起;

压合合并(squashed commits):将一条分支上的若干个提交条目牙合城一个提交条目,提交到另一条分支的末梢;

拣选合并(cherry-picking):拣选另一条分支上的某个提交条目的改动带到当前分支上。

假设当前项目有两条分支:master和develop,对应的版本演进轨迹如下(左右标识了时间顺序):

C1---->C2---->C3----->C4---------->C6 (master)

|

|

|--------------->C5------------->C7 (develop)

则checkout到master上,将develop分支合并到主分支上,得到

C1---->C2---->C3----->C4----->C5----->C6------>C7----->C8(Merge branch 'develop') (master)

那具体是如何合并的呢?

是先把C5合并进C4和C6,没问题再合并上C7,没问题之后再commit得到C8?

还是直接把develop分支的末梢和master分支的末梢进行合并,如果有冲突则先处理,然后commit得到C8呢?

后面通过合并log,我猜测应该是后者是正确的。

当然,git log是按照时间顺序组织的

注意:

使用git diff 命令查看各个commit与当前分支master的末梢的差异,会发现:

1、git diff C7:没有C4、C6两个提交的内容,跟直接与develop分支的C7比较是一样的;

2、git diff C6:没有C5提交的内容;

3、git diff HEAD:跟C8比;

4、git diff HEAD^:跟C6比,而不是C7;

5、git diff HEAD~2:跟C4比,而不是C6;

由此,可以猜测到(实践已证实):

使用git reset --hard C7:将会失去C4和C6两个commit(包括实际内容和log),得到的master分支将和develop分支一模一样。

总结:

1、合并两个分支,是把两个分支末梢的最新版本断面合并,log安实践顺序交汇到一起;

2、每个commit对应的内容与每个分支上相应commit对应的内容是完全一致的(个人理解,在.git版本库中,一个commit只有一份存储,不论是在哪个分支上做的commit),因此使用git diff和git reset命令时需要尤其注意和小心,不要搞错;

3、HEAD引用对应某个分支,即使合并后,也是对应所在分支上的commit的层级,与其他分支上commit无关。

猜你喜欢

转载自seazenith.iteye.com/blog/1722622
今日推荐