Getting geeky with Git #4. Fast-forward merge and merge strategies

栏目: IT技术 · 发布时间: 4年前

内容简介:When working with branches, we often need to synchronize our changes. When doing so, we can implement different approaches. In this article, we explain how merging works and discuss various situations. During that, we will touch on the subject of the fast-

When working with branches, we often need to synchronize our changes. When doing so, we can implement different approaches. In this article, we explain how merging works and discuss various situations. During that, we will touch on the subject of the fast-forward merging and different merge strategies.

The basics of merging

The job of the git merge command is to integrate a code history that we’ve forked at some point. Let’s look deeper into how it works. First, let’s create a new branch and make some changes.

git checkout -b new-branch
echo "Additional line of code" >> README.md
git add ./README.md 
git commit -m "Added a line of code"

We see the current state of the branch with git log :

commit b53e0718f93eff963181b8c6ef92341641141641 (HEAD -> new-branch)  Author: Marcin Wanago <wanago.marcin@gmail.com>  Date: Sat Jul 18 18:03:06 2020 +0200
Added a line of code
commit cf418d2c640d839570fe3151fc3f12116c118db9 (origin/master, master)  Author: Marcin Wanago <wanago.marcin@gmail.com>  Date: Sat Jul 18 17:52:01 2020 +0200
initial commit

Now, let’s move back to master and merge the changes:

git checkout master
git merge new-branch
Updating cf418d2..b53e071  Fast-forward  README.md | 1 +  1 file changed, 1 insertion(+)

Fast Forward Merge

One of the most important things about git merge , when compared to  git rebase , is that merging creates a  merge commit . This is not always the case, though. Let’s look into the  git log after the above commit:

commit b53e0718f93eff963181b8c6ef92341641141641 (HEAD -> master, new-branch)  Author: Marcin Wanago <wanago.marcin@gmail.com>  Date: Sat Jul 18 18:03:06 2020 +0200
Added a line of code
commit cf418d2c640d839570fe3151fc3f12116c118db9 (origin/master)  Author: Marcin Wanago <wanago.marcin@gmail.com>  Date: Sat Jul 18 17:52:01 2020 +0200
initial commit

Since our new - branch is very simple, a fast forward merge occurred. It works by combining the histories of both branches. It can happen when there is a linear path from the current branch tip to the target branch. The above is the case since we haven’t committed anything to master before creating the  new - branch .

In the third part of this series , we can learn that  the branch is a reference .

If we dig a bit deeper, we can see that both master and the  new - branch now point to the same commit. This is the case thanks to performing a  fast-forward merge .

git show-branch --sha1-name master
[b53e071] Added a line of code
git show-branch --sha1-name new-branch
[b53e071] Added a line of code

True merge

However, the above is not possible if our branches have diverged. To create such an example, let’s create a new branch but then make some changes to master .

git checkout -b feature-b
git checkout master
echo "console.log('Feature A')" >> feature-a.js
git add ./feature-a.js
git commit -m "Added feature A"

Now that our master includes some new changes let’s go back to feature - b .

git checkout feature-b
echo "console.log('Feature B')" >> feature-b.js
git add ./feature-b.js
git commit -m "Added feature B"

Now, let’s merge feature - b to  master .

git checkout master
git merge feature-b

Once we do the above, Git fires up the text editor. The default depends on your system. In my case, it is Nano :

Getting geeky with Git #4. Fast-forward merge and merge strategies

The editor opens because the merge results in creating a merge commit . Once we finalize the merge, we get the following:

Merge made by the ‘recursive’ strategy.  feature-b.js | 2 ++  1 file changed, 2 insertions(+)  create mode 100644 feature-b.js

Getting geeky with Git #4. Fast-forward merge and merge strategies

In the above graph, we can observe at which point the master diverges into  feature - b and when it comes together with the use of the merge commit.

Let’s look into the merge commit a bit more to understand it better.

git cat-file -p 73575db27f3c8a9d7492139013eae0e01193b880
tree 6b45e53ad2e6946d3a9f38ccf33a93ff8ef28a28  parent ff435740aad2a498294bd162e611f9a876c2b489  parent 86251d7ea21d1b718e249ca83ae93dbdbb480e48  author Marcin Wanago <wanago.marcin@gmail.com> 1595166982 +0200  committer Marcin Wanago <wanago.marcin@gmail.com> 1595166982 +0200
Merge branch ‘feature-b’

In the second part of this series , we’ve learned that a parent of a commit is simply the previous commit. When we create a  merge commit , it has multiple parents. Let’s inspect them:

git cat-file -p ff435740aad2a498294bd162e611f9a876c2b489
// …  Added feature A
git cat-file -p 86251d7ea21d1b718e249ca83ae93dbdbb480e48
// …  Added feature B

We can see that the parents of the merge commit are the tips of the branches involved.

Merge strategies

When we attempt to merge two branches, Git tries to find a common base commit. When looking for the latest common commit between two branches, Git can adopt one of a few strategies.

Resolve

It works for merging two branches, and it used to be the default. A detailed explanation of this strategy can be found in Version Control with Git

[…] pick one of the possible merge bases […] and hope for the best. […] Git detects that it’s remerging some changes that are already in place and just skips duplicate changes, avoiding the conflict. Or, if there are slight changes that do cause a conflict, at least the conflicts should be fairly easy for a developer to handle.

Octopus

It is a default strategy when attempting to merge more than two branches. It fails to do so if it encounters situations in which a manual resolution is required. A merge commit created with this strategy has more than two parents.

Recursive

The recursive strategy became the default when pulling or merging two branches in 2005. It has proven to cause fewer conflicts when working on the Linux kernel as opposed to the resolve strategy .

It uses a three-way merge algorithm to recurse over the changes in the branches. The recursive strategy has quite a few options available, such as  ours and  theirs . For a full list, check out the documentation .

Subtree

It is a form of a recursive strategy. It might prove to be useful when managing multiple projects within a single repository. Github has quite a detailed documentation on this topic with examples .

Ours

When merging, it discards changes from the other branch (or multiple branches), merging just the history. It does not affect the files at all. According to the documentation, it is meant to be used to supersede the old development history of side branches. It differs from using the recursive strategy with the “ours” flag.

Summary

Although it is usually the best idea to rely on Git to choose the best approach to merging, it is useful to have at least a basic understanding of the reasons behind it. When dealing with merges, we might alter our approach slightly to have a cleaner history and fewer conflicts. One of the additional processes that we might want to introduce to our flow is rebasing , and we will cover it in the upcoming parts of this series.


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Web技术

Web技术

杰克逊 / 清华大学出版社 / 2007-6 / 59.00元

本书详细介绍了广泛的Web技术,包括:HTTP、XHTML、CSS、JavaScript、DOM、Java servlet、XML及相关技术、JSP、SOAP、Web服务、JAX-RPC等;简要概述了相关的技术,包括:CGI、ASP、PHP和ColdFusion技术。本书还使用大量的示例来示范各种技术的原理和用法,并且说明相关的概念。各章章末还提供了一些问题,用以测试学生对内容的理解程度,并让他们......一起来看看 《Web技术》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

MD5 加密
MD5 加密

MD5 加密工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试