Saturday 24 June 2023

How to Perform complex Git merging tasks

Git can be a lifesaver when it comes to the development of a project. If you have many dancers on the floor, then one or two of them will step on each other. This means that two developers can work on the exact same code suite and commit it. In these cases, you will need to use some Git merge techniques to resolve the conflict.

Even though a Git merging can be simple, you may need to use a more advanced approach in other situations. You will use techniques such as three-way merging and recursive merges. At some point, you may need to undo the Git merge.

This tutorial will cover some advanced Git merge techniques that you can add to your toolbox. We can jump right in to the good stuff!

Introduction to Git Merge Strategy

Merging is a simple concept: You join two branches to make multiple commits one. There are several techniques that you can use to ensure you merge and commit the correct code.

Here are a few strategies that you should know. You may need all of them at some point during your career in development. You will also need to have a good understanding of the basic Git concepts such as branches, pointers and commits.

What is the difference between two-way and three-way merges?

Understanding the differences between a three-way merger and a two-way merger is important. The majority of the strategies that we will cover in our next article are for three-way situations. It’s easier to describe a three-way merger. Take the following example.

If you merge these using a two-way approach, you lose a commit (likely on main). Instead, Git will create a new merge commit from both the current main and feature branches. You lose a commit if you merge them using the two-way method.

Git merges changes by looking at three snapshots: the main head, the feature branch head, and the common parent. This is the last commit that will affect both the main branch and the feature branches.

In reality, it doesn’t matter if a merge strategy is three-way or two-way. Many times you will have to use the same strategy. It’s always helpful to understand how Git “thinks” when merging repositories and branches.

Fast-Forward Merging

You may not have to take any action at all to implement the first strategy. Fast-forward merges shift the pointer from the previous commit to the most recent commit in main without creating a new commit (which could be confusing). This is a standard approach that will be used by many developers.

This technique begins with a branch which may or may have no commits. You open a branch, edit the code and commit. You must also merge these changes back into main at this stage. To pull off a fast-forward merge, you must meet one condition:

While you are working on the new branch, make sure that there is no other activity on main.

It’s not always possible to do this, especially when you are part of a large group. If you merge your commits into a current main branch without any commits of its own, it will still be a fast-forward merging. This can be done in two different ways.

git merge –ff only>

You won’t always need to specify if you want a fast-forward merging. This merge is common for solo projects or small teams. This is a rare merger in a fast-paced work environment. Other mergers will therefore be more common.

Recursive Merging

Recursive merging is the default because it occurs more often than any other type of merge. Recursive merging is when you commit to a branch but then further commits are made on the main.

Git will recurse the branch to commit its final version when it is time to merge. Once you’ve completed a merge commit, it will have two parent commits.

You won’t need to specify a merge recursive in most cases, just as you wouldn’t with a fast forward merge. You can use the following flags and commands to ensure that Git does not choose something similar to a fast-forward merg.

git merge –no-ff git merge -s recursive

The second line uses -s and explicit naming in order to perform a merge. A recursive merging creates a merge commit, unlike a fast merge. Recursive merges are a good strategy for two-way merging.

Ours and Theirs

It’s not uncommon to create a feature in your project, but it won’t be approved. You will often have to merge a large amount of code that is also co-dependent. The best way to solve these conflicts is by merging the code into a single ‘ours.’

This merge type can handle as many branches you need, and ignores all changes made to those branches. This is great for clearing out old features and unwanted development. This is the command that you need:

git merge –s ours

A merge of ours means that the current branch is the one with the legal code. This is similar to ‘theirs merges’, which treat the other branch as valid. You need to choose another option for this strategy:

git merge –X theirs

It can be confusing to use ours and theres merges, but you should stick to the standard cases (keep everything in the current tree and delete the rest).

Octopus

Handling multiple heads – i.e. Merging more than one branch can be tricky for a git merg. You might say that you need to use more than just two hands to resolve conflicts. This is the perfect way to merge octopus.

Octopus merging is the opposite of ours-and-theirs merges. It is common to want to merge multiple commits that are similar and include them in one. You can pass it in the following way:

git merge -s octopus

Git, however, will reject an octopus merger if you need to manually resolve the issue later. If you want to automatically resolve conflicts, the octopus merger will be your default option.

Resolve

A resolve merge is one of the most secure ways to merge commits. It’s great for situations that involve crisscross merges. This is a fast way to resolve a conflict. This method can also be used for merging histories with more complexity, but only if they have two heads.

git merge -s resolve

A resolve merge might not be flexible enough to handle all merge scenarios. It uses a three way algorithm that works with your current branch as well as the one you are pulling from. A resolve merge will do the job for you if it is what you want.

Subtree

This companion to a merge recursive could be confusing. This will be explained using an example.

This will often be two repos. You want to merge both trees into one. You will usually have two repos. You want to merge the trees together.

A subtree merger is a great way to combine several repos into a single definitive article. This will also make necessary changes to both branches’ common ancestor tree.

git merge -s subtree

If you are looking to merge two repositories, you will want to use a subtree merger. You might find it difficult to determine which merge strategy works best for you. We will discuss later some tools that can help.

You need to be able to resolve some advanced merge conflict before you can proceed.

How to deal with more complex Git merge conflicts

Git merges branches more like managing and resolving conflicts. Conflicts are more likely to occur the larger your team or project. Some conflicts can be difficult and complex to resolve.

You need to find a way to stop conflicts in their tracks as they can waste time, money and resources. Most often, two developers work on the exact same code and will both decide to commit.

You may not be able start the merge due to pending updates or you could have an error during a merging process that requires manual intervention. You can start once your working directory has been ‘cleaned’. Git can notify you of conflicts when you start a merge.

decoding=”async” class=”size-full wp-image-155619″ src=”https://kinsta.com/wp-content/uploads/2023/06/git-conflict.png” alt=”A Terminal window showing Git commands to show all branches, then merge changes. The error is displayed as a merge conflicts with instructions on how to resolve and commit the conflict results.” width=”1000″ height=”412″ srcset=”https://kinsta.com/wp-content/uploads/2023/06/git-conflict.png 1000w, https://kinsta.com/wp-content/uploads/2023/06/git-conflict-300×124.png 300w, https://kinsta.com/wp-content/uploads/2023/06/git-conflict-768×316.png 768w” sizes=”(max-width: 1000px) 100vw, 1000px”>

A Terminal window displaying a conflict between merges in Git.

You can also run git status to see more details.

decoding=”async” loading=”lazy” class=”size-full wp-image-155623″ src=”https://kinsta.com/wp-content/uploads/2023/06/git-status.png” alt=”A Terminal window showing the result of a git status command. It displays a list of unmerged paths in green with instructions on how to resolve them. width=”1000″ height=”342″ srcset=”https://kinsta.com/wp-content/uploads/2023/06/git-status.png 1000w, https://kinsta.com/wp-content/uploads/2023/06/git-status-300×103.png 300w, https://kinsta.com/wp-content/uploads/2023/06/git-status-768×263.png 768w” sizes=”(max-width: 1000px) 100vw, 1000px”>

A Terminal window displaying the results of running git status.

You can now begin working on the files that are causing conflict. The tools and techniques that we will discuss in the next section can help.

Resetting Merges and Borting

You may need to cancel the merge and start over. Both commands are useful in situations where you don’t know how to resolve a conflict.

The following commands allow you to cancel or reset an ongoing merge:

git merge –abort git reset>

Both commands have the same meaning, but they are used in different situations. Aborting a merger, for example, will simply return the branch to its pre-merge state. This may not work in some cases. If your working directory has uncommitted or unstashed changes in it, for example, you will not be able run an abort.

Resetting a merging means that you will revert all the files to their ‘known good’ state. This is a good option to use if Git cannot start the merge. This command will remove any changes that you do not commit.

Checking for Conflicts

Most merge conflicts are easy to identify and resolve. In some cases you may need to dig a little deeper to find out why the conflict occurs and how to resolve it.

Checkouts can provide more context following a git merging.

git checkout –conflict=diff3

This compares the two files to show the conflict.

decoding=”async” loading=”lazy” class=”size-full wp-image-155618″ src=”https://kinsta.com/wp-content/uploads/2023/06/checkout-merge-conflict.png” alt=”A code editor that shows the results of running a git checkout –conflict command. It highlights code areas in red, and uses symbols to indicate where there is a change that prevents the commit from taking place.” width=”1000″ height=”486″ srcset=”https://kinsta.com/wp-content/uploads/2023/06/checkout-merge-conflict.png 1000w, https://kinsta.com/wp-content/uploads/2023/06/checkout-merge-conflict-300×146.png 300w, https://kinsta.com/wp-content/uploads/2023/06/checkout-merge-conflict-768×373.png 768w” sizes=”(max-width: 1000px) 100vw, 1000px”>

Checking for a conflict in a project file.

Technically, you will be able to check out the file again and replace any conflict markers. This might be repeated several times during a resolution. If you pass the diff3 arguments, you will get the base version as well as the alternatives in both ‘ours and theirs’ versions.

You don’t need to specify the merge argument style unless you want to change it from the default.

Negative Space Ignored

The use of negative space is often discussed. Different programming languages use different spacing and individual developers may use different formatting.

We won’t get involved in the tabs versus spaces debate. If you encounter situations where the formatting of a file or coding style changes, this Git merge problem could occur.

When you look at the conflict, there will be some lines that have been removed and others added.

decoding=”async” loading=”lazy” class=”size-full wp-image-155627″ src=”https://kinsta.com/wp-content/uploads/2023/06/negative-space-conflict.png” alt=”A code editor showing the differences between two files with merge conflicts. The red highlights are used to highlight the differences in each area. width=”1000″ height=”692″ srcset=”https://kinsta.com/wp-content/uploads/2023/06/negative-space-conflict.png 1000w, https://kinsta.com/wp-content/uploads/2023/06/negative-space-conflict-300×208.png 300w, https://kinsta.com/wp-content/uploads/2023/06/negative-space-conflict-768×531.png 768w” sizes=”(max-width: 1000px) 100vw, 1000px”>

The file that shows the differences between conflicting files in an editor.

Git interprets this as a change because it looks at the lines and considers them to be changes.

You can also add arguments to git merge that will ignore negative spaces in files.

git merge -Xignore-all-space git merge -Xignore-space-change>

These two arguments may seem similar but they are different. Git will ignore all negative spaces if you tell it to. 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. It will therefore ignore single spaces at line ends.

You can also use the –no commit command to double-check that you are counting negative space correctly.

Merge logs

Logging is essential for any software that transmits data. You can use Git’s log to get more information on a merging conflict. This information can be accessed using git log.

decoding=”async” loading=”lazy” class=”size-full wp-image-155621″ src=”https://kinsta.com/wp-content/uploads/2023/06/git-log-file.png” alt=”A Terminal window showing the Git log for a repository. The two commits have yellow titles, as well as details about the author, date and commit message. width=”1000″ height=”537″ srcset=”https://kinsta.com/wp-content/uploads/2023/06/git-log-file.png 1000w, https://kinsta.com/wp-content/uploads/2023/06/git-log-file-300×161.png 300w, https://kinsta.com/wp-content/uploads/2023/06/git-log-file-768×412.png 768w” sizes=”(max-width: 1000px) 100vw, 1000px”>

Run Git and view the Git log.

This is essentially a text dump for all actions within a repository. You can refine the view to only show the commits that you want.

git log –oneline –left-right

It uses a “Triple Dot” to show a list of all commits in two branches when merging. This will filter out all the commits that both branches have in common, leaving a list of commits for further investigation.

You can also use git-log –oneline –leftright –merge to show only commits on either side of the merge that “touch” a conflicting document. You can use the -p option to see all of the changes made for a particular ‘diff’. However, this only applies to non-merge-commits. This can be fixed, and we’ll cover it next.

Using the Combined Diff format to investigate a Git Merge conflict

The git log can be used to further investigate merge conflicts. Git merges code in most cases and stages everything that is successful. You will only have conflicting lines. To see these, use the git diff command.

decoding=”async” loading=”lazy” class=”size-full wp-image-155620″ src=”https://kinsta.com/wp-content/uploads/2023/06/git-diff.png” alt=”A Terminal window that shows the output of a git diff command. It displays the details in red and green text along with the differences between the file names within the repository. width=”1000″ height=”714″ srcset=”https://kinsta.com/wp-content/uploads/2023/06/git-diff.png 1000w, https://kinsta.com/wp-content/uploads/2023/06/git-diff-300×214.png 300w, https://kinsta.com/wp-content/uploads/2023/06/git-diff-768×548.png 768w” sizes=”(max-width: 1000px) 100vw, 1000px”>

Run a git-diff command from the Terminal.

This format adds an extra two columns. The first column tells you whether a line differs between your branch (‘ours,’) and the working version; the second provides the same information about the ‘theirs branch’.

A plus sign indicates that a line has been added to the working copy, but not on the side where the merge is taking place. And a minus symbol denotes the removal of the line.

You can see the combined diff format in Git’s Log using two commands:

git show git cc –p>

First, you can use the command -h to view the history of a merge commit. The second command makes use of the -p option to display changes made to a non merge commit in the format of the combined diff.

How To Undo a Git Merge

You can make mistakes and merges can be done that you want to undo. You can sometimes amend the latest commit by using git –amend. You can edit the message of the most recent commit using the editor.

You can often reverse commits, but it is difficult to do so when there are more complex merge conflicts.

There are many steps to take:

Once you know the branches and commits that you require, there are Git commands to perform the desired action.

Let’s start by looking at the review process. We can then show you how to quickly undo a Git merging, and look at more advanced commands.

Review Commits

If you’re looking for the commit message and revision IDs associated with the current branch, the git log command –oneline is a great option.

decoding=”async” loading=”lazy” class=”size-full wp-image-155622″ src=”https://kinsta.com/wp-content/uploads/2023/06/git-log-oneline.png” alt=”A portion of a Terminal window that shows the output for a one line Git diff command. It displays the minimum amount of information: the commit hash, the branches and the message for each branch before it shows the Terminal prompt.” width=”1000″ height=”356″ srcset=”https://kinsta.com/wp-content/uploads/2023/06/git-log-oneline.png 1000w, https://kinsta.com/wp-content/uploads/2023/06/git-log-oneline-300×107.png 300w, https://kinsta.com/wp-content/uploads/2023/06/git-log-oneline-768×273.png 768w” sizes=”(max-width: 1000px) 100vw, 1000px”>

Run a git diff one-line command in the Terminal.

The gitlog –branches=* will display the same information, but for all branches. You can still use reference IDs to create a detached HEAD state by using git and a checkout. You won’t be working on any branch technically, and when you switch to an existing branch, the changes are ‘orphaned’.

You can therefore use the checkout as a sandbox that is risk-free. If you wish to keep the changes you have made, checkout the branch, and then give it a different name with git checkout. This is an easy way to undo the Git merge. However, there are other more advanced ways to accomplish this.

Using git reset

Most of your merge conflict could occur on a local repository. You can use git reset in these situations. This command also has many parameters and arguments. This is how you would use the command:

git reset –hard

This first part – git-reset-hard– is broken down into three steps.

The hard reset changes the index (i.e. The next proposed commit snapshot looks like the reference branch.

This command will remove all later commits from the commit history and restore it to the ID you specified. This is a good way to undo the merge of Git, but it’s not suitable in all cases.

You will get an error when you attempt to push a reset commit from a local repo to a remote repository that contains this commit. You can also use another command in this situation.

Using git revert

There are important differences between git reset, git revert and other similar commands. In the examples given so far, undoing involves moving reference pointers to a particular commit. This is similar to shuffling playing cards in order to create a different order.

This is why you can use git revert to resolve remote repo merging conflicts.

Use git revert if you want to undo the Git merge. You must always specify a commit number, otherwise the command will not run. You can also add HEAD as a parameter to the command in order to go back to the most recent commit.

You can also give Git more information about what you’re trying to achieve:

git revert 1

The new commit has two “parents” when you merge. One is the reference that you specified, and the second is the tip branch of the branch you wish to merge. Git will keep the first child, in this case. The specified reference is the mainline.

The default option to git revert -e is –edit. The editor will be opened to allow you to edit the commit message prior to reverting. You can also pass –noedit to prevent the editor from opening.

You can also use -n, or –no commit. This instructs git to not create a commit but to ‘inverse’ and add the changes to the staging index.

What is the Difference Between Merging and Rebasing in Git?

You can use git-rebase instead of the git-merge command. It is a similar way to merge changes in one directory.

It is the default option when using git merge. It merges snapshots of two branches into a single commit. There won’t even be a new branch.

Use this command by checkouting to the branch where you want to rebase. You can then use the command:

git rebase –i

In many situations, the main branch will be your reference. The -i switch starts interactive rebasing, which allows you to change the commits while they are being moved. This is a great way to clean up your commit history.

The command displays a list with potential commits that can be moved into the editor. You can completely change the look of the commit history. If you switch the pick command from fixup to merge, you can merge commits. Git will rebase your code once you have saved the changes.

You use Git merge to resolve many conflicts. Rebasing also has many benefits. Rebasing, for example, can be more efficient than merging because you can combine your commit history in one.

Rebasing is still a tricky process, and you need to be extra careful, because the possibility of errors is high. You shouldn’t even use this technique for public branches as it will only affect the repo. You’d have to merge multiple commits in order to fix the issues that resulted.

The Tools that Help You Manage Git Merges Better

You might need a little help with the complexity of Git merge conflict. You can use a variety of tools to merge successfully. If you are using Intellij IDEA you already have one built in:

decoding=”async” loading=”lazy” class=”size-full wp-image-155624″ src=”https://kinsta.com/wp-content/uploads/2023/06/intellij-branches.png” alt=”The bottom corner of the Intellij IDEA code editor, showing the Git widget panel. The context menu for right-clicking is displayed, and the Checkout option is highlighted to allow you to review branch modifications.” width=”1000″ height=”378″ srcset=”https://kinsta.com/wp-content/uploads/2023/06/intellij-branches.png 1000w, https://kinsta.com/wp-content/uploads/2023/06/intellij-branches-300×113.png 300w, https://kinsta.com/wp-content/uploads/2023/06/intellij-branches-768×290.png 768w” sizes=”(max-width: 1000px) 100vw, 1000px”>

Looking at a specific branch in Intellij IDEA.

VSCode includes the same functionality in its user interface. Microsoft’s Git integration is still available to older Atom users, and they can connect directly to GitHub with no additional extensions or add-ons.

Command Palette gives you more options. It’s the same in editors like Onivim2, which are built on VSCode open-source framework.

decoding=”async” loading=”lazy” class=”size-full wp-image-155628″ src=”https://kinsta.com/wp-content/uploads/2023/06/onivim-git-merge.png” alt=”A portion of the Onivim2 screen showing the Command Palette and the Git: Merge Branch command.” width=”1000″ height=”396″ srcset=”https://kinsta.com/wp-content/uploads/2023/06/onivim-git-merge.png 1000w, https://kinsta.com/wp-content/uploads/2023/06/onivim-git-merge-300×119.png 300w, https://kinsta.com/wp-content/uploads/2023/06/onivim-git-merge-768×304.png 768w” sizes=”(max-width: 1000px) 100vw, 1000px”>

Onivim2 Command Palette: Accessing Git: Merge Branch Command

As with the other tools in this list, you do not need to use the command line for merging. You can select the source and the target branches from a dropdown menu. The editor will then merge the files. You don’t need to be completely hands-off. You can review the changes and then commit the changes you require.

Sublime Text is one editor that provides a separate GUI for working with Git. Sublime Merge is a great tool to add to your workflow if you are using this editor.

decoding=”async” loading=”lazy” class=”size-full wp-image-155629″ src=”https://kinsta.com/wp-content/uploads/2023/06/sublime-merge.png” alt=”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.” width=”1000″ height=”498″ srcset=”https://kinsta.com/wp-content/uploads/2023/06/sublime-merge.png 1000w, https://kinsta.com/wp-content/uploads/2023/06/sublime-merge-300×149.png 300w, https://kinsta.com/wp-content/uploads/2023/06/sublime-merge-768×382.png 768w, https://kinsta.com/wp-content/uploads/2023/06/sublime-merge-360×180.png 360w” sizes=”(max-width: 1000px) 100vw, 1000px”>

The Sublime Merge App.

It doesn’t matter which code editor you use, most will allow you to work with Git using the command-line. Even Vim and Neovim can be used with Tim Pope’s Git Fugitive plug-in, which is a fantastic and easy to use tool.

There are some dedicated third-party tools that specialize in this task.

Git Merge apps Dedicated

For instance, Mergify is an enterprise-level way to merge code that integrates into your continuous integration/continuous delivery (CI/CD) pipeline and workflow:

decoding=”async” loading=”lazy” class=”size-full wp-image-155626″ src=”https://kinsta.com/wp-content/uploads/2023/06/mergify-app.png” alt=”A section of the Mergify website showing a number of white-outlined graphics on a black background. There are lists for Git branches and code editors. width=”1000″ height=”640″ srcset=”https://kinsta.com/wp-content/uploads/2023/06/mergify-app.png 1000w, https://kinsta.com/wp-content/uploads/2023/06/mergify-app-300×192.png 300w, https://kinsta.com/wp-content/uploads/2023/06/mergify-app-768×492.png 768w” sizes=”(max-width: 1000px) 100vw, 1000px”>

Mergify is a website that you can visit.

You can automate your pull request updates before merging, sort them by priority and even batch them. Meld is a good open-source solution:

decoding=”async” loading=”lazy” class=”size-full wp-image-155625″ src=”https://kinsta.com/wp-content/uploads/2023/06/meld-app.png” alt=”The Meld app interface showing side-by-side code, complete with highlighting in blue and green to denote changes between each file.” width=”1000″ height=”651″ srcset=”https://kinsta.com/wp-content/uploads/2023/06/meld-app.png 1000w, https://kinsta.com/wp-content/uploads/2023/06/meld-app-300×195.png 300w, https://kinsta.com/wp-content/uploads/2023/06/meld-app-768×500.png 768w” sizes=”(max-width: 1000px) 100vw, 1000px”>

The Meld App interface.

The stable release runs on Windows and Linux under GPL. You can use this to edit merges and compare branches. Even better, you can perform two- or even three-way comparisons. You also get support for Subversion and other version control systems.

You can read more about it here:

Git is a powerful tool for managing code changes and collaborating with others. Conflicts can arise if several developers are working on the same code. There are many ways you can resolve conflicts using Git merge strategies. You can use advanced tactics to find more complex Git merg strategies.

You can do this by ignoring the negative space, or searching through search logs. You don’t have to always use the command-line. You can use many apps and code editors will have a built-in user interface.

If you’d like to secure high-qualityapplication hosting, we’ve got you covered. Cloud-based app-hosting services will have your full-stack application ready in no time.

Which of these Git merging strategies will you get out of a bind? Tell us in the comment section below!

This post explains how to perform complex Git merge tasks.

Did you miss our previous article…
https://www.affiliatemarketingbuzz.com/memcached-vs-redis-choose-your-memory-cache/

The post How to Perform complex Git merging tasks appeared first on Affiliate Marketing Buzz.



from
https://www.affiliatemarketingbuzz.com/how-to-perform-complex-git-merging-tasks/?utm_source=rss&utm_medium=rss&utm_campaign=how-to-perform-complex-git-merging-tasks

No comments:

Post a Comment

Customer Service Metrics – 2023 Guide and Free Template

Customer Service Metrics – 2023 Guide and Free Template https://www.affiliatemarketingbuzz.com/customer-service-metrics-2023-guide-and-fre...