Git conflicts occur when Git is unable to automatically merge changes made to the same lines of code or when changes overlap in a file across branches. This often occurs in RocketPy repository when two developers make changes to the same file and try to merge them. In this scenario, Git pauses the operation and marks the conflicting files, requiring manual intervention.
Merge
The merge operation combines the changes from one branch into another. It creates a new commit that marks the merging of the two branches together.
- Retains the full history of both branches.
- Non-linear history shows how changes were combined.
- The history can become cluttered if there are many branches, due to the number of merge commits.
Rebase
The rebase operation integrates changes from one branch into another by reapplying the commits on top of the target branch. It results in a more linear history.
- Produces a cleaner, linear commit history.
- Easier to follow the sequence of changes.
- Can rewrite history, leading to potential issues when working on shared branches.
Let's consider a common scenario from which conflicts can arise:
updating a feature branch with the latest changes from the branch it was created.
Both merge and rebase can be used to update the feature branch.
However, the rebase option is highly recommended to keep a more linear history.
Suppose you have two branches, enh/feature that was branched off develop.
It is likely that develop has been updated since you branched off enh/feature, therefore before merging enh/feature into develop, you should update enh/feature with the latest changes from develop.
One way to do this is by merging develop into enh/feature as follows:
git checkout develop
git pull
git checkout enh/feature
git merge developIf there are conflicts, Git will pause the operation and mark the conflicting files. VS Code provides a visual interface to resolve these conflicts in the Merge Editor.
If you want to abort the merge, you can use git merge --abort.
Similarly, another way to update enh/feature with the latest changes from develop is by rebasing enh/feature onto develop as follows:
git checkout develop
git pull
git checkout enh/feature
git rebase developDifferently from merge, if there are conflicts, they must be resolved commit by commit. After resolving each step conflicts, you can continue the rebase with git rebase --continue. If you want to abort the rebase, you can use git rebase --abort.
Generally, the maintainers will inform you which operation to use when merging your PR. Notice that there is no wrong way to merge branches, but rebase is usually preferred to keep a more linear history.
Furthermore, it is important to avoid letting conflicts accumulate, since they can become harder to resolve. It is recommended to update your feature branch frequently with the latest changes from the branch it was branched off.
When conflicts arise, Git marks the conflicting files. The file will contain markers like:
<<<<<<< HEAD
Current branch changes
=======
Incoming branch changes
>>>>>>> branch-nameThe HEAD section contains the changes from the current branch, while the branch-name section contains the changes from the incoming branch.
The ======= line separates the two sections.
One can manually edit the file to resolve the conflict, removing the markers and keeping the desired changes, however for convenience it is recommended to use a visual tool like the Merge Editor in VS Code.
When a conflict occurs, VS Code will open the Merge Editor to help you resolve it.
- Open the conflicting file (marked with a
!). - The Merge Editor will show the conflicting sections side by side.
- Click on the
Accept Current ChangeorAccept Incoming Changebuttons to keep the desired changes, sometimes both changes will be kept or even a manual edit will be necessary.
More details on VS Code interface and conflict solver can be found in VS Code Docs. After resolving the conflicts, save the files, make sure all conflicts are resolved, and then commit the changes.