Working on a team means multiple people are often changing the same codebase simultaneously. A merge conflict happens when Git can't automatically figure out how to combine changes from two different branches, typically because the same lines of code or parts of a file were modified differently in both places. For example, if you change line 10 in app.js on your feature branch, and a colleague changes line 10 in the same app.js on the main branch, Git won't know which version to keep. When you try to merge or rebase, Git will pause, notify you of the conflict, and essentially say, "Human, I need your help to decide." This is a common and normal part of development, so don't be intimidated!
Resolving a merge conflict means you manually edit the conflicting files to tell Git which changes to keep. Git marks conflicting sections in your files with special markers: <<<<<<< HEAD (your current branch's changes), ======= (the separator), and >>>>>>> <branch-name> (the incoming branch's changes). Your task is to open the file, examine these sections, delete the markers, and edit the code to the desired final state. This might mean keeping your changes, keeping the incoming changes, or combining parts of both. After you've resolved all conflicts in a file, you use git add <file-name> to stage the resolved file, and then git commit to finalize the merge or rebase. Many modern IDEs offer excellent built-in tools to help visualize and resolve these conflicts more easily.
While merging combines histories, interactive rebase (git rebase -i) allows you to rewrite your branch's commit history before merging it into another. Think of it as a powerful editing tool for your local commits. You can use it to "squash" multiple small, related commits into a single, cleaner commit; reorder commits; edit commit messages; or even delete commits. The primary use case is to clean up your feature branch's history before you push it to a remote repository or merge it into the main branch, making the project's history more linear and understandable. Crucially, never rebase branches that have already been pushed to a shared remote repository (like main or another developer's branch) because it rewrites history and can cause major problems for anyone else who has based their work on those original commits. Only rebase your own local, unpushed work.
Key Takeaways
- Merge conflicts happen when Git can't automatically combine changes; you must resolve them manually.
- Resolve conflicts by editing files, removing Git's markers (
<<<<<<<,=======,>>>>>>>), and thengit addandgit commit. - Interactive rebase (
git rebase -i) lets you clean up your local commit history (e.g., squash, reorder, edit commits) before sharing. - Never use
git rebase -ion branches that have already been pushed to a shared remote, as it rewrites history for collaborators. - Utilize your IDE's built-in tools to simplify conflict resolution.
Code Example
How this code works
This code example visually demonstrates a merge conflict within a JavaScript file. Its job in the lesson is to show the raw state of a file when Git encounters incompatible changes from two different development paths, requiring manual intervention to proceed.
Git inserts special markers to highlight the conflicting sections. The lines starting with <<<<<<< HEAD and ending just before ======= contain the version of the code from the current branch (often main or HEAD), where the initializeApp function logs "App started on main branch.". Following the ======= separator, the section ending with >>>>>>> feature/new-login represents the changes from the other branch, feature/new-login, where the same initializeApp function logs a different message: "App started with feature X.". A key concept for beginners is recognizing that these marker lines are not part of the application's functional code. All <<<<<<<, =======, and >>>>>>> lines, along with one of the conflicting code blocks, must be explicitly deleted or modified by the developer to resolve the conflict before the file can be committed.