Atlassian’s Bitbucket is a web-based version control repository service that comes in handy for teams that use Git revision control systems. In this article, I take a closer look at one of Git’s principal functionalities – merge – to show you how to make the most of it in Bitbucket. I also discuss merge conflicts and show how to handle them.
Merge in Git and Bitbucket
In Git, merging is like putting back together a forked history of commits. By using the git merge command, developers can integrate the independent lines of development into a single branch.
Here’s how git merge works:
The command combines multiple commit sequences into one unified stream. Most of the time, development teams use it to combine two branches. In this most common branch merging pattern, git merge takes two commit pointers – usually, it’s the branch tips – and finds a common base commit they share. Once that happens, Git creates a new merge commit that includes the changes of every queued merge commit sequence.
Here’s an example:
Let’s say that you have a new branch feature which is based on the master branch. Now you want to merge this feature branch into the master branch. If you use this command, you will merge the branch feature into the current branch – which we will assume here is the master. Git will come up with the merge algorithm automatically.
The thing about merge commits is that they have two parent commits – contrary to other types of commits. That’s why when creating a merge commit, Git will try to marge their separate sequences automatically. But if it stumbles upon a piece of data changed in both histories, it won’t be able to put them together. That’s when a version control conflict arises, and Git requires users to fix that before continuing the merge.
Do this before merging
Before performing a merge, take these preparation steps to make sure everything goes smoothly:
Step 1: Verify the receiving branch
You need to execute git status to make sure that HEAD is pointing to the correct branch that will be receiving the merge. You can also use git checkout <receiving> for switching to the receiving branch.
Step 2: Fetch the latest remote commits
It’s also smart to ensure that the receiving branch and merging branch are kept up-to-date with the latest remote changes. To do that, execute git fetch. That’s how you pull the latest remote commits. Once this action is completed, you can be sure that the master branch has all the latest updates by using the git pull command.
Now it’s time to merge!
You’re ready to initiate the merge by executing the following command: git merge <branch name>. <branch name> refers to the name of the branch that you’re planning to merge into the receiving branch.
Note: This and other commands mentioned in this article merge into the current branch. It will be updated to reflect the merge, leaving the target branch unaffected. That’s why developers use git merge together with git checkout for selecting the current branch. They also use git branch -d to delete the obsolete target branch if necessary.
When the path from the current branch tip to the target branch is linear, we can talk about a fast-forward merge. In this scenario, Git doesn’t really merge branches – instead, it integrates the histories by moving (or fast-forwarding) the current branch tip to the target branch tip.
This method helps to combine these sequences efficiently – all the commits that can be reached from the target branch are now available in the current branch.
If the branches have diverged at some point, fast-forward merge won’t be an option. If Git doesn’t see a linear path to the target branch, it will be forced to combine the branches using a 3-way merge (the two branch tips and their common ancestor) which uses a dedicated commit to tie two sequences together.
Development teams like to use fast-forward merges for smaller features or simple bug fixes. 3-way merges work best for integrating longer-running features.
If a feature branch is small, developers can rebase it onto the master branch and do a fast-forward merge. That way, you won’t be cluttering the project’s history with unnecessary merges.
Merge conflicts and how to deal with them
Let’s imagine the following situation:
You have two branches that you want to merge, but both of them changed the same part of the same file. Git will have no idea which version it should use. In this scenario, Git will stop right before the merge commit to allow you to resolve the conflict manually.
To resolve merge conflicts, Git uses the edit, stage, commit workflow which is familiar to most developers. When a merge conflict occurs, all you need to do is run the git status command to see which files need to be manually resolved. Also, when Git encounters a conflict during a merge, it edits the content of the affected files using visual indicators that mark both sides of the content where conflict occurs.
So once you identify the conflicting sections, you can fix the merge easily. When you’re ready to finish it, all it takes is running git add on the conflicted file or multiple files – that’s how you tell Git that you’ve resolved the conflict. After that, run the regular git commit to generate the merge commit. This process makes it easier for developers to manage their merges.
Note: It’s not possible to encounter conflicts in a fast-forward merge. Merge conflicts will only occur in a 3-way merge.
Merging is one of the key processes for development teams working with Git. I hope this article helps you get the hang of the git merge command and simplify your work with Git and Bitbucket.
If you’re looking for expert consultants, who could help you take advantage of Bitbucket, get in touch with us. We help development teams streamline their processes with Atlassian tools to position their organizations for success.