How to overcome your fear of git merge conflicts
- Introduction
- Setting the stage for a merge conflict
- Picture 1: How we got here
- Picture 2: The conflict when develop is applied to main
- Picture 3: How to understand the diff
- Picture 4: How to resolve the conflict
- Build with Naz video series on developerlife.com YouTube channel
Introduction #
There are few things that generate as much fear and anxiety in developers as git
merge
conflicts. git
is very popular and very powerful, and it is a low level command line
tool. And it is not very user friendly. It is meant to be orchestrate-able and automated
using scripts and CI/CD tools, and build systems; it is extremely flexible. It is not
meant to be used in an interactive manner w/ a human user at the keyboard.
This just creates an opportunity for others to come along and craft user experiences on
top of git
that are more use case driven. And these UXes can come in the form or GUIs,
TUIs, or even conversational interfaces.
But that’s not the focus of this article which is all about the CLI experience of inducing and resolving merge conflicts. So let’s get started.
Setting the stage for a merge conflict #
Let’s create a local repo from scratch and set things up so that we can predictably generate a merge conflict. Here’s what we will do at a high level:
- Create a local repo.
- Create a
main
branch. - Create a file in the
main
branch and add some content to it. - Create a
feature
branch based on themain
branch. - Modify the file in the
feature
branch. - Modify the same file in the
main
branch with a change that is going to conflict w/ a change infeature
branch. - Merge the
feature
branch into themain
branch.
Here’s a script to get you started:
#!/usr/bin/env bash
# Create a local repo.
export TMP_REPO_DIR="~/Downloads/tmp/git-merge-conflict-demo"
if [ -d $TMP_REPO_DIR ]; then
echo "Folder exists, recreating $TMP_REPO_DIR"
rm -rf $TMP_REPO_DIR
mkdir -p $TMP_REPO_DIR
else
echo "Folder does not exist, creating $TMP_REPO_DIR"
mkdir -p $TMP_REPO_DIR
fi
cd $TMP_REPO_DIR
git init
git checkout -b main
# Create a file in the main branch and add some content to it.
# This is the "OG change".
echo -e "This is a new feature.\n## 3. Example 3" > file.txt
git add file.txt
git commit -m "Add myexample3"
# Create a develop branch based on the main branch.
git checkout -b develop main
# Person A comes along and changes this line w/ a plus in the develop branch.
echo -e "This is a new feature.\n## 3. Example 3+" > file.txt
git add file.txt
git commit -m "Fix typo w/ plus in develop branch"
# Person B comes along and change this line w/ a minus in the main branch.
# This is going to conflict with the change in the develop branch.
git checkout main
echo -e "This is a new feature.\n## 3. Example 3-" > file.txt
git add file.txt
git commit -m "Fix typo w/ minus in main branch"
# Merge (using rebase, so no extra commit) the develop branch into the main branch.
git rebase develop
This results in a merge conflict. And when you run git diff
it looks like this:
diff --cc file.txt
index 89da142,ef43c8f..0000000
--- a/file.txt
+++ b/file.txt
@@@ -1,2 -1,2 +1,8 @@@
This is a new feature.
++<<<<<<< HEAD
+## 3. Example 3+
++||||||| parent of 7c0f0e4 (Fix typo w/ - in main branch)
++## 3. Example 3
++=======
+ ## 3. Example 3-
++>>>>>>> 7c0f0e4 (Fix typo w/ - in main branch)
Let’s use some pictures to understand the story of how we got here. And how to resolve this.
Picture 1: How we got here #
Picture 2: The conflict when develop is applied to main #
Picture 3: How to understand the diff #
Picture 4: How to resolve the conflict #
Build with Naz video series on developerlife.com YouTube channel #
If you have comments and feedback on this content, or would like to request new content (articles & videos) on developerlife.com, please join our discord server.
You can watch a video series on building this crate with Naz on the developerlife.com YouTube channel.
- YT channel
- Playlists
👀 Watch Rust 🦀 live coding videos on our YouTube Channel.
📦 Install our useful Rust command line apps usingcargo install r3bl-cmdr
(they are from the r3bl-open-core project):
- 🐱
giti
: run interactive git commands with confidence in your terminal- 🦜
edi
: edit Markdown with style in your terminalgiti in action
edi in action