Skip to main content

GitKit (VSCode Edition): Learn git and GitHub in Context

Section 1.5 Merge Conflicts Instructor Notes

At the start of this chapter students will have made pull requests for the "Round 2" issues. Initially GitHub will report that these PRs can be merged automatically. However, the instructor will begin this topic by introducing changes to the upstream main that create merge conflicts with the fixes to each of the "Round 2" issues. Students will then observe that their PRs go from being able to be merged automatically to containing conflicts.
This chapter then focuses on the resolution of merge conflicts. The concepts of merge commits, common ancestors, best common ancestor, and non-conflicting and conflicting changes are introduced. The topic then covers the process of merging main into a feature branch, git’s raw conflict information and the use of graphical merge tool. The hands-on activity concludes with the students having resolved the merge conflict in their "Round 2" pull request. Note that these PRs are never merged into the upstream as part of the GitKit activities.
The exercises in this chapter have the students perform the following major tasks:
  1. Synchronize their main branches with the upstream main branch, which will bring in the changes that conflict with their "Round 2" fixes.
  2. Merge the main branch into their feature branch, which will create the merge conflict.
  3. Examine the raw merge conflict information.
  4. Use the VS Code merge tool to resolve the conflict.
  5. Commit the merged result to their feature branch.
  6. Push the feature branch to update their pull request.

Subsection 1.5.1 Slide Notes

  • Slide 2.
    Another opportunity is taken to review of the steps involved in the forking workflow. Students typically have a good handle on these steps and how they are ordered when using the forking workflow to upstream changes.
  • Slides 3-4.
    The instructor may merge a provided branch that creates conflicts with the "Round 2" issues (See: Subsection 1.5.2) either before or during class. Merging the conflicts during class is the preferred option if time permits. This allows the instructor to show a few student "Round 2" PRs and that indicate that they can currently be merged automatically. Then merge the PR with the conflicts and look at the PR’s again to show that they now contain conflicts. Slide 4 can be used to illustrate how the conflicts have arisen.
  • Slide 5.
    Introduces the merge operation and merge commits. At this point, a merge with no conflicts (i.e. like the "Round 1" PRs) is illustrated. This is shown from the project maintainer perspective with the feature branch from a PR being merged into the upstream main branch. Later this will be reversed when students are merging their copy of the upstream main branch into their feature branch to resolve conflicts (see Slides 19-23).
    Merge commits are shown in the diagram as a colored dot with a ring around them. A merge commit for non-conflicting changes are shown with a white ring around them. The ring is added to indicate that the meta information about the commit is different than what was contained in the feature branch. This also records, in the project history, the fact that the changes were merged into main.
  • Slides 9-12.
    Uses a text based example to introduce the concepts of common ancestors and best common ancestor, and then uses those to identify conflicting changes and non-conflicting changes. One way to identify these changes is first to compare the feature branch to the best common ancestor and highlight all changes in the feature branch. Then repeat, but compare the main branch to the best common ancestor and highlight all differences in the main branch. Then any lines that are highlighted in both the feature branch and the main branch are conflicting changes. All other highlighted lines are non-conflicting changes.
    Note that in these examples the identification of conflicting changes is simplified to be line based. That is, if a change is found, the entire line is marked as containing a change. Similarly, if a line is changed in both the feature branch and the main branch, the entire line is marked as a conflict. The algorithm used by git is more complex than this simplified approach, but the concept is sufficiently the same for the purposes of these activities.
  • Slides 13-16.
    These slides contain some additional practice exercises for identifying non-conflicting and conflicting changes, and merging the results. These activities can be done and discussed in small groups during class if time permits.
  • Slide 17.
    Establishes the basis for how developers (i.e. the students) will resolve merge conflicts. While a maintainer could resolve the conflict, more typically the developer who submitted the PR will be expected to resolve any conflicts in their PR.
  • Slide 18.
    The way that a developer will resolve a merge conflicts is to pull the (conflicting) changes to the upstream main to their local repository. They then merge the main branch into their feature branch. They then push their updated feature branch to their origin, which automatically updates the PR for that branch. Because the PR has been updated the maintainers are now able to review not only the proposed changes but also the way that the merge conflicts were resolved.
    Note that this is backwards from what was done earlier. In Chapter 4 the maintainer was merging the feature branch into the main branch. Here the developer is merging the main branch into their feature branch. The rule that developers "only commit to feature branches" can be used as a grounding for why developers do the merge in this direction.
  • Slide 19.
    Illustrates in more detail the merge of both non-conflicting and conflicting changes from the main branch into the feature branch. Here the merge commit contains a colored ring instead of a white ring (as it did earlier). The colored ring indicates that the merge commit blends the changes that were contained in its two parent commits.
  • Slide 20.
    Shows the raw merge conflict information that is produced by git when a merge creates a conflict. This information can be edited manually in any text editor. However, it is often difficult to identify exactly what changes exist. This is good motivation for the use of a graphical merge tool that makes it easier to see what changes have been made and where the conflicts exist.
  • Slides 21-23.
    Shows the graphical merge tool that is built into VS Code. The exercises guide the students through use this tool to resolve the conflicts in their PRs for their "Round 2" issues.
  • Slide 24-25.
    Here for review and reference and not much time needs to be spent on these slides. The final slide collects into one diagram everything that is a part of the forking workflow. It has a lot going on, but by this point students should be able to make sense of each of the actions that are illustrated.

Subsection 1.5.2 To-Do List

  1. If time permits, monitor the "Round 2" tickets in the issue tracker. There are only 4 "Round 2" issues and thus there will need to be multiple students working on each. If a student uses the the comment from Section 2.2, and they are the first to do so, the issue will be assigned to them automatically. The instructor can manually assign the issue to all other students that comment on it.
  2. Create, but do not merge, a pull request for the addRound2Conflicts branch in the upstream. When merged this branch will create a conflict with each of the changes requested in a "Round2" issue. Thus, this PR should not be merged until after the students have synchronized with the upstream main at the start of this chapter. If it is merged before they synchronize, then they will begin the fix for their "Round 2" issue with the (conflicting) changes already in place, and thus their fix will not generate the expected merge conflict. If students find themselves in this situation, there are instructions in the chapter guide them through a process that will create a conflict for them.
  3. Just before class, or during class merge the PR for the addRound2Conflicts branch. It has been effective to do the merge of the PR for the addRound2Conflicts branch live in class.

Subsection 1.5.3 Exercise Notes

  • In this exercise there are no conflicting changes and the merge would be able to be completed automatically. However, if all of the non-conflicting changes are merged into the result the program will not produce the correct result. The point being that automatic merges can check for structural conflicts, but not logical or semantic conflicts and thus caution should be used when performing merges.
  • Inevitably some students will be behind on their work and will complete their sync with upstream main after you have merged the PR for the addRound2Conflicts branch. In these cases, their pull requests will not create a conflict to be resolved. These students should follow the instructions given in Section 5.10. These directions have them pull the mergeConflictPractice branch and create a pull request for it. That PR will then contain conflicts with the changes in the addRound2Conflicts branch that was merged into main. They will then complete the activity using the mergeConflictPractice branch as it it were their feature branch. Students not in this situation, but who would like additional practice can also pull and use the mergeConflictPractice branch at the end of the activity.
  • By default, VS Code does not display the best common ancestor in its merge tool. The steps given in these questions has the students change the VS Code configuration such that it includes the best common ancestor.
  • If the student did not need to use the merge-conflict-practice branch in Exercise 5.2.4, then they can use it at this point for additional practice with resolving merge conflicts.
You have attempted of activities on this page.