The git merge command integrates the independent lines of development into a single branch. The git merge command goes hand in hand with the git checkout command to select the current branch and the git branch command with the -d flag to delete the obsolete target branch. Read about these commands in our previous chapters.
How it works
The primary use of git merge is to combine two branches. It is also used to merge multiple commits into one history. In the following illustration, git merge takes two branch tips and finds a common case commit between them. The common base commit creates a new commit that merges the changes of the sequence of each merge commit. Here we have two branches: a master and a stage. We should merge the stage branch to the master branch.
Merge commits are unique because they have two parent commits. Git automatically merges separate histories when a new merge commit is created. It will not combine the data that is changed in both histories. This is what is called “version control conflict”.
Before the merging process we should take some steps.
- Firstly, invoke git status so that to point HEAD to the correct merge-receiving branch. Run git checkout <receiving branch> to switch to the receiving branch.
- The next step is to fetch latest remote commits. The receiving branch and the merging branch should be updated with the latest remote changes. Invoke git fetch to pull the latest remote commits. After the fetching process invoke git pull to update the master branch.
- The final step is executing git merge <branch name> which is the name of the branch to be merged into the receiving branch.
Fast forward merge
A fast-forward merge occurs the path from the current branch to the target branch is linear. The fast-forward merge combines the histories, as all the commits that are reachable from the target branch are available through the current branch. Here’s an example of a fast-forward merge:
When the two histories are diverged, Git uses the 3-way merge as an alternative. 3-way merge uses a dedicated commit to combine two histories.
A fast-forward merges are used to fix bugs and small features, whereas 3-way merges are used to integrate long-running features. The following examples use a fast-forward merge:
# Start the stage git checkout -b stage master # Edit some files git add <file> git commit -m "Start with the stage" # Edit some files git add <file> git commit -m "Finish with the stage" # Merge in the stage branch git checkout master git merge stage git branch -d stage
We run the git branch -d to delete the stage branch, as stage is now accessible from the master branch.
The git merge command with the --no-ff option is run if you require a merge commit during a fast-forward merge to merge the specified branch into the current branch always generating a merge commit (also, in the case of a fast-forward merge):
git merge --no-ff <branch>
Another example which requires a 3-way merge as the master branch progresses while the stage is in progress. This is used when members of the team work on the large feature simultaneously:
# Start the stage git checkout -b stage master # Edit some files git add <file> git commit -m "Start with the stage" # Edit some files git add <file> git commit -m "Finish with the stage" # Develop the master branch git checkout master # Edit some files git add <file> git commit -m "Make some super-stable changes to master" # Merge in the stage branch git merge stage git branch -d stage
In the above example, stage would be a larger feature taking much time to develop, that is why we use a 3-way merge. If your feature is small, you had better use a fast-forward merge to prevent unnecessary commits messing up the project history.
When you want to merge two branches and the same part of the same file is changed, merging conflicts occur as Git cannot figure out which version to use. When this happens, it stops before the merge commit so as to resolve that conflict. Git merging process uses edit/stage/commit workflow for resolving merge conflicts.When conflict occurs executing git status will display the files that need to be resolved. The following picture will show up when the same parts of the example.txt file have been changed:
On branch master Unmerged paths: (use "git add/rm ..." as appropriate to mark resolution) both modified: example.txt
How conflicts are presented
In the case of conflicts, Git edits the content of the affected files with the visual marks both sides of the conflicted content. Merge conflicts only occur in the case of a 3-way merge.
These markers are: <<<<<<<, =======, and >>>>>>>. They help you search for a project for these indicators to find the conflicted parts.
here is some content not affected by the conflict <<<<<<< master this is conflicted text from master ======= this is conflicted text from stage branch