In this video, we'll discuss resolving merge conflicts. We will start with a merge conflict overview. If you perform a merge with a merge commit, Git takes on the responsibility of combining the work of multiple branches and placing the result into a single merge commit. Git will try to do this automatically. However, there are cases where multiple branches make different changes to the same part of a file. In that case, a merge conflict occurs and a person needs to make a decision on how to resolve it. In this example, we start with commit A on the master branch. That commit contains a fileA.txt file containing the string feature one. Then let's say that you create a feature two branch based on commit A. While you are working on the feature two branch, someone makes commit C on the master branch. Commit C contains a fileA.txt file that includes the string feature three as the second line of the file. Now let's say that you have finished feature two and made a commit B on the feature two branch. Commit B contains the string feature two as the second line of the fileA.txt file. Now you are ready to merge your feature two work into the master branch. You cannot use a fast forward merge because commit C has been made to the master branch after you created the feature two branch. When you perform a merge, Git tries to automatically create a merge commit, combining the work of commits B and C. However, when Git tries to combine the work, it notices that the second line of fileA.txt is different on each branch. Git doesn't know how to write fileA.txt, then you have a merge conflict. A person needs to decide how to write fileA.txt. We have just seen that a merge conflict can occur if different branches change the same part of the file in different ways. If only one branch changes any file, you'll not have a merged conflict. In this example, the feature two branch adds a new file, fileB.txt, to implement feature two. There's no merge conflict because changes are made to separate files. Commit C changed fileA.txt and commit B created fileB.txt. After the merge, commit M contains the two files implementing the three features. Git also can automatically merge changes to different parts of the same file. In Git, a part of a file is called a hunk. In this example, the project starts with commit A, which contains a fileA.txt file containing feature one with a bug and feature two. A feature three branch is created off of commit A of the master branch. While the feature three branches being worked on, commit C is made, which fixes the bug in feature one. On the feature three branch, the string feature three is appended to the fileA.txt file as commit B. Notice that the feature three branch has the bug because the bug was there when the branch was created. When the feature three branch is finished, a merge will execute without a merge conflict. Git is smart enough to realize that the first part of the file was changed on the master branch and the last part of the file was changed on the feature three branch. In merge commit M, Git will automatically create the fileA.txt file shown here. How Git actually merges the files depends on what is called the merge strategy. Usually, the default merge strategy works well. Since Git is open source software, anyone can contribute improved merge strategies. There is a link to more information on merge strategies here. We have seen that merge conflicts occur when two branches modified the same hunk of the same file. To make merging easier, avoid making a lot of changes over a long period of time without merging. Smaller frequent merges are usually the best approach. It's better to create many small merge problems than one giant merge problem. The diagram on the left shows what to avoid with Git. A branch was made off of the initial commit and then more branches and commits were made without merging back into the master branch. Notice that the master branch has been changing as we've been working. It's better to frequently merge as shown in the diagram on the right. If your project is a software project, decoupled modular code is much less likely to have merge conflicts. In some ways, the number and complexity of merge conflicts is a test of how modular your code is. Next, we will discuss resolving a merge conflict. Resolving a merge conflict between two branches involves three commits. Let's look at a simple example to help understand these three commits. In this commit graph, the project starts with commit A on the master branch. A feature X branch was created off of commit A. Commit B was then made to the master branch, then commit C was made to the feature X branch. Let's assume that we are finished with feature X and want to merge it into the master branch. We've checked out the master branch as you can see from the head reference pointing to the master branch label. The first commit involved with resolving a merge conflict is the commit at the tip of the current branch. We call this commit, ours or mine. In our example, the current branch is the master branch and the tip is commit B. The second commit involved with resolving a merge conflict is the commit at the tip of the branch to be merged. We call this commit, theirs. In our example, the branch to be merged is the feature X branch and the tip is commit C. The final commit involved with resolving the two branch merge conflict is the common ancestor of the two branches. We call this commit, the merge base. In our example, the most recent commit that both branches contain is commit A, so commit A is our merge base. Here are the basic steps to resolve a merge conflict. You start out just like with any other merge by checking out the base branch. In this case, the base branch is the master branch. You then attempt to merge the feature X branch into the master branch. Git will inform me that there is a merge conflict, both branches modified the same hunk in fileA.txt in different ways. At this point, Git has modified fileA.txt showing you exactly where the conflicts are and has placed the file in your working tree. You then open fileA.txt and resolve the merge conflict. This is the part that requires human judgment. Once fileA.txt looks the way that you want it to, you stage it so that it becomes part of the merge commit. You then commit the merge. At this point, the branches are merged. Just like with other merges, you can then optionally delete the feature X branch label. The key point here is that, when attempting a merge, files with conflicts are modified by Git and placed in the working tree. You need to fix those files before executing a successful merge. Let's resolve a merge conflict using source tree. We see here that our commit graph has three commits. The original commit added feature one. A feature two branch was made off of the original commit and a commit was made to that branch. The current commit on the master branch added feature three. We've intentionally modified the same hunk in both branches, so that a merge will result in a conflict. We want to merge the feature two branch into the master branch, so we start by checking out the master branch. Next, we clicked the merge button to begin the merge process. We are then asked to pick a commit to merge into our current branch. We select the tip of the feature two branch, then we click OK to start the merge process. At this point, Git sees that we've modified the same hunk in conflicting ways on the two branches. You are notified that the file or files that contain the conflicts have been modified and placed in your working tree. You have to fix the merge conflicts before you can execute a successful merge. Click OK to close this message. You will notice that Git has modified your working tree. There is an indicator of changes in the file status tab and there are uncommitted changes shown in your history. If you click on the uncommitted changes item in the history, you can see that fileA.txt has been modified, and you can see the changes to the file in the lower right. You can use any editor that you want to fix the conflicted file. This can be a simple text editor or a custom tool called a diff or merge tool. We'll keep it simple here and use a simple text editor. When you view fileA.txt, you can see that Git marked up the file in hunks where there are conflicts. Conflicted hunks are surrounded by less than and greater than signs that are called conflict markers. This file has one conflicted hunk immediately after the feature one line. Any text that isn't surrounded by conflict markers was cleanly resolved by Git. The first part of the conflict marker is labeled head. We have checked out the master branch, so this line is from the file in the master branch. This is the ours commit in the merge. After the equal signs is the line feature two. This is labeled with the branch name, so this line comes from the feature two branch. This is the theirs commit in the merge. So basically, what happened is that Git saw these changes and didn't know what line two of fileA.txt it should save. Should it save feature three or should it save feature two? That's why the merge conflict was presented, Git needed a human to make a decision. We can use our text editor to fix fileA.text. We have ordered the features nicely in the file. This file will be part of the merge commit. Once our conflicted file has been fixed, we can add it to the staging area so that it becomes part of the merge commit. We can then click commit to continue the process of creating the merge commit. The default commit message for the merge commit is displayed for you. You can modify this in any way that you would like. Notice that there are commented lines that show the files that had merge conflicts. You can uncomment those by removing the pound signs. If you uncomment them, they will be part of the merge commit message. When the message is written the way you want, click Commit to create the merge commit. This time, there should be no merge conflicts. After a successful merge, you have the commit graph shown here. The master branch now contains all three features in the correct order. As a final step, you have the option of deleting the feature two branch label, since the master branch contains all of the commits. Here, we have deleted the feature two branch label and finished the merge. Finally, we will discuss aborting a merge attempt. Let's say that you attempted a merge that resulted in a merge conflict. You may choose to undo the merge attempt, rather than trying to resolve it. To do this, start by selecting Reset from source tree's Repository menu. Click on the Reset All button. This will abandon all local changes including the files changed by Git because of the merge conflict. Click Reset All to complete the reset. You are now back to the state before the merge attempt. Here's a review of what we've discussed in this video. Merge conflicts occur when two branches modify the same hunk. When a conflict occurs, Git will create files in the working tree containing conflict markers, fix, add, and commit the conflicted files. Now, it's time for you to work on the topics discussed in this video, separate instructions are provided for you.