===== Overview =====
Both basic and advanced merging operations.
===== SYNOPSIS =====
git merge [-n] [--stat] [--no-commit] [--squash]
[--[no-]edit]
[-s ] [-X ] [-S[]]
[--[no-]allow-unrelated-histories]
[--[no-]rerere-autoupdate] [-m ]
[-F ] [...]
git merge --abort
git merge --continue
===== Simple merging =====
==== Basic merge ====
If you have this situation:
A---B---C topic
/
D---E---F---G master
followed by:
$ git checkout master
$ git merge topic
the end result is a new merge commit H:
A---B---C topic
/ \
D---E---F---G---H master
==== Fast-forward merge ====
If you have this:
A---B---C topic
/
D---E master
followed by:
$ git checkout master
$ git merge topic
the default fast-forward merge will produce:
A---B---C topic
/ master
D---E
or, depicted another way:
D---E---A---B---C master
topic
===== Query containedness and mergeness =====
From ''man git-branch'':
With --contains, shows only the branches that contain the named
commit (in other words, the branches whose tip commits are
descendants of the named commit), --no-contains inverts it.
With --merged, only branches merged into the named commit (i.e.
the branches whose tip commits are reachable from the named
commit) will be listed. With --no-merged only branches not
merged into the named commit will be listed. If the
argument is missing it defaults to HEAD (i.e. the tip of the
current branch).
Examples:
$ git branch --merged master
$ git branch --no-merged
$ git branch --contains v4.19
$ git branch --no-contains v4.19
===== Dealing with simple merge conflicts =====
Imagine this change on the ''master'' branch:
$ git show master
commit 4a93eab592cf790838314b3799eb7a4faa213538 (HEAD -> master)
Author: Robert P. J. Day
Date: Fri Mar 1 08:17:50 2019 -0500
Change to third edition
diff --git a/README.asc b/README.asc
index fa40bad..9fefbd5 100644
--- a/README.asc
+++ b/README.asc
@@ -1,4 +1,4 @@
-= Pro Git, Second Edition
+= Pro Git, Third Edition
Welcome to the second edition of the Pro Git book.
$
And imagine this clearly-conflicting change on the branch ''4th'':
$ git show 4th
commit 9e679bc1c27d5d708d571ea1b47564f3a99df944 (4th)
Author: Robert P. J. Day
Date: Fri Mar 1 08:19:35 2019 -0500
Fourth edition
diff --git a/README.asc b/README.asc
index fa40bad..1f0879f 100644
--- a/README.asc
+++ b/README.asc
@@ -1,4 +1,4 @@
-= Pro Git, Second Edition
+= Pro Git, Fourth Edition
Welcome to the second edition of the Pro Git book.
$
Trying to merge will generate a //merge conflict//:
$ git checkout master
$ git merge 4th
Auto-merging README.asc
CONFLICT (content): Merge conflict in README.asc
Automatic merge failed; fix conflicts and then commit the result.
$
''git status'' will tell you that you have a merge conflict;
$ git status
... snip ...
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add ..." to mark resolution)
both modified: README.asc
no changes added to commit (use "git add" and/or "git commit -a")
The merge conflict is identified in the ''README.asc'' file:
$ less README.asc
<<<<<<< HEAD
= Pro Git, Third Edition
=======
= Pro Git, Fourth Edition
>>>>>>> 4th
Welcome to the second edition of the Pro Git book.
... etc etc ...
So edit the file and resolve the conflict any way you want, such as:
$ less README.asc
= Pro Git, Fifth Edition
... snip ...
Stage the resolved file:
$ git add README.asc
You can tell the conflicts are now resolved:
$ git status
On branch master
All conflicts fixed but you are still merging.
(use "git commit" to conclude merge)
Changes to be committed:
modified: README.asc
$
And commit:
$ git commit -m "Bumped merge up to fifth edition"
The final version of ''README.asc'':
= Pro Git, Fifth Edition
Welcome to the second edition of the Pro Git book.
... etc ...
===== Advanced merging =====
==== Fast-forwarding ====
Recall a fast-forward merge:
A---B---C topic
/ master
D---E
You may or may not want that:
--ff
When the merge resolves as a fast-forward, only update the
branch pointer, without creating a merge commit. This is
the default behavior.
--no-ff
Create a merge commit even when the merge resolves as a
fast-forward. This is the default behaviour when merging an
annotated (and possibly signed) tag that is not stored in
its natural place in refs/tags/ hierarchy.
--ff-only
Refuse to merge and exit with a non-zero status unless the
current HEAD is already up to date or the merge can be
resolved as a fast-forward.
==== Committing ====
--commit, --no-commit
Perform the merge and commit the result. This option can be
used to override --no-commit.
With --no-commit perform the merge but pretend the merge
failed and do not autocommit, to give the user a chance to
inspect and further tweak the merge result before
committing.
==== Editing ====
--edit, -e, --no-edit
Invoke an editor before committing successful mechanical
merge to further edit the auto-generated merge message, so
that the user can explain and justify the merge. The
--no-edit option can be used to accept the auto-generated
message (this is generally discouraged). The --edit (or -e)
option is still useful if you are giving a draft message
with the -m option from the command line and want to edit
it in the editor.
==== Squashing ====
--squash, --no-squash
Produce the working tree and index state as if a real merge
happened (except for the merge information), but do not
actually make a commit, move the HEAD, or record
$GIT_DIR/MERGE_HEAD (to cause the next git commit command
to create a merge commit). This allows you to create a
single commit on top of the current branch whose effect is
the same as merging another branch (or more in case of an
octopus).
With --no-squash perform the merge and commit the result.
This option can be used to override --squash.
As in:
$ git checkout master
$ git merge --squash
$ git commit
===== Setting merge options =====
==== Per-branch merge options ====
From ''man git-config'', you can set (either locally or globally) //per-branch// merge options:
branch..mergeOptions
Sets default options for merging into branch . The
syntax and supported options are the same as those of git-
merge(1), but option values containing whitespace
characters are currently not supported.
For example, if you wanted to prevent any fast-forward merges to any ''master'' branch across all of your repositories, you could:
$ git config --global branch.master.mergeOptions "--no-ff"
==== Global merge.ff option ====
For merging, there is at least one repo-wide merge option you can set (see ''man git-merge''):
merge.ff
By default, Git does not create an extra merge commit when
merging a commit that is a descendant of the current
commit. Instead, the tip of the current branch is
fast-forwarded. When set to false, this variable tells Git
to create an extra merge commit in such a case (equivalent
to giving the --no-ff option from the command line). When
set to only, only such fast-forward merges are allowed
(equivalent to giving the --ff-only option from the command
line).
So for widespread fast-forward merge configuration:
$ git config --global merge.ff "true"
This setting is superseded by any per-branch fast-forward merge setting.
===== Merge strategies =====
==== ours ====
Technically record a merge while totally ignoring its content -- for record-keeping.
Example:
$ git checkout master
$ git merge --strategy=ours
How to make ''master'' look exactly like ''develop'':
$ git checkout topic
$ git merge -s ours master
$ git checkout master
$ git merge --ff-only topic
To do this for an arbitrary commit, create a temporary branch:
$ git checkout -b tempbranch
$ git merge -s ours master
$ git checkout master
$ git merge --ff-only tempbranch