LinuxCommandLibrary

git-merge

Combine changes from one branch into another

TLDR

Merge a branch into your current branch

$ git merge [branch_name]
copy

Edit the merge message
$ git merge [[-e|--edit]] [branch_name]
copy

Merge a branch and create a merge commit
$ git merge --no-ff [branch_name]
copy

Abort a merge in case of conflicts
$ git merge --abort
copy

Merge using a specific strategy
$ git merge [[-s|--strategy]] [strategy] [[-X|--strategy-option]] [strategy_option] [branch_name]
copy

SYNOPSIS

git merge [] ...
git merge []
git merge --abort
git merge --continue

PARAMETERS

...
    The names of commits, typically branch names, to be merged into the current branch.

-n, --no-summary
    Suppress showing a short summary of how the branches are merged.

--stat
    Show a diffstat at the end of the merge.

--no-commit
    Perform the merge, but do not create a merge commit, allowing the user to inspect the changes and make further adjustments.

--no-ff
    Create a merge commit even when a fast-forward merge is possible, preserving the branch's history.

--ff-only
    Only perform the merge if it can be resolved as a fast-forward. If not, refuse to merge.

--squash
    Produce a single commit result from the changes of the merged branch, without recording the merge itself. The history of the merged branch is not integrated.

-s
    Use the given merge strategy. Common strategies include recursive (default), ours, and octopus.

-X
    Pass strategy-specific options. E.g., -Xours to prefer 'ours' changes on conflicts for recursive strategy.

-m
    Specify the commit message for the merge commit.

--abort
    Abort the current merge in progress, restoring the branch to its state before the merge attempt.

--continue
    After resolving conflicts during a merge, use this to commit the changes and complete the merge operation.

--allow-unrelated-histories
    Allows merging branches that do not share a common ancestor. Useful when merging two independent repositories.

--autostash
    Automatically stash and unstash local modifications before and after the merge.

DESCRIPTION

The git-merge command is a fundamental Git operation used to combine divergent lines of development. When you merge, Git takes two (or more) separate histories and combines them into a single, new history. This is typically done by creating a new "merge commit" that has multiple parent commits—one for each branch being merged.

Git handles merges in two primary ways: fast-forward merges and three-way merges. A fast-forward merge occurs when the current branch's tip is an ancestor of the target branch's tip; Git simply moves the current branch pointer forward to the target branch's tip without creating a new commit. A three-way merge, on the other hand, is required when the histories have diverged. Git identifies a common ancestor, then combines changes from both branches relative to that ancestor, creating a new merge commit.

If Git cannot automatically resolve differences, a merge conflict occurs, requiring manual intervention to resolve the conflicting changes before the merge can be completed.

CAVEATS

Merge operations can introduce merge conflicts when the same lines of code have been changed differently in the branches being merged. These conflicts must be resolved manually before the merge can be completed. While git-merge aims to preserve history, using options like --squash will rewrite history by discarding the individual commits from the merged branch and creating a single new commit, which can complicate debugging or code archaeology. Always be mindful of the implications of fast-forward vs. non-fast-forward merges on your repository's history graph. Merging branches with unrelated histories requires the --allow-unrelated-histories option, which should be used with caution as it bypasses a safety check.

MERGE STRATEGIES

Git offers several merge strategies to handle different merging scenarios. The recursive strategy is the default and most commonly used, handling complex three-way merges with options to resolve conflicts (e.g., preferring 'ours' or 'theirs'). The ours strategy resolves any conflicting changes by preferring the changes from the current branch. The octopus strategy is used for merging more than two heads simultaneously. The subtree strategy is useful for managing a subdirectory as a separate repository.

FAST-FORWARD VS. NON-FAST-FORWARD MERGES

A fast-forward merge occurs when the current branch's tip is an ancestor of the branch being merged. Git simply moves the current branch pointer forward, effectively 'fast-forwarding' it. This doesn't create a new merge commit. A non-fast-forward merge (often enforced with --no-ff) creates a new merge commit even if a fast-forward was possible. This preserves the history of the merged branch and clearly shows where a feature branch was integrated, which can be useful for understanding project history.

RESOLVING MERGE CONFLICTS

When git-merge encounters conflicting changes, it pauses the merge process and marks the files with conflict markers (e.g., <<<<<<<, =======, >>>>>>>). You must manually edit these files to resolve the conflicts. After resolving, you use git add <file> to stage the changes, and then git merge --continue to complete the merge. git status is invaluable during conflict resolution to see which files are conflicted.

HISTORY

git-merge is a core command that has been part of Git since its inception in 2005. It's fundamental to Git's distributed nature, enabling developers to integrate work from different branches and contributors. Over time, new merge strategies like recursive (which became the default) were added to handle more complex scenarios, and options like --allow-unrelated-histories (introduced in Git 2.9) were added to address common usage patterns and safety concerns. Its evolution reflects the ongoing refinement of Git's ability to manage complex project histories efficiently.

SEE ALSO

Copied to clipboard