官方帮助文档
$ git help merge
GIT-MERGE( 1) Git Manual GIT-MERGE( 1)
NAME
git-merge - Join two or more development histories together
SYNOPSIS
git merge [ -n] [ --stat] [ --no-commit] [ --squash] [ --[ no-] edit]
[ --no-verify] [ -s < strategy> ] [ -X < strategy-option> ] [ -S[ < keyid> ] ]
[ --[ no-] allow-unrelated-histories]
[ --[ no-] rerere-autoupdate] [ -m < msg> ] [ -F < file> ] [ < commit> .. .]
git merge ( --continue | --abort | --quit)
DESCRIPTION
Incorporates changes from the named commits ( since the time their histories
diverged from the current branch) into the current branch. This command is
used by git pull to incorporate changes from another repository and can be
used by hand to merge changes from one branch into another.
Assume the following history exists and the current branch is "master" :
A---B---C topic
/
D---E---F---G master
Then "git merge topic" will replay the changes made on the topic branch since
it diverged from master ( i.e., E) until its current commit ( C) on top of
master, and record the result in a new commit along with the names of the two
parent commits and a log message from the user describing the changes.
A---B---C topic
/ \
D---E---F---G---H master
The second syntax ( "git merge --abort" ) can only be run after the merge has
resulted in conflicts. git merge --abort will abort the merge process and try
to reconstruct the pre-merge state. However, if there were uncommitted
changes when the merge started ( and especially if those changes were further
modified after the merge was started) , git merge --abort will in some cases
be unable to reconstruct the original ( pre-merge) changes. Therefore:
Warning: Running git merge with non-trivial uncommitted changes is
discouraged: while possible, it may leave you in a state that is hard to back
out of in the case of a conflict.
The third syntax ( "git merge --continue" ) can only be run after the merge has
resulted in conflicts.
OPTIONS
--commit, --no-commit
Git Merge —— Fast Forward ( 快进到某个分支)
master不变,新创建一个分支bugfix,在bugfix分支上修改代码提交commit,完后在master分支上,把master分支上指向bugfix上最新的commit对象,
$ cat .git/HEAD
ref: refs/heads/master
$ git log
commit ef1ab1732d63429bee8a8e8d50adf315eca3a74b ( HEAD -> master)
.. .
$ git checkout -b fix-xxx
切换到一个新分支 'fix-xxx'
$ git branch
* fix-xxx
master
$ git log
commit ef1ab1732d63429bee8a8e8d50adf315eca3a74b ( HEAD -> fix-xxx, master)
$ vim hello.txt
$ git add hello.txt
$ git commit -m 'fix'
[ fix-xxx 351ed28] fix
1 file changed, 1 insertion( +) , 1 deletion( -)
$ git log
commit 351ed2832ff8d44d3a9bcd459d2d3c750606637a ( HEAD -> fix-xxx)
Author: xxx < xxx.com>
Date: xxx
fix
commit ef1ab1732d63429bee8a8e8d50adf315eca3a74b ( master)
.. .
$ git checkout master
切换到分支 'master'
$ git log
commit ef1ab1732d63429bee8a8e8d50adf315eca3a74b ( HEAD -> master)
.. .
$ git merge fix-xxx
Updating ef1ab17.. 351ed28
Fast-forward
hello.txt | 2 +-
1 file changed, 1 insertion( +) , 1 deletion( -)
$ git log
commit 351ed2832ff8d44d3a9bcd459d2d3c750606637a ( HEAD -> master, fix-xxx)
Author: xxx < xxx.com>
Date: xxx
fix
commit ef1ab1732d63429bee8a8e8d50adf315eca3a74b ( HEAD -> master)
.. .
$ tree .git
.git
├── COMMIT_EDITMSG
├── HEAD
├── ORIG_HEAD
├── config
├── description
├── hooks
├── index
├── info
│ ├── exclude
│ └── refs
├── logs
│ ├── HEAD
│ └── refs
│ └── heads
│ ├── fix-xxx
│ └── master
├── objects
│ ├── 35
│ │ └── 1ed2832ff8d44d3a9bcd459d2d3c750606637a
│ ├── 56
│ │ └── 00391ce473902576cb284ecb48410ea7c9f308
│ ├── 91
│ │ └── b84d9a6b5b007824972f6f8478e2a2eb662b54
│ ├── info
│ │ ├── commit-graph
│ │ └── packs
│ └── pack
│ ├── pack-0c8c5e08719b5d74e9c03714a71555a9bc1c9632.idx
│ └── pack-0c8c5e08719b5d74e9c03714a71555a9bc1c9632.pack
├── packed-refs
└── refs
├── heads
│ ├── fix-xxx
│ └── master
└── tags
$ cat .git/HEAD
ref: refs/heads/master
$ cat .git/ORIG_HEAD
ef1ab1732d63429bee8a8e8d50adf315eca3a74b
$ cat .git/refs/heads/master
351ed2832ff8d44d3a9bcd459d2d3c750606637a
我们可以在这时进行回滚操作
Git认为Fast-forward 这种场景很危险,我们需要有回滚操作,也就是撤回当上一个版本
$ git reset ORIG_HEA
重置后取消暂存的变更:
M hello.txt
$ git log
commit ef1ab1732d63429bee8a8e8d50adf315eca3a74b ( HEAD -> master)
$ git status
位于分支 master
尚未暂存以备提交的变更:
(使用 "git add <文件>..." 更新要提交的内容)
(使用 "git restore <文件>..." 丢弃工作区的改动)
修改: hello.txt
修改尚未加入提交(使用 "git add" 和/或 "git commit -a" )
Git Merge —— 3 Way merge
在我们merge之前,已经有人merge过其他分支
修改一样的文件,产生冲突
git checkout -b fix-xxx2
切换到一个新分支 'fix-xxx2'
$ vim hello.txt
$ git add hello.txt
$ git commit -m 'fix 2'
[ fix-xxx2 79c4f6a] fix 2
1 file changed, 1 insertion( +)
$ git log
commit 79c4f6aede40a7042add2f89fcd80d260041c0a5 ( HEAD -> fix-xxx2)
Author: hh < hh@123.com>
Date: Sun Mar 28 14:25:38 2021 +0800
fix 2
$ tree .git/objects
.git/objects
├── 17
│ └── 8724d997ef9fc1141e797171d682553136edfc
├── 41
│ └── 1b486eb6afe280fb7e26ed1b00b39c11af4462
├── 61
│ └── 5640b3bdc533cc5180a00ebfe8675115aa11ac
├── 79
│ └── c4f6aede40a7042add2f89fcd80d260041c0a5
├── b4
│ └── bfc685e634816f6bad0b51bac882173bc8e54a
├── e4
│ └── 582fa0fc21613231e5bb8bf284a7db9df0937e
├── info
│ ├── commit-graph
│ └── packs
└── pack
├── pack-3c257c1a1c5cddbd7adcbbcd0b2eae95178d8e6b.idx
└── pack-3c257c1a1c5cddbd7adcbbcd0b2eae95178d8e6b.pack
8 directories, 10 files
$ git checkout master
切换到分支 'master'
$ git merge fix-xxx2
更新 ef1ab17.. 79c4f6a
Fast-forward
hello.txt | 1 +
1 file changed, 1 insertion( +)
$ git merge fix-xxx
自动合并 hello.txt
冲突(内容):合并冲突于 hello.txt
自动合并失败,修正冲突然后提交修正的结果。
$ vim hello.txt
hello git
<<< <<< < HEAD
fix bug
fix bug
== == == =
fix
>> >> >> > fix-xxx
$ git status
位于分支 master
您有尚未合并的路径。
(解决冲突并运行 "git commit" )
(使用 "git merge --abort" 终止合并)
未合并的路径:
(使用 "git add <文件>..." 标记解决方案)
双方修改: hello.txt
修改尚未加入提交(使用 "git add" 和/或 "git commit -a" )
$ git add hello.txt
$ git status
位于分支 master
所有冲突已解决但您仍处于合并中。
(使用 "git commit" 结束合并)
要提交的变更:
修改: hello.txt
$ git commit -m 'fix merge bug-fix-xxx'
[ master c21d1eb] fix merge bug-fix-xxx
$ git log
commit c21d1eb5cba29552302382495fb9dbf9bae66f47 ( HEAD -> master)
Merge: 79c4f6a 351ed28
Author: XXX
Date: XXX
fix merge bug-fix-xxx
commit 79c4f6aede40a7042add2f89fcd80d260041c0a5 ( fix-xxx2)
Author: XXX
Date: XXX
fix 2
commit 351ed2832ff8d44d3a9bcd459d2d3c750606637a ( fix-xxx)
Author: XXX
Date: XXX
fix
commit c21d1eb5cba29552302382495fb9dbf9bae66f47
.. .
$ tree .git/objects
.git/objects
├── 17
│ └── 8724d997ef9fc1141e797171d682553136edfc
├── 41
│ └── 1b486eb6afe280fb7e26ed1b00b39c11af4462
├── 61
│ └── 5640b3bdc533cc5180a00ebfe8675115aa11ac
├── 79
│ └── c4f6aede40a7042add2f89fcd80d260041c0a5
├── b4
│ └── bfc685e634816f6bad0b51bac882173bc8e54a
├── c2
│ ├── 1d1eb5cba29552302382495fb9dbf9bae66f47
│ └── 7e40a839d857c095dd5e3bda0aaf2a61224cb5
├── c7
│ └── 037c0fda18887223fc27048d5491bd4627471a
├── e4
│ └── 582fa0fc21613231e5bb8bf284a7db9df0937e
├── f9
│ └── 9c1c17a0c67bd6df61ed7fae3e7842b8723105
├── info
│ ├── commit-graph
│ └── packs
└── pack
├── pack-3c257c1a1c5cddbd7adcbbcd0b2eae95178d8e6b.idx
└── pack-3c257c1a1c5cddbd7adcbbcd0b2eae95178d8e6b.pack
11 directories, 14 files
$ git cat-file -t c21d1e
commit
git cat-file -p c21d1e
tree c27e40a839d857c095dd5e3bda0aaf2a61224cb5
parent 79c4f6aede40a7042add2f89fcd80d260041c0a5
parent 351ed2832ff8d44d3a9bcd459d2d3c750606637a
author hh < hh@123.com> 1616913093 +0800
committer hh < hh@123.com> 1616913093 +0800
fix merge bug-fix-xxx
$ git cat-file -t c27e40
tree
$ git cat-file -p c27e40
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 empty_file.txt
040000 tree c2ed92794640553084dfab1d35c0f468342e02a6 folder1
100644 blob c7037c0fda18887223fc27048d5491bd4627471a hello.txt
100644 blob 0f7b21a50d13eb924a712a1cb763dca8ef69f6f3 hello_copy.txt
修改不一样的文件,不会产生冲突
git checkout fix-xxx
切换到分支 'fix-xxx'
$ vim fix-xxx.txt
$ git add fix-xxx.txt
$ git commit -m 'add fix-xxx'
[ fix-xxx 8814570] add fix-xxx
1 file changed, 1 insertion( +)
create mode 100644 fix-xxx.txt
$ git checkout master
切换到分支 'master'
$ git checkout fix-xxx2
切换到分支 'fix-xxx2'
$ vim fix-xxx2.txt
$ git add fix-xxx2.txt
$ git status
位于分支 fix-xxx2
要提交的变更:
(使用 "git restore --staged <文件>..." 以取消暂存)
新文件: fix-xxx2.txt
$ git commit -m 'add fix-xxx2'
[ fix-xxx2 6048e4f] add fix-xxx2
1 file changed, 1 insertion( +)
create mode 100644 fix-xxx2.txt
$ git checkout master
切换到分支 'master'
$ git merge fix-xxx2
Merge made by the 'recursive' strategy.
fix-xxx2.txt | 1 +
1 file changed, 1 insertion( +)
create mode 100644 fix-xxx2.txt
$ git merge fix-xxx
Merge made by the 'recursive' strategy.
fix-xxx.txt | 1 +
1 file changed, 1 insertion( +)
create mode 100644 fix-xxx.txt
$ git log
commit daeef85f655ca2a2f240839edfbbc858b32bce0b ( HEAD -> master)
Merge: ac68fc7 8814570
Author: hh < hh@123.com>
Date: Sun Mar 28 14:49:00 2021 +0800
Merge branch 'fix-xxx' into master
fix bug fix xxx
commit ac68fc7a6f26ec18585249989a5023a940bc9974
Merge: c21d1eb 6048e4f
Author: hh < hh@123.com>
Date: Sun Mar 28 14:48:42 2021 +0800
Merge branch 'fix-xxx2' into master
commit 6048e4fc794e7df0192939309d8be0d47ca3f71a ( fix-xxx2)
Author: hh < hh@123.com>
Date: Sun Mar 28 14:48:13 2021 +0800
add fix-xxx2
commit 88145707b4619e8ada9308178bec3cd54b18f290 ( fix-xxx)
Author: hh < hh@123.com>
Date: Sun Mar 28 14:46:46 2021 +0800
add fix-xxx
commit c21d1eb5cba29552302382495fb9dbf9bae66f47
Merge: 79c4f6a 351ed28
Author: hh < hh@123.com>
Date: Sun Mar 28 14:31:33 2021 +0800
fix merge bug-fix-xxx
tree .git/objects
.git/objects
├── 17
│ └── 8724d997ef9fc1141e797171d682553136edfc
├── 38
│ └── da773d597dd7a0c0f829ebc9435913347bb4ba
├── 41
│ └── 1b486eb6afe280fb7e26ed1b00b39c11af4462
├── 60
│ └── 48e4fc794e7df0192939309d8be0d47ca3f71a
├── 61
│ └── 5640b3bdc533cc5180a00ebfe8675115aa11ac
├── 68
│ └── 0ee446d66eab3822ad022908fc03a08f3979de
├── 79
│ └── c4f6aede40a7042add2f89fcd80d260041c0a5
├── 80
│ └── 2ad127fc8baeb11b1a78fd939b5c1fa20636a1
├── 88
│ └── 145707b4619e8ada9308178bec3cd54b18f290
├── ac
│ ├── 1fb501cc308e056a74e3ede5e30c48ac97d2b6
│ └── 68fc7a6f26ec18585249989a5023a940bc9974
├── b4
│ └── bfc685e634816f6bad0b51bac882173bc8e54a
├── c0
│ └── 9cc07facbad3ad88b6384e0f9529ac2a429f30
├── c2
│ ├── 1d1eb5cba29552302382495fb9dbf9bae66f47
│ └── 7e40a839d857c095dd5e3bda0aaf2a61224cb5
├── c7
│ └── 037c0fda18887223fc27048d5491bd4627471a
├── c8
│ └── 1e07cb60fa336b16995dadcd13e50f9c7f9dd4
├── da
│ └── eef85f655ca2a2f240839edfbbc858b32bce0b
├── e4
│ └── 582fa0fc21613231e5bb8bf284a7db9df0937e
├── f9
│ └── 9c1c17a0c67bd6df61ed7fae3e7842b8723105
├── info
│ ├── commit-graph
│ └── packs
└── pack
├── pack-3c257c1a1c5cddbd7adcbbcd0b2eae95178d8e6b.idx
└── pack-3c257c1a1c5cddbd7adcbbcd0b2eae95178d8e6b.pack
20 directories, 24 files