Merge conflicts occur when Git can't automatically combine changes from different branches. This happens when two or more people modify the same lines of code in a file. Git doesn't know which version to keep, so it presents you with a conflict to resolve.
Here's a simple illustration:
// Branch A:
const name = "Alice";
// Branch B:
const name = "Bob";
// After merging:
<<<<<<< HEAD
const name = "Alice";
=======
const name = "Bob";
>>>>>>> feature-branch
To resolve a merge conflict, you need to decide which changes to keep and which to discard. Here's a step-by-step guide:
Git will indicate conflicts by placing "<<<<<<< HEAD", "======= ", and ">>>>>>>" markers in your affected files. The code between these markers represents the conflicting changes.
Carefully review the code between the markers. Understand the changes made in both branches. It's often helpful to compare the versions side by side using a diff tool.
Make your decision. You can choose to:
Remove the markers and the code you're discarding. Save the file.
Stage the resolved file using `git add ` and then commit your changes with `git commit -m "Resolved merge conflict"`.
Let's say you have a function in a file called `utils.js`:
// utils.js
function calculateTotal(items) {
// Logic to calculate total price
return total;
}
Branch A modifies the function to include tax:
// utils.js
function calculateTotal(items) {
let total = 0;
for (const item of items) {
total += item.price;
}
// Add tax
total *= 1.05;
return total;
}
Branch B modifies the function to handle discounts:
// utils.js
function calculateTotal(items) {
let total = 0;
for (const item of items) {
total += item.price;
}
// Apply discount
total *= 0.9;
return total;
}
After merging, you encounter a conflict in `utils.js`:
// utils.js
function calculateTotal(items) {
let total = 0;
for (const item of items) {
total += item.price;
}
<<<<<<< HEAD
// Add tax
total *= 1.05;
=======
// Apply discount
total *= 0.9;
>>>>>>> feature-branch
return total;
}
To resolve the conflict, you need to decide how to apply both tax and discount. You might choose to apply the discount first and then the tax:
// utils.js
function calculateTotal(items) {
let total = 0;
for (const item of items) {
total += item.price;
}
// Apply discount
total *= 0.9;
// Add tax
total *= 1.05;
return total;
}
Remember to remove the conflict markers before staging and committing the resolved file.
Many tools and features make resolving conflicts easier. These include:
Visual tools like GitKraken, Sourcetree, and GitHub Desktop provide intuitive interfaces for viewing and resolving merge conflicts.
Diff tools like Meld, DiffMerge, and Beyond Compare highlight differences between versions, making it easier to identify changes and choose which ones to keep.
Git offers different merge strategies that can simplify conflict resolution in some cases. For example, the `--ours` strategy accepts only changes from the current branch, while `--theirs` takes only changes from the merging branch.
While conflicts are inevitable, you can minimize their frequency by following these tips:
Merge your branches more frequently. This helps to keep changes smaller and easier to integrate.
Communicate with your team members about what you're working on. This reduces the likelihood of conflicting changes.
While rebasing can be useful, it can also introduce complex conflicts. Use it with caution, especially if multiple people are working on the same branch.
© 2023 Your Company Name