Practical Git: Resolve merge conflicts with git status

Trevor Miller
InstructorTrevor Miller

Share this video with your friends

Send Tweet
Published 7 years ago
Updated 4 years ago

Sometimes when you run git merge (also during a git pull which runs a git merge) you get a merge "conflict"; this means that the same line(s) of code were changed locally as in new changes in the remote (most likely from another developer working on a related feature); git merge can automatically merge all other changes but when the same line is modified in two places, you have to fix the conflict manually. In this lesson, we show how a conflict happening from a git pull, and then how to fix it using git status to update the conflict markers in our file(s) with conflicts. You can use a graphical app for this, but this lesson will show you how to resolve conflicts directly from the command line and your code editor.

[00:00] We're inside of a directory called utilityfunctions, which is a Git repo, and we want to change this file here called getInitials.js. So, let's open that up in our editor. Inside this file we have a function called getInitials, which takes in a name and spits back the initials.

[00:18] For example, if we pass it in For Your Information, it would give us back fyi. For this change, we'd like to update the initials to be capitalized, so we'll be outputting FYI in all caps like this.

[00:34] To do that, let's go down to line four, and after we grab the character from the word, let's say toUpperCase, now I'm going to go up and delete the comment that we made, and then we'll save this file. Now back in our command line, let's run git-status, and we can see that getInitials has been modified, so let's stage and commit as usual.

[00:57] Now that our changes have been staged and committed, let's run git-push, but it says here that we can't push yet, because updates were rejected, because the remote contains work that we do not have locally, so that means we need to run a git-pull. So, let me clear my screen here and I'll run git-pull, but it says here that we have merge conflicts in getInitials.js.

[01:20] A merge conflict is when your local code changes and the remote code changes can't be merged automatically because there's been a change on the same line of code in both places. In this case, it looks like someone else has modified getInitials and pushed it to the remote, so when we try to push as well with the same file that has some changes on the same lines, it creates a conflict.

[01:45] What we need to do is fix the conflicts, and then we'll be able to commit and push like normal. The first thing we need to do go run git-status to see which files have a conflict.

[01:55] Running git-status becomes more helpful as there are more files that have conflicts in them, because it says that these are the unmerged paths. If we had other paths that had been merged properly, they'd show up above that, and then the ones that could not be automatically merged show up here in the unmerged path section. These are the files that we need to modify to fix conflicts in.

[02:17] After we've run git-status and we have the list of the files that have conflicts, we need to open those in our editor, so let's open this getInitials. The file has been modified by Git to show where the conflicts are.

[02:29] We can see here a marker that says head, and then there's equals signs, and then there's another market with arrows and a commit ID here. What this is saying is that the area between the first set of markers is our changes, so this is the code, the line that we changed.

[02:49] Then, between the middle marker and the last marker, is the code from the remote that's having a conflict with our changes. Now we need to figure out what Git's not smart enough to do, which is what needs to be in this file that we should commit. There are three situations. The first is if we want to keep all of our code and discard the changes from the remote.

[03:12] The second is the opposite of that, if we want to keep all the remote changes and discard our changes, and the third would be if there's a mixture of the two where we need to keep some pieces from both of the changes. In this case, it looks like on the remote a developer had added a new feature to add a period after each initial.

[03:32] So, that means that if you were previously getting back fyi when passing in "for your information," now you will get f.y.i. like that, with the code that's located on the remote.

[03:43] But with our feature, we also want to capitalize this letters so we get capital F, capital Y, and capital I. It looks like we're going to be using situation three, where we need a combination of both sets of changes. Now let's go down and remove these markers from the conflict, and let's grab the important piece of our changes, so that would be this toUpperCase bit, and we'll add it to the changes from the remote.

[04:12] Now we can delete line three, so now our file is how we want it to be for our merge to be finalized. We've introduced our changes into the changes from the remote, so let's save and close this file. Now we can stage and commit as normal. Finally, let's run git-push, and because our conflict has been resolved, Git allowed us to push successfully.

Carlos Núñez
Carlos Núñez
~ 5 years ago

Hi Trevor,

There is a silly mistake in your explanation at 3:35. You should pass space-separated values. Since name.split(' ') is splitting spaces, it won't give you the expected result if the string passed has not spaces.

Otherwise, you can swap split('') and also join(' ')

function getInitials(name) {
  return name.split('')
    .map(word => `${word.charAt(0)}.`).join(' ')

It is not related to the git explanation which is good though.