- Lab
- Core Tech

Guided: Advanced Merge Strategies
In this Git lab, you will deal with complex merging scenarios, common in collaborative development environments. The lab focuses on deepening understanding and practical skills in utilizing Git's advanced merging strategies, including how to use ours and theirs merge options. You will walk away with a nuanced understanding of each merge strategy's implications and best-use cases, enhancing your capability to manage code merges in a collaborative setting with precision and efficiency.

Path Info
Table of Contents
-
Challenge
Introduction
Welcome!
In this guided Git lab, you will be put into a scenario that will help you learn some advanced merge strategies and options, and more importantly, when to use each one.
Tip: Before you jump in
You should already be familiar with the essentials of using `git merge` and committing files. Additional information or context is provided with tips like this to dive deeper or help remind you how to use Git commands.The demo form is written in plain JavaScript, HTML, and CSS but you don't need to know the languages to complete the lab. Instead, you'll have to handle each merge scenario using the appropriate strategy and the lab will verify the files look correct.
info> Since this lab relies on the file system and Git for validation, some Checks depend on previous steps and cannot re-run later in the lab. It would be best to fully complete each step before continuing on.
info> If you are stuck, you can refer to the
solution/INSTRUCTIONS.md
file for complete solution steps. You can also reset the environment under Settings to get the file system back to the default state.Your First Command
Before you start, let's make sure the lab is set up correctly. ## You've Been Promoted
Throughout the lab, you will play the role of a lead engineer and be put into a scenario working on a user profile form that your team has been enhancing with new features and bug fixes for a major release.
Feel free to view the profile form in the Web Browser tab in the lab, or explore the files in the Filetree.
Once you're ready, it's time to integrate their changes and get the new form deployed out to production!
-
Challenge
Creating a Merge Conflict
The Last Minute Avatar Picker
You just got a phone call from your boss who said there needs to be a way for a user to upload a file to be their avatar photo.
Gosh, you have to deploy this tomorrow morning! Better get it done quick. ## A Plea for Help
Oh darn, you don't have any more time to work!
You're going to need to cut it short and ask a teammate to help.
Luckily, Henri is working and still has a few hours left.
You tell him what's going on and he says, "No problem!"
An hour passes...
Henri tells you the code is ready and he pushed it into a branch named
henri/picker
.Fantastic, now all you need to do is merge his changes into the current
master
branch. Uh-oh, what's that message saying in the Terminal?CONFLICT (content): Merge conflict in index.html
There's a conflict with our local changes and Henri's new changes.
Let's see how you can resolve this...
-
Challenge
Resolving Conflicts Using Their Version
A State of Conflict
When you ran the
git merge
command, Git attempted to merge Henri's commits into your working tree.However, since you both worked on the
index.html
file in the same place, you created a merge conflict.What exactly is the problem? When the diff is displayed, you will see Git merge conflict markers like this:
++<<<<<<< HEAD + <label for="avatar">Upload a file...</label> + <input type="file" name="avatar"> ++======= + <label for="avatar-picker">Upload a file...</label> + <input type="file" name="avatar-picker"> + </form-group> + <form-group> + <label for="username">Username</label> + <input type="text" name="username" required> ++>>>>>>> henri/picker
The first section is your
HEAD
branch changes which are "our" changes, and the second section are thehenri/picker
changes which are "their" changes.Different merge tools can visually display these changes side-by-side and provide quick and easy ways to go through each change to accept or reject changes.
However, you trust Henri's changes and it's okay if it overwrites your own. In this case, you can tell Git to skip any conflicts with your code and simply take theirs (the bottom section).
Let's try it out.
Aborting a Merge
First, you have to abort the current merge operation.
Use "Their" Changes
Next, you'll retry the merge but this time you'll pass a new argument:
-X theirs
You could also pass the longer form,
--strategy-option theirs
but-X
is the short form.This strategy option will tell Git to resolve any conflicts automatically by taking the other branch's code over ours (that's why it's called "theirs"). ## What Did This Do?
When you originally made your change, you replaced the Username input with an avatar picker. This was a mistake, but now if you check the
index.html
file, you will see that the missing Username form input is back in place because it was in Henri's branch. You prioritized Henri's changes over yours when merging which fixed your form.When Should You Use
theirs
?You may use the
theirs
merge strategy option when you are certain you don't care about your own changes to the branch and simply want to take whatever is from the other branch.There could be many reasons this might make sense:
- When taking a teammates changes that redid your work
- When merging in a hotfix or other high-priority update
- When writing scripts that should be non-interactive
However,
theirs
isn't the only merge strategy option available. What if we'd like to prioritize our changes? -
Challenge
Resolving Conflicts Using Our Version
Don't Forget to Validate
After getting a good night's sleep, you wake up to a message from your boss:
Boss: Hey team, the new avatar picker looks great, but it's missing validation. Can you add that quick before release?
OK, fair enough -- you should run validation for a user's avatar. Your code is ready! Now you are ready to submit it for review and get the team's sign-off.
A Case of Miscommunication
But wait -- what's this?
Henri just sent the following message to the team:
Henri: Finished the avatar validation, it's in the
henri/picker-validation
branch. Take a look please!Oh gosh! You just duplicated work because you forgot to tell people you were working (it was an honest mistake, usually Henri's asleep)!
OK, let's take a look at Henri's changes. You should see a diff like this:
--- a/index.js +++ b/index.js @@ -16,7 +16,8 @@ function onSubmit(e) { function validateAvatarPicker(avatarFilename) { // Note: The server will double-check the content and MIME type if (avatarFilename.endsWith(".png") || - avatarFilename.endsWith(".jpg")) { + avatarFilename.endsWith(".jpg") || + avatarFilename.endsWith(".jpeg")) { return true; } return false;
In this case, it actually looks like Henri forgot to add support for the "JPEG" file extension. But otherwise, the validation logic is mostly the same (great minds think alike, you say to yourself).
Preferring Our Changes
You could perform a regular merge, but then you'll have to manually resolve the conflicts. You also don't want to merge using the
theirs
strategy, because you want to keep your.jpeg
validation changes.Instead, you'll pass the
-X ours
merge strategy option. This will tell Git to resolve any conflicts with your code instead of their code.Let's try it out. ## What Did This Do?
When you made your validation change, you checked for the following file extensions:
.png
.jpg
.jpeg
But when Henri wrote their validation logic, they forgot to add
.jpeg
.Now if you check
index.js
, you will see your changes are preserved with the correct file extension checks. In addition, if Henri had added any new files, you would have merged those in as well. It's only in the case of a conflict that our changes are preferred over theirs.When Should You Use
ours
?You may use the
ours
merge strategy option when you are certain you don't care about the other branch's changes and simply want to take whatever is from your branch.There could be many reasons this might make sense:
- When taking a teammates changes and extending their work
- When merging in a hotfix or other high-priority update
- When writing scripts that should be non-interactive
You've now successfully used both the
theirs
andours
advanced merge strategy options.Hopefully this is the last merge you'll have to do before the major release.
And as soon as you think this, your phone's incoming message sound dings again...
-
Challenge
Creating an Audit Trail with `Ours` Merge Strategy
Making Auditors Happy
As a bead of sweat trickles down your forehead, you squint to read the new message from your other teammate, Janice who is on the Compliance team:
Janice: Hey team, remember that when we initiate the release we need to document the change in the
audit
branch.Ah yes, the hoops you have to jump through for compliance purposes.
Since it's time to push the new release, you'll need to switch to the
audit
branch. Did you notice something weird? There are no files in the audit branch!The
audit
branch is a formal placeholder for compliance reasons. It is supposed to be a reference for the legal team to keep track of a "clean" release history. This means it doesn't need to contain any files but the Git history needs to matchmaster
and it's standard process of your team to update it during a release. (Even though it sounds strange, you've learned not to ask too many questions when it comes to legal compliance.)To mirror
master
's history, how can you do that without changing any files?The Default Merge Strategy
If you look at the output in the Terminal after having done the last merge, you should have seen this message:
Auto-merging index.html Merge made by the 'ort' strategy.
This is the default Git merge strategy. This is what you use day-to-day without thinking and it performs a 3-way merge.
History Lesson: `recursive` used to be the default
There is an older merge strategy named `recursive` which was the default until Git v2.33.0. That's why `ort` is actually an acronym that stands for "Ostensibly Recursive's Twin".
ort
adds some additional features which is why it's now the default.You can still pass the
-s recursive
merge strategy along with some additional parameters that can result in less merge conflicts (but might be less accurate).Only Merging Commit History
In this case, you don't want to actually take any files from the other branch -- you just want the commit history.
To handle this, you can switch the merge strategy to
ours
instead ofort
. You can change the merge strategy using the-s <NAME>
or--strategy <NAME>
command-line switch. Notice how the output has changed to say:Merge made by the 'ours' strategy.
You'll also notice the working tree has remained unchanged -- no files were modified or added.
Now that you've merged in
master
to theaudit
branch using theours
merge strategy, let's see how this impacts the commit history by viewing the history of the branch. In the commit history, you should see a commit like this:commit <sha> Author: PS User <psuser@labs.pluralsight.com> Date: <date> Committed validation changes
Git merged in the history of
master
but did not modify the working tree or files in the branch. It effectively preserves the working tree of the current branch.Even though it's rare, hopefully you can see how the
-s ours
merge strategy might be useful in very specific situations like legal compliance.Terminology: Merge Strategies vs. Merge Strategy Options
You may wonder what the difference is between using the
-s ours
argument vs. the previous-X ours
argument. Aren't they the same?The
-s
(or--strategy
) argument specifies a merge strategy and each strategy may take different options, which are passed by the-X
(or--strategy-option
) argument.The
ort
merge strategy is the default so in previous steps you did not need to explicitly pass-s ort
but effectively that's what you were doing.In this step, you switched to a different merge strategy,
ours
which can also take options. -
Challenge
Next Steps
Congratulations, you've finished all the tasks needed for the new user profile release and your customers (and boss) are happy with the results! 🎉
Here's a Recap
- The default merge strategy is
ort
and it replaces the originalrecursive
merge strategy. - There are two advanced merge strategy command-line switches for Git:
-s, --strategy
-- The merge strategy to use (default:ort
)-X, --strategy-option
-- The merge strategy option to use
- You can pass two merge options to the default
ort
strategy,theirs
andours
using the-X
or--strategy-option
switch. - The
theirs
merge strategy option will resolve conflicts using "their" version of changes. - The
ours
merge strategy option will resolve conflicts using "our" version of changes. - You can switch the merge strategy from
ort
toours
to ignore changes in the other branch while merging. This will copy history but maintain the current branch's working tree, effectively "mirroring" history. This can be useful in specific situations like legal compliance.
You can read and learn more about the available merge strategies in the official Git handbook.
Bonus Challenge: Merging Multiple Branches at Once
You can pass multiple branches to
git merge
and it will use theoctopus
merge strategy. Reset the lab and try merging bothhenri/picker
andhenri/picker-validation
at once intomaster
on Step 5 to see what happens. - The default merge strategy is
What's a lab?
Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.
Provided environment for hands-on practice
We will provide the credentials and environment necessary for you to practice right within your browser.
Guided walkthrough
Follow along with the author’s guided walkthrough and build something new in your provided environment!
Did you know?
On average, you retain 75% more of your learning if you get time for practice.