Programming and IT

git merge

Merging brings work from one branch into another. git merge takes the branch you name and joins its history with the current one — sometimes by just moving a pointer, sometimes by creating a separate commit, and sometimes by stopping and asking for help.

Updated
In this article

What merges into what#

A merge always goes one way: from the branch you name into the branch you are on. So first you switch to the receiving branch and only then name the source:

git switch main
git merge feature/export

The source branch does not go anywhere afterwards and stays on its commit — you either delete it as finished or keep working in it. How the pointers themselves work is explained in the article on git branch.

Fast-forward versus a real merge#

If main has not received a single commit since the branch split off, Git does not invent anything — it just moves the pointer forward:

Updating 4f1c2ab..9d31c07
Fast-forward
 export.py | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)
 create mode 100644 export.py

If both branches have moved on, a commit with two parents appears:

Merge made by the 'ort' strategy.
 export.py | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

ort is the name of the merge algorithm in recent versions of Git; older ones said recursive here. It does not change what the output means.

Option What it changes
--no-ff always create a merge commit, even when a fast-forward would do
--ff-only the opposite: merge only by fast-forward, otherwise refuse
--squash combine all the branch's commits into one set of changes, no merge commit
--no-commit stop before recording, so you can inspect the result
-m "text" your own message for the merge commit
--abort drop an unfinished merge and put everything back

Teams like --no-ff where it matters to see in history that a group of commits is one task. --squash is handy when a branch has twenty tiny commits like "typo" that the shared history does not need: afterwards the changes sit in the index and you commit them yourself with git commit. If you would rather replay commits than join histories, compare this with git rebase.

A conflict: what it is and what to do#

A conflict happens when the same piece of a file was changed differently in both branches. Automation cannot guess here:

Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Automatic merge failed; fix conflicts and then commit the result.

Git does not roll back; it leaves the work halfway: what merged cleanly is already in the index, and the disputed part is marked right in the file.

<<<<<<< HEAD
Run: python app.py
=======
Run: python -m app
>>>>>>> feature/export

On top is the version from the current branch, below it the one from the branch being merged. The routine goes like this:

  1. git status — the "Unmerged paths" section lists the disputed files.
  2. Open each one, keep the right text and remove all three marker lines.
  3. git add README.md — this tells Git the file is resolved.
  4. git merge --continue (or git commit) — record the merge commit.

A useful detail: git checkout --ours README.md takes the current branch's version in full, --theirs takes the incoming one. This saves you in conflicts over generated files where there is nothing to mix. The full walkthrough, with the zdiff3 style and common traps, is in how to resolve a merge conflict.

How to undo a merge#

The merge is not finished, the file is full of conflict markers, and you want to start over:

git merge --abort

The branch and the working directory return to the state before the command.

The merge commit is already created but not pushed:

git reset --hard ORIG_HEAD

ORIG_HEAD holds where the branch was before the merge began. --hard erases uncommitted work, so first make sure you have nothing unsaved.

The merge is already on the server and others have seen it — you must not rewrite history, so you undo it with a new commit:

git revert -m 1 8b2d5e9

The number after -m is the parent to treat as the main line; 1 means the branch you merged into. More on pushing and its rejections in the article on git push.

How to look at the result#

git log --oneline --graph -12

The slanted lines on the left show where history split and where it joined again. If the picture is not what you expected, do not worry: until the commits are pushed, any merge can be undone without a trace, and the earlier positions of the branch are listed in git reflog.

Step-by-step plan

  1. Update the receiving branchSwitch to the target branch and pull the latest commits from the server.
  2. See what will come ingit log --oneline main..feature — the list of the source branch's commits.
  3. Run the mergegit merge feature; add --no-ff or --squash if needed.
  4. Resolve conflictsFix the files, remove the markers, git add, git merge --continue.
  5. Check and tidy upRun the tests, then delete the finished branch with git branch -d.

Start learning this in your own space

The plan goes into your repository: tick off stages, keep notes — the change history shows how far you have come.

Start the plan

Check yourself

1.A merge stopped on a conflict. Which command puts everything back as it was before the merge?

2.What does git merge --no-ff do?

3.The conflicted file is edited and the markers are removed. What next?

Sources

Was this helpful?

More articles

Programming and IT git rebase git rebase moves the commits of your branch as if you had started work not from an old state but from the current one. History becomes linear, but the commits are created anew — with new hashes. That leads to the main rule: you can only rebase what nobody else is using. Programming and IT git pull git pull brings other people's commits from a remote repository and immediately merges them into your current branch. It is two operations in a row, and almost every problem with pull comes from the second one — how it joins the two histories. Programming and IT Git branches A Git branch is a movable pointer to a commit, not a copy of your files. That is why creating one costs nothing, and the git branch command is what you use to list, create, rename and delete branches. Programming and IT git checkout Historically `git checkout` does several unrelated things at once: it moves your working copy to another branch, creates a branch and pulls a single file out of a commit. Because it was so overloaded, Git 2.23 added two separate commands — `switch` and `restore`. Here are both sides: the old way and its modern replacement. Programming and IT How to undo a commit The question "how do I undo a commit" actually hides four different ones: fix the last commit, take it back and redo it, erase several, or cancel an old commit in the middle of history. The answer depends above all on one thing — whether anyone besides you has seen that commit. Programming and IT How to resolve a merge conflict A conflict is not a breakage, it is a question. Git merges changes automatically as long as they are in different parts of a file; when two branches edit the same lines, only a person can choose the right version. Your job is to read both versions, build working code out of them and tell Git the question is settled.

More solutions