How To Carry Out Complex Git Merge Tasks
انتشار: تیر 02، 1402
بروزرسانی: 18 تیر 1404

How To Carry Out Complex Git Merge Tasks

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:

The Submline Merge interface, showing a list of commits on the left-hand side of the screen, along with a summary of the changes and conflicts with a specific commit on the right.
The Sublime Merge app.

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.

To use this command, checkout to a branch you’d like to rebase to. From there, you can use the following command:

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

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

Note that you can also see this combined diff format within Git’s log using a couple of commands:

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.

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.

Its stable release supports Windows and Linux\xa0and 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.

Summary

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.

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.

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.

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:

A portion of the Onivim2 screen showing the Command Palette and the Git: Merge Branch command.
Accessing the Git: Merge Branch command from the Command Palette in Onivim2.

The git log --oneline command is great if you want to see the revision IDs and commit message relating to the current branch:

A portion of a Terminal window that shows the output for a one line Git diff command. It shows a minimal number of details: the commit’s hash, branches, and message for each before showing the Terminal prompt.
Running a one line git diff command in the Terminal.
git merge -s resolve <branch1> <branch2>

Before this, there are some advanced merge conflicts that you have to know how to resolve.

How To Deal With More Complex Git Merge Conflicts

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.

git log --oneline --left-right <branch1>...<branch2>
git merge -X theirs <branch2>

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.

Let’s look at these in more detail and start with the review process. From there, we can show you a quick way to undo a Git merge, then look at specific commands for more advanced use cases.

Review Commits

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:

You can choose to abort or reset a merge that’s in progress with the following commands:

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.

git reset --hard <reference>

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.

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:

A Terminal window that shows the output of a git diff command. It shows details of the changes in green and red text, along with more details of the differences with file names within the repository.
Running a git diff command in the Terminal.

However, you can give Git greater clarity on what you want to do:

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.

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.

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:

Many of your merge conflicts could happen on a local repo. In these cases, git reset is the command you need. However, this command has more parameters and arguments to dive into. Here’s how you use the command in practice:

git checkout --conflict=diff3 <filename>

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.

The first strategy might not need you to carry out any action to perform. A fast-forward merge shifts the pointer to the latest commit on main without creating an extra commit (which can be confusing.) It’s a clean approach that many developers will use as standard.

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.

Fast-Forward Merging

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.

Merge Logs

git show

git log --cc -p

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.

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.

Subtree

git merge -s ours <branch1> <branch2>

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.

This takes the typical navigation that a checkout provides and creates a comparison between the two files that shows the merge conflict:

A code editor that shows the results of running a git checkout --conflict command. It highlights areas of code in red and uses symbols to denote where there’s a change that prevents a commit to take place.
Checking out a conflict within a specific project file.

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

If you’d like to secure high-quality\xa0application 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.

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>
git merge -s subtree <branch1> <branch2>
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

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.

Which of these Git merge strategies will get you out of a tight spot? Let us know in the comments section below!



git rebase -i <reference>

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

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.

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:

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.

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.

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).

Octopus

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.

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.

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.