Merge - biswajitsundara/gitdoc GitHub Wiki

The git merge command integrates the branch to the current branch

Fast Forward Merge

  • This merge operation occurs when the branch being merged has all its changes ahead of the current branch.
  • So instead of creating a new merge commit, Git can simply move the current branch pointer forward to the latest commit of the other branch.
  • So the master(head) pointer will be moved to the latest commit of the feature branch
  • This results in a linear history and a cleaner git log.
  • When we use the git merge command, it will check the current branch's history and if the changes are linear it will go for fast forward merge.

Example

  • Let's say we create "feature" branch from "master" branch
  • We make some changes to the "feature" branch and commit them.
  • There are no other commits made to the "master" branch after the feature branch was created.
  • We switch back to the "master" branch and run the command git merge feature.
  • Since the changes in "feature" branch are entirely linear git will perform a fast-forward merge by simply moving the "master" branch pointer (HEAD) to the latest commit of the "feature" branch.
//1. Currently on master branch
git branch
*master

//2. create a feature branch
git checkout -b feature/help

//3. Create a file and commit to the feature branch
create a file 'help.html'
git add --all
git commit -m "help"
git push -u origin feature/help

//4. Be on the branch to which the other branch 
//will be merged (master <--- feature/help)
git checkout master

//5. Merge the feature branch
git merge feature/help

Updating 137f151..9b5c4ff
Fast-forward
 help.html | 12 ++++++++++++
 1 file changed, 12 insertions(+)
 create mode 100644 help.html

//6. Push the local branch updates to remote
git push -u origin master

Note that a fast-forward merge can only be performed when there are no other changes made to the current branch after the branch being merged was created.

2. Recursive Merge

  • Occurs when the changes being merged diverge from the current branch's history, resulting in multiple commit paths.
  • In this case, Git creates a new merge commit that combines the changes from both branches and creates a new commit that represents the merge.
  • When you use the git merge command, Git will first check whether the changes being merged diverge from the current branch's history.
  • If the changes are not entirely linear and diverge, then Git will perform a recursive merge.

Example

  • Let's say we create a "feature" branch from "master"
  • We make some changes to the "feature" branch and commit them.
  • Meanwhile, another person makes changes to the "master" branch and commits them.
  • We switch back to the "master" branch and run the command git merge feature.
  • Git will recognize that there are multiple commit paths and perform a recursive merge.
  • It will create a new merge commit that combines the changes from both branches and creates a new commit that represents the merge.
  • If there are conflicts between the changes in both branches, Git will prompt you to resolve them manually before finalizing the merge.
//1. Currently on master branch
git branch
*master

//2. Create the feature branch
git checkout -b feature/register
create a file 'register.html'
git add --all
git commit -m "register"
git push -u origin feature/register

//3. Master branch got updated
git checkout master
open an existing file (hello.html), add a new line
git add --all
git commit -m "updated hello"
git push -u origin master

//4. Switch to master and then merge the feature branch (master <--- feature)
git checkout master
git merge feature/register
Merge made by the 'recursive' strategy.
 register.html | 12 ++++++++++++
 1 file changed, 12 insertions(+)
 create mode 100644 register.html

//5. Check the git log
//We will see one more commit is created by Git
git log
commit ee8983edb880573857402c3344123 (HEAD -> main)
Merge: 5e7884b 753cfd9
Author: Biswajit Sundara <[email protected]>
Date:   Fri Jan 31 01:38:10 2023 +0530

    Merge branch 'feature/register'

commit 5e3284b92f87f6b8m5m3ckc6fcbe42742bb (origin/main)
Author: Biswajit Sundara <[email protected]>
Date:   Fri Jan 31 01:35:41 2023 +0530

    updated hello

//6. Push the changes to remote
git push -u origin master

Merge Conflict

  • The merge conflict occurs when git is unable to merge two branches together automatically because there are conflicting changes in the code.
  • This happens when two or more branches have made changes to the same file or the same lines of code in a file
  • Git is unable to determine which changes should be kept and which should be discarded.
  • When Git encounters a merge conflict, it will pause the merge process and ask the user to manually resolve the conflict.
  • The user will then need to open the file(s) with conflicts and decide which changes to keep, which to discard
  • When a file goes to conflict state it will have both the changes in the file highlighted by <<<< ===
<<<<<<< HEAD
this is some content to mess with
content to append
=======
totally different content to merge later
>>>>>>> new_branch_to_merge_later
  • The user needs to manually remove the part that's not required, save and commit the file
  • This might happen when two developers are working on the same codebase
  • Or when a developer is working on multiple branches and tries to merge them together.

Auto Merge

  • When resolving a merge conflict, we have the option to accept changes from either "ours" or "theirs".
  • We can perform this automatic merge when we are clear which code to retain.
  • Let's say we have a feature branch created out of master branch and hello.html is updated by both branches
  • Accepting changes from ours means that you are choosing to keep the version of the code that exists in the current branch we are working on.
  • This is useful if we want to ignore the changes made in the other branch and only keep our changes.
  • Accepting changes from theirs means that you are choosing to keep the version of the code that exists in the branch you are merging in.
  • This is useful if we want to ignore our changes and only keep the changes made in the other branch.
git branch
*master

//it will keep master branch's updates and ignore feature/works branch's updates for the conflicting file
git merge -X ours feature/works

Auto-merging hello.html
Merge made by the 'recursive' strategy.

//it will bring feature/works branch's updates and ignore master branch's updates for the conflicting file
git merge -X theirs feature/works

  • Note that using these options will only affect the merge conflict resolution and will not affect the final merged code.
  • After resolving the conflict, we will still need to commit the changes to complete the merge.