Once you invoke this command, the commit history removes later commits and resets the history to the referenced ID. It’s a clean way to undo a Git merge but isn’t suitable for all cases.
For the signs, a plus sign denotes whether a line is an addition to the working copy but not in that specific side of the merge, and a minus sign denotes whether the line is removed.
git merge -s octopus <branch1> <branch2>
Get started with a free trial of our Application Hosting or Database Hosting. Explore our plans or talk to sales to find your best fit.
As with a fast-forward merge, you won’t normally need to specify a recursive merge. However, you can make sure Git doesn’t choose something like a fast-forward merge using the following commands and flags:
On the whole, you use Git merge for many conflicts. However, rebasing has lots of benefits too. For example, while merging is simple to use and lets you preserve the context surrounding your merge history, rebasing can be cleaner as you can simplify your commit history into one.
This is because Git looks at those lines and deems the negative space to be a change.
When it’s time to merge, Git will recurse over the branch in order to make its definitive commit. This means a merge commit will have two parents once you complete it.
The second line uses the -s strategy option and explicit naming to carry out a merge. Unlike a fast-forward merge, a recursive merge does create a dedicated merge commit. For two-way merges, a recursive strategy is solid and works well.
Ours and Theirs
Logging is crucial for almost every piece of software that passes data. For Git, you can use the log to ascertain more detail on a merge conflict. You can access this information using git log:
While you can reverse more complex merge conflicts and the resultant changes, it can be tough because commits are often permanent.
As such, there are a lot of steps you need to follow:
First, you need to review commits and find references to the merges you need.
Next, checkout branches to review commit histories.
Once you have knowledge of the branches and commits you need, there are specific Git commands based on your desired action.
While a Git merge can be straightforward, there are often many other times when you need an advanced approach. This will see you use strategies such as recursive merging, three-way merges, and many more. You may even need to undo a Git merge at some point.
As such, you can use the checkout almost as a risk-free sandbox. However, if you want to preserve the changes, you can checkout the branch and give it a new name using git checkout -b <branch-name>. This is a solid way to undo a Git merge, but there are more nuanced ways to do this for advanced use cases.
Using git reset
Negative space and its usage is a common discussion point. Some programming languages will use different types of spacing, and even individual developers will use different formatting.
While these two arguments seem similar, they have a unique difference. If you choose to ignore all negative space, Git will do so. It’s a broad brush approach, but in contrast, -Xignore-space-change will only count sequences of one or more negative spaced characters as equivalent. As such, it will ignore single spaces at the end of lines.
Octopus merges are like the polar opposite of ours and theirs merges. The typical use case is where you want to include multiple commits for similar features and merge them into one. Here’s how you pass it:
For extra safety, you could also review the merge using the --no-commit command, in order to check that you ignore and count negative space in the right way.
Sometimes, you need to stop the merge altogether and start from a somewhat clean slate. In fact, both of the commands we mention suit situations where you won’t yet know what to do with a conflict.
Get all your applications, databases, and WordPress sites online and under one roof. Our feature-packed, high-performance cloud platform includes:
Easy setup and management in the MyKinsta dashboard
24/7 expert support
The best Google Cloud Platform hardware and network, powered by Kubernetes for maximum scalability
An enterprise-level Cloudflare integration for speed and security
Global audience reach with up to 35 data centers and 300 PoPs worldwide
This might mean you might not be able to start the merge at all due to pending changes or have a failure during a merge that requires manual intervention. Once your working directory is ‘clean’ you can begin. Lots of times, Git will notify you of a conflict once you begin a merge:
You could use git revert <reference> to undo a Git merge. Note that you always need to specify a commit reference, or the command won’t run. You can also pass HEAD to the command to revert to the latest commit.
You can choose to abort or reset a merge that’s in progress with the following commands:
You can take the view you get with git log further to look into merge conflicts. In typical circumstances, Git will merge code and stage everything that succeeds. This will leave you with only conflicting lines, and you can see them using the git diff command:
Git is an essential tool to collaborate and manage code changes efficiently. However, if multiple developers work on the same code, conflicts may arise. Git merge strategies will help you resolve these conflicts, and there are lots of ways to do the job. For more complex Git merge strategies, you need to turn to advanced tactics.
Note that the default argument option is merge, which you don’t have to specify unless you change the merge conflict style away from the default.
Ignoring Negative Space
We’re going to look at a few important strategies you need to understand. They aren’t in any order, and at some point in your development career, you may need them all. What’s more, you will also want a solid understanding of basic Git concepts, such as pointers, branches, and commits.
The Difference Between Two-Way and Three-Way Merges
Mistakes can happen, and you can carry out merges that you need to walk back on. In some cases, you can simply amend the most recent commit using git commit --amend. This will open the editor to let you modify the last commit message.
If you’d like to secure high-qualityapplication hosting, we’ve got you covered. Our cloud-based app hosting services ensure your full-stack app is ready for prime time in no time.
One editor that offers a separate graphical user interface (GUI) for working with Git is Sublime Text. If you use this editor, Sublime Merge could be an ideal addition to your workflow:
You also get further options using the Command Palette. This is even the case in editors that build on top of VSCode’s open-source framework, such as Onivim2:
git merge <branch>
git merge --ff-only
This won’t always be possible, especially if you work in a large team. Even so, if you choose to merge your commits with a main branch that is current and without its own commits, this will carry out a fast-forward merge. You can do this in a couple of different ways:
This uses a ’Triple Dot’ to provide a list of commits involved in two branches during a merge. It will filter all of the commits both branches share, which will leave a selection of commits to investigate further.
Its stable release supports Windows and Linux and runs under the GPL license. This gives you basic functionality in order to compare branches, edit your merges, and more. You even get two- or three-way comparisons and support for other version control systems such as Subversion.
The technique starts with a main branch that may or may not have commits. In this case, you open a new branch, work on the code, and make commits. At this point, you also need to merge those changes back to main. A fast-forward merge has one requirement to pull off:
You need to ensure that no other commits take place on main while you work on your new branch.
git merge -X theirs <branch2>
With the work that takes place on a development project, Git is a godsend. However, if you have a lot of movers on the dancefloor, one or two will tread on each other’s toes. For your project, this means two developers may work on the same suite of code and both may commit. For these situations, you need to pull out some Git merge strategies to resolve the conflict.
In a nutshell, Git will look at three different snapshots to merge changes: the head of main, the head of the feature branch, and the common ancestor. This will be the final commit common to both main and the feature branch.
Handling multiple heads – i.e. merging more than one branch into another – can be a tricky scenario for a git merge. You could say you need more than two hands to resolve the conflicts. This is perfect for an octopus merge.
git reset --hard <reference>
You could also use git log --oneline --left-right --merge to only show commits either side of a merge that ‘touch’ a conflicting file. The -p option will show you the exact changes for a specific ‘diff,’ although note that this is only for non-merge commits. There’s a workaround to this, which we cover next.
Using the Combined Diff Format to Investigate a Git Merge Conflict
In practice, you won’t need to worry about whether a certain merge strategy is two-way or three-way. Lots of times, you have to use a strategy regardless. In any case, it’s helpful to know how Git ‘thinks’ when it comes to merging branches and repos.
git log --cc -p
Note that you can also see this combined diff format within Git’s log using a couple of commands:
The default option for git revert is -e or --edit. This will open the editor in order to amend the commit message before you revert. However, you can also pass --no-edit, which won’t open the editor.
git merge -s subtree <branch1> <branch2>
Given how conflicts can eat away at time, money, and resources, you need to figure out how to nip them in the bud fast. In most cases, two developers will work on the same suite of code, and both will decide to commit.
In contrast, git revert creates a new commit based on backtracking changes, then updates the reference pointers and makes the branch the new ‘tip.’ It’s also why you should use this command for remote repo merge conflicts.
Regardless of your choice of code editor, it often will include the ability to work with Git without using the command line. It’s even the case with Vim and Neovim, using Tim Pope’s Git Fugitive plugin, which is fantastic and simple to use.
The first part of this – git reset --hard – goes through three steps:
It moves the reference branch to its location before the merge commit.
The hard reset makes the ‘index’ (i.e. the next proposed commit snapshot) look like the reference branch.
It makes the working directory look like the index.
This means a subtree merge is fantastic if you want to combine multiple repos into one definitive article. It will also make the necessary changes to the common ‘ancestor’ tree of both branches.
A common situation during development is one where you create a new feature within your project that ultimately won’t get the green light. In many cases, you will have a lot of code to merge that’s also co-dependent. An ‘ours’ merge is the best way to resolve these conflicts.
git checkout --conflict=diff3 <filename>
However, there are a few dedicated third-party merge tools that focus solely on the task.
Dedicated Git Merge Apps
This can even be as straightforward as ignoring negative space or trawling through the search logs. However, you don’t always have to use the command line, either. There are plenty of apps to help you, and your code editor will often use a built-in interface too.
git merge --abort
Merging branches in Git is more like managing conflicts and resolving them. The greater the size of your team and project, the greater the chance of conflicts. Some of these can be complex and difficult to resolve.
When you invoke the merge, the new commit will have two ‘parents.’ One relates to the reference you specify, and the other is the tip of the branch you want to merge. In this case, -m 1 tells Git to keep the first parent – i.e. the specified reference – as the ‘mainline.’
An ours merge essentially means that the current branch contains the code de jure. This ties in with ‘theirs’ merges, which treats the other branch as correct. However, you need to pass another strategy option here:
It’s essentially a text file dumping station for every action within a repo. However, you can add further arguments to refine the view and only see the commits you wish:
The first is a command you use on a merge commit to see its history. The second command uses the functionality of -p to show changes to a non-merge commit alongside the combined diff format.
How To Undo a Git Merge
This ‘combined diff’ format adds two extra columns of information. The first tells you if a line is different between your (‘ours’) branch and the working copy; the second gives you the same information for the ‘theirs’ branch.
One of the safest ways to merge commits, a resolve merge is great if you have a situation that involves criss-cross merges. It’s also a quick resolution method to implement. You may also want to use this one for more complex merge histories – but only those with two heads.
While both git reset and git revert seem similar, there are some important differences. In the examples so far, the undo process involves moving the reference pointers and HEAD to a specific commit. It’s akin to shuffling around playing cards to create a new order.
However, you can give Git greater clarity on what you want to do:
Despite this, you have to take more care with rebasing, as the potential for errors is huge. What’s more, you shouldn’t use this technique on public branches, as rebasing will only affect your repo. To fix the resultant issues, you’d need to make even more merges and will see multiple commits.
Tools That Help You Manage a Git Merge Better
A recursive merge is often the default, as it will crop up during more common situations than other types of merge. A recursive merge is where you make commits on a branch, but further commits happen on main too.
From here, you can begin to work on the various files causing the conflict. Some of the tools and techniques we discuss next will help.
Aborting and Resetting Merges
However, you can add specific arguments to the git merge command that will overlook negative space in the relevant files:
In short, a subtree merge is what you want if you need to combine two repositories. In fact, you might struggle to understand which merge strategy is right for you. Later, we discuss some tools that could help.
This companion to a recursive merge could confuse you. We’ll try to explain this using a clear example:
First, consider two different trees – X and Y. This will often be two repos.
You want to merge both trees into one.
If tree Y corresponds with one of the subtrees in X, tree Y is changed to match the structure of X.
git merge -s resolve <branch1> <branch2>
However, for more information, you can run a git status and see the details:
The majority of merge conflicts will be straightforward to ascertain and resolve. However, in some cases, you might need to dig deeper in order to figure out both why a conflict happens and how to begin to fix it.
Using ours and theirs merges can be confusing, but it’s generally safe to stick to the typical use cases (that of keeping everything in the current branch and discarding the rest).
In a technical sense, this will check the file out again and replace the conflict markers. You might do this a few times throughout a resolution. Here, if you pass the diff3 argument, it will give you the base version and alternatives in ‘ours’ and ‘theirs’ versions.
The core concept of a merge is straightforward: you join two branches together in order to turn multiple commits into one. However, there are a number of techniques you can employ to make sure you commit and merge the right code.
However, resetting a merge means you revert the files back to a known ‘good’ state. The latter is something to consider if Git fails to start the merge. Note that this command will delete any changes you don’t commit, which means this one is more of a deliberate act that requires care.
Checking Out Conflicts
The two commands are similar, but you use them in different circumstances. For example, aborting a merge will simply revert the branch back to its state pre-merge. In some cases, this won’t work. For instance, if your working directory contains uncommitted and unstashed changes, you won’t be able to run an abort.
git revert -m 1 <reference>
This tutorial will discuss some complex Git merge techniques to add to your tool belt. In fact, we can dive right into the good stuff first!
An Introduction to Git Merge Strategies
You can also pass -n or --no-commit. This tells git revert to not create a new commit, but ‘inverse’ the changes and add them to the staging index and working directory.
The Difference Between Merging vs Rebasing in Git
git merge -s ours <branch1> <branch2>
For instance, Mergify is an enterprise-level way to merge code that integrates into your continuous integration/continuous delivery (CI/CD) pipeline and workflow:
Running the command will display a list of potential commits to be moved in the editor. This gives you complete scope to change how the commit history looks. You can also merge commits if you change the pick command to fixup. Once you save your changes, Git will perform the rebase.
Lots of times, you won’t need to specify that you want to run a fast-forward merge. This type of merge happens on solo projects, or those with small teams. In a fast-paced environment, this is a rare merge. As such, others will be more common.
Spaces versus tabs is a battleground we won’t join. However, if you have situations where formatting changes from one to the other depending on the file and coding practice, you could run into this Git merge issue.
VSCode also includes similar functionality within its user interface (UI.) Older Atom users will find that Microsoft has carried on its fantastic Git integration here, complete with the ability to connect to GitHub without further extensions or add-ons.
This type of merge can handle as many branches as you need and works to ignore all of the changes on those other branches. It’s great if you want to clear the decks when it comes to old features or unwanted development. Here’s the command you need:
The git log --oneline command is great if you want to see the revision IDs and commit message relating to the current branch:
This takes the typical navigation that a checkout provides and creates a comparison between the two files that shows the merge conflict:
However, Git will refuse an octopus merge if you have to make a manual resolution down the line. For automatic resolutions, an octopus merge will be a default if you need to merge multiple branches into one.
Because a resolve merge uses a three-way algorithm to work with both your current branch and that you’re pulling from, it might not be as flexible as other merge methods. However, for the job you need it to do, a resolve merge is near-perfect.
To use this command, checkout to a branch you’d like to rebase to. From there, you can use the following command:
In lots of situations, your reference will be your main branch. The -i option starts ‘interactive rebasing.’ This gives you the opportunity to alter the commits as they move across. You can use this to clean up the commit history, which is one of the big benefits of using git rebase.
Some of the features here help you to automate the update of your pull requests before the merge, reorder them based on priority, and batch them too. For an open source solution, Meld might be valuable:
Which of these Git merge strategies will get you out of a tight spot? Let us know in the comments section below!