Git
How to Fix Conflicts in Git?
Git conflicts occur when two or more changes in different branches affect the same part of a file and Git can’t automatically resolve them. While conflicts can seem daunting at first, resolving them is a routine part of collaborative coding. This guide will walk you through understanding why conflicts happen, how to identify them, and practical steps to resolve them.
Why Do Conflicts Happen in Git?
Conflicts arise when:
- Two branches modify the same line(s) in a file.
- A change in one branch deletes or renames a file that’s modified in another branch.
- Merging a branch with substantial changes into the main branch, where those changes overlap or contradict existing code.
Git usually merges changes automatically, but when it encounters overlapping modifications, it flags a conflict that requires human intervention.
Types of Conflicts in Git
Conflicts usually happen in three scenarios:
- Merge Conflicts: When merging branches.
- Rebase Conflicts: When changing the base of your branch.
- Cherry-Pick Conflicts: When applying commits from one branch to another.
Regardless of the type, the process for resolving conflicts is generally the same.
Step 1: Identify the Conflict
When Git detects a conflict, it will stop the merge (or rebase, cherry-pick) process and display a message indicating which files have conflicts.
- Run
git status
:
git status
- This command shows a list of files with conflicts under “both modified.”
- View the Conflicted File:
- Open the file(s) with conflicts. You’ll see conflict markers like this:
<<<<<<< HEAD Code from your current branch ======= Code from the branch being merged >>>>>>> branch-name
- The section between
<<<<<<< HEAD
and=======
is your current branch’s code, while the section between=======
and>>>>>>> branch-name
represents the incoming changes from the branch you’re merging.
Step 2: Resolve the Conflict
Now that you know which lines are causing the conflict, you can decide how to resolve it. There are three main approaches:
- Keep Your Changes: If you want to keep only your current branch’s code, delete the incoming code and remove the conflict markers.
- Keep Incoming Changes: If you want to keep only the changes from the branch being merged, delete your code and remove the conflict markers.
- Combine Changes: You may need both sets of changes. In that case, edit the lines manually to create a new, merged version that includes elements from both branches.
Step 3: Stage the Resolved File
Once you’ve edited the file and removed the conflict markers, save your changes and stage the resolved file.
- Stage the Resolved File:
git add filename
- Replace
filename
with the name of the file you resolved. Staging the file tells Git that the conflict has been resolved.
- Check for Remaining Conflicts:
- Run
git status
again to ensure all conflicts are resolved. If there are more files with conflicts, repeat the previous steps.
Step 4: Complete the Merge or Rebase
Once all conflicts are resolved and staged, you can complete the process.
If You’re Merging
Run the following command to complete the merge:
git commit
- Git will automatically generate a commit message, but you can edit it if needed. Save and close the message to finalize the merge.
If You’re Rebasing
Continue the rebase with:
git rebase --continue
- Git will proceed to the next commit, or, if there are no more commits left, complete the rebase.
Step 5: Test and Verify the Changes
After resolving conflicts, it’s good practice to test your code to ensure that your resolution didn’t introduce new issues or break functionality.
- Run Tests: Run any available tests to confirm that your code still works as expected.
- Review the Code: Take a final look at the merged code, especially if you’ve combined changes from both branches, to verify it aligns with project requirements.
Example of Resolving a Conflict
Let’s say you’re working on a feature branch called feature-login
and trying to merge it into the main
branch, but you encounter a conflict in login.js
.
- Identify the Conflict:
git status
Output:
both modified: login.js
- Open
login.js
and find the conflict markers:
<<<<<<< HEAD
function loginUser() {
console.log("Logging in user");
authenticateUser();
}
=======
function loginUser() {
authenticateUser();
console.log("User logged in successfully");
}
>>>>>>> feature-login
- Resolve the Conflict:
Decide which lines to keep. Here’s a potential resolution combining both changes:
function loginUser() {
console.log("Logging in user");
authenticateUser();
console.log("User logged in successfully");
}
Remove the conflict markers.
- Stage and Complete the Merge:
git add login.js
git commit
Tips for Avoiding Conflicts
- Pull and Sync Regularly: Frequently pull changes from your main branch to keep your branch up-to-date, reducing the chance of conflicts.
- Make Small, Focused Commits: Limit each commit to a specific change or feature, so conflicts are easier to resolve.
- Communicate with Team Members: When working in teams, coordinate with others to avoid working on the same parts of the codebase simultaneously.
Conclusion
Resolving conflicts in Git is a skill every developer should master. While conflicts may seem intimidating, following a systematic approach helps you address them efficiently and with minimal stress. By understanding the causes and steps for resolution, you’ll find that conflicts are manageable and even beneficial in maintaining a high-quality codebase.