Merging and Resolving Conflicts
Learn how to combine changes from different branches and resolve conflicts
Once you've completed work on a branch, you'll want to incorporate those changes back into your main branch. This is done with the git merge
command. In this section, we'll explore how to merge branches and handle merge conflicts.
Understanding Merging
Merging is the process of combining changes from one branch into another. When you merge, Git attempts to automatically combine the changes. If the same part of a file wasn't changed in both branches, Git will merge them automatically. If there are conflicting changes, Git will notify you and ask you to resolve them.
Types of Merges
Git performs two types of merges:
Fast-Forward Merge
A fast-forward merge occurs when the target branch has no new commits since your branch was created. In this case, Git simply moves the pointer forward. No new commit is created.
Before:
main A---B---C
\
feature D---E
After:
main A---B---C---D---E
feature D---E
Three-Way Merge (Recursive Merge)
A three-way merge occurs when both branches have progressed independently. Git creates a new "merge commit" that combines the changes from both branches.
Before:
main A---B---C---F
\
feature D---E
After:
main A---B---C---F---G
\ /
feature D---E
Where G is the merge commit.
Basic Merge Process
To merge a branch into your current branch:
- Switch to the branch you want to merge into (typically
main
):
git checkout main
- Merge your feature branch:
git merge feature-user-profiles
If the merge is a fast-forward merge, Git will simply update the branch pointer. If it's a three-way merge, Git will create a new merge commit.
Merge Commit Messages
For three-way merges, Git will open your editor to create a merge commit message. The default is usually sufficient:
Merge branch 'feature-user-profiles' into main
But you can provide more context if needed.
Merge Strategies
Git offers several merge strategies for different scenarios:
--ff
(default): Do a fast-forward merge if possible, otherwise create a merge commit--no-ff
: Always create a merge commit, even if a fast-forward merge is possible--ff-only
: Only perform the merge if it's a fast-forward merge--squash
: Combine all changes into a single new commit
Example of forcing a merge commit:
git merge --no-ff feature-branch
Example of a squash merge:
git merge --squash feature-branch
git commit -m "Add user profile feature"
Handling Merge Conflicts
Sometimes Git can't automatically merge changes because both branches modified the same part of a file. This is called a merge conflict.
When a conflict occurs, Git will tell you which files are conflicted:
Auto-merging profile.html
CONFLICT (content): Merge conflict in profile.html
Automatic merge failed; fix conflicts and then commit the result.
Understanding Conflict Markers
Git modifies the conflicted files and adds conflict markers to show the conflicting parts:
<<<<<<< HEAD
<h1>User Profile Page</h1>
=======
<h1>Customer Profile</h1>
>>>>>>> feature-user-profiles
These markers mean:
<<<<<<< HEAD
: The beginning of the conflicting section in your current branch=======
: The divider between the conflicting changes>>>>>>> feature-user-profiles
: The end of the conflicting section, with changes from the branch you're merging
Resolving Conflicts
To resolve a conflict:
- Open the conflicted file(s) in your editor
- Edit the file to resolve the conflict by:
- Choosing one version
- Combining both versions
- Writing something completely different
- Remove the conflict markers (
<<<<<<<
,=======
,>>>>>>>
) - Save the file
- Stage the resolved file:
git add profile.html
- Complete the merge by committing:
git commit -m "Resolve merge conflict in profile page heading"
Git will create a merge commit that includes your conflict resolutions.
Tools for Resolving Conflicts
Many tools can help you resolve merge conflicts:
- Git's built-in tool:
git mergetool
- Visual Studio Code: Built-in conflict resolution interface
- IntelliJ/PyCharm: Built-in merge tools
- Beyond Compare, P4Merge, etc.: External diff tools
To configure a merge tool:
git config --global merge.tool vscode
To start the configured merge tool:
git mergetool
Aborting a Merge
If you want to cancel a merge that has conflicts:
git merge --abort
This will return you to the state before you started the merge.
Prevention is Better Than Cure
While Git handles merges well, it's better to avoid complex conflicts:
- Communicate with your team: Know who's working on what
- Keep branches short-lived: Merge frequently to reduce divergence
- Structure your code modularly: Separate concerns to reduce conflicts
- Pull from main regularly: Keep your branch updated with the latest changes
Advanced Merge Techniques
Cherry-Picking
Sometimes you want to apply a single commit from one branch to another:
git cherry-pick commit-hash
This creates a new commit on your current branch with the same changes as the specified commit.
Rebase as an Alternative to Merging
Another way to integrate changes is rebasing:
git checkout feature-branch
git rebase main
This moves your feature branch to start from the tip of main, creating a linear history:
Before:
main A---B---C---F
\
feature D---E
After:
main A---B---C---F
\
feature D'---E'
Where D' and E' are the replayed commits.
⚠️ Warning: Never rebase branches that others are working on. Rebasing changes commit history, which can cause problems for others using the branch.
When to Merge vs. When to Rebase
- Use merge when:
- You want to preserve the complete history
- The branch is shared with others
- You want to record that a feature branch existed
- Use rebase when:
- You want a cleaner, linear history
- You're working on a personal branch
- You want to integrate the latest changes from the main branch
Best Practices for Merging
- Review changes before merging: Understand what you're merging
- Test before and after merging: Ensure functionality doesn't break
- Use meaningful commit messages: Explain the purpose of the merge
- Keep merges focused: Merge one feature at a time
- Delete branches after merging: Keep your repository clean
With these merging skills, you're now equipped to combine changes from different branches and handle any conflicts that arise. In the next section, we'll explore working with remote repositories to collaborate with others.
Found an issue?