What is git merge and how to undo it
Tags: git
Published: 2022-12-18 16:41:06

When you want to combine the changes from one branch into another, you can use the git merge command. For example, suppose you have two branches: "main" and "new-feature". You have been working on "new-feature" for a while and now you want to merge the changes you made into "main". To do this, you can use the following steps:

1. Switch to the main branch: `git checkout main`
2. Merge the changes from new-feature into main: `git merge new-feature`

Git will automatically try to merge the changes from "new-feature" into "main". If there are no conflicts, the merge will be completed and you will be able to see the changes you made in "new-feature" in the "main" branch.

If there are conflicts, git will not be able to automatically merge the changes and you will have to resolve the conflicts manually. This means that you will have to edit the conflicting files and decide which changes to keep and which to discard. Once you have resolved the conflicts, you can commit the merged changes to complete the merge.

## Undo git merge -
There are several ways to undo a git merge, depending on what you want to achieve and in most cases first two will be sufficient. Here are some options:

1) `git merge --abort`: This command will abort the merge and restore the state of the repository to before the merge was started. This is the most straightforward way to undo a merge, but **it will only work if the merge has not been completed and the repository is still in a "merging" state i.e., there was a merge conflict and the changes have not been pushed** to a remote repository.

In git, a repository is considered to be in a "merging" state when a merge operation is in progress but has not yet been completed. **This typically occurs when you are using the git merge command to combine changes from one branch into another, and git has detected conflicts that need to be resolved.**

When git is in the process of merging, it creates a special merge commit that represents the combined changes from the two branches. This commit has two parent commits, one for each branch being merged. However, until the merge conflicts are resolved and the merge commit is finalized, the repository remains in a "merging" state.

2) `git reset --hard HEAD~1`: This command will discard the changes from the merge and restore the repository to the state it was in before the merge. It will also remove any commits that were added during the merge. **This option is useful if you want to completely discard the changes from the merge and start over.** 

This command works for both cases whether the changes were pushed or not.

However, it's important to keep in mind that using git reset --hard will permanently discard the changes made in the commits that are being removed. This means that the changes will be lost and cannot be recovered. Therefore, it's generally a good idea to use this command with caution and only if you are sure that you want to permanently discard the changes made in the merge commit.

3) `git revert <commit_hash>`: Alternatively, you can use git revert to undo specific changes from a commit. It will undo the changes made in the specified commit by creating a new commit that reverses the changes. This is a safer option if you are not sure which changes you want to discard, as it preserves the history of the repository.


## Good to know -
If there are no conflicts between the branches, **Git will automatically create a new commit** that merges the changes from the feature branch into the master branch. If there are conflicts, Git will stop the merge and ask you to resolve the conflicts before completing the merge.

You can also use the git merge command with the `--no-commit` flag, which will perform the **merge but not create a new commit.** This can be useful if you want to review the changes before committing them to the repository.

It's important to note that a **merge creates a new commit in the history of the branch you are merging into**. This means that after a merge, the two branches have a common ancestor commit, and any commits on the merged branch are considered to be part of the branch's history.