In this post we’ll talk about how to handle conflicts in Git. Once you learn how to do it it’s not that scary, but it definitely helps to learn how to do it on code that doesn’t matter as opposed to production code. Check out all of our Git tutorials here.
Note: This is a kind of post where the video really helps, I encourage you to watch it.
What is a Git conflict?
You get conflicts when Git has files that “conflict” with each other, like when one developer modifies a file, and another developer deletes that same file in a different branch. When you try to merge those branches together Git doesn’t know whether to change the file or delete it, so a conflict occurs.
When this happens Git will take all of the changes and lay them out and basically say “These are all the conflicting parts of the code. What do you want to do?”
From there you get to decide… Does this file get deleted? Do I use this code, that code, both, or something else? Once you’ve made your changes and “resolved” the conflict, you have to make an additional commit saying you’ve resolved the conflicts. Let’s give it a try!
(Note: Be aware! I was using “windows preview” as my command line, which was creating my files as utf-16, which caused git to read them as binary files, and they weren’t able to be merged. I tried the default command prompt and that fixed the problem. You want utf-8 but this most likely won’t be an issue. )
We’re going to create a new folder called conflictGit, initialize a repository, create two files, add some text to the files, and make the commit all in one go.
$ mkdir conflictGit $ cd conflictGit $ git init $ echo "commit from master" > file.txt $ echo "another commit from master" > file2.txt $ git add . $ git commit -m "commit from master"
Ok, we have our code, and we’re ready to make a conflict. Pop open a text editor to see the changes being made to help you visualize. Now let’s move over to a different branch. From that branch we’ll REMOVE file2.txt, and modify file.txt
$ git branch dev $ git checkout dev
Now perform the following steps:
- Delete file2.txt
- Modify file.txt by replacing the existing content with the following text:
"this is code from the dev branch"
Save and commit this branch, then prepare to make your conflict by switching back to master and making some edits.
$ git add . $ git commit -m "deleted file2.txt and modified file.txt" $ git checkout master
From the master branch we still have our file2.txt even though it’s been deleted in the dev branch. Let’s modify the file2.txt to create a conflict by adding these two lines:
"delete and modify conflict" It feels good to be alive!
Let’s REPLACE the code in file.txt with the following:
"this is a much better commit from master"
Once these changes are committed there will be a conflict. We have changes in the dev branch that conflict with what’s happened in master. Git won’t know what to do…. Let’s add, commit, and merge the dev branch into our master to see the conflict:
$ git add . $ git commit -m "another commit from master" $ git merge dev
There’s your conflict. Git doesn’t know what to do because in one branch file2.txt is deleted, but in another branch file2.txt has been modified. Then in file.txt the content is completely different on the same line. So git let’s you decide what to do.
If I try to open my file.txt It looks really weird… Git has added BOTH versions to the file. In the HEAD section is the master branch code. underneath the ==== is the dev branch code. From here you could commit the code and it’d include all those carats and equal signs. YOU get to decide how you want this file to be. It just pulls everything in so you can see for yourself what you want.
Note. Good text editors properly setup can make this a bit easier. VSCode allows you to “accept current change”, “accept incoming change”, both, or compare via a toolbar above the changes. Otherwise you may have to edit the code how you want it to be… manually…. The following image is what my code looks like. (Apparently my VSCode settings got fudged and I have to edit changes manually)
I’ll go ahead and edit my file however I see fit (In this case I’ll keep the changes from master. So I’ll delete all the carats, the ===== and everything I don’t want and hit save.
Now let’s keep that file that the dev branch deleted… We’re making a new commit. So if we want that file we have to add it and commit. Let’s give it a try. running $ git status shows us the state of our repository:
Since we want to keep both files let’s add them and make a commit:
$ git add . $ git commit -m "keeping file2.txt and custom file.txt"
If you wanted to DELETE the file2.txt as they did in the dev branch, well… the message tells you how to do that. Use “git add/rm file”.. if you wanted to remove the file you’d run $ git rm file2.txt
If done correctly, your master branch should have the modified file2.txt and whatever you saved for the file.txt. Here’s what my final project looks like:
Now… this is our entire project on the master branch. If you go back to the dev branch it’s still the same as it was before the merge because we made a new commit to handle the conflicts. When you go back to dev be sure to get the new version of the project. if I run $ git checkout dev then take a look at my project folder you’ll see that file2.txt is still gone:
Just run $ git merge master to pull in the changes from master.
$ git merge master
There you have it! It takes a little practice but it’s nothing too hard. Good to be confident when you’re working on a live project that’s for sure.