第一次在csdn发文章,还没找到节奏,请多多指教~
这次给大家介绍一下Git中常用的cherry-pick。
cherry-pick的作用:将现有的某个提交应用到当前分支上
git cherry-pick [--edit] [-n] [-m parent-number] [-s] [-x] [--ff]
[-S[]] …
git cherry-pick --continue
git cherry-pick --quit
git cherry-pick --abort
首先看一下最简单的用法。
git cherry-pick
这个用法就是将目前仓库中已存在的某个提交A应用到当前分支。在应用成功以后,当前分支的HEAD引用变为A。
示例:切换到dev分支下,并将master分支中的C提交应用到dev分支:
如上图所示,当前仓库有两个本地分支:master和dev。其中master分支中有A,B,C,D 4个提交,dev分支有A,B,E,F 4个提交。
$ git checkout dev
Switched to branch 'dev'
$ git cherry-pick feca78f
[dev bc9f684] C
Date: Sat Jan 19 20:46:31 2019 +0800
1 file changed, 1 insertion(+)
create mode 100644 C
$ git log --oneline --abbrev-commit
bc9f684 (HEAD -> dev) C
14f4789 F
eeb02b1 E
9c0305c B
4cd0c6d A
此时通过gitk看到的提交图形是这样的:
git cherry-pick -n
这个用法是将目前仓库中存在的某个提交应用到当前分支,但是不生成提交。需要通过commit才能产生新的提交。
例如,在前面将master分支上的提交C应用到dev分支后,继续将提交D应用到dev分支,但是在执行时携带-n操作。
$ git cherry-pick 0ed1d6c -n
//当前状态下并没有直接生成一个提交,而是在暂存区中存在D提交的内容。
$ git status
On branch dev
Changes to be committed:
(use "git reset HEAD ..." to unstage)
new file: D
//提交cherry-pick -n 后的D’提交
git commit -m "cherry-pickD"
[dev 6a3a121] cherry-pickD
1 file changed, 1 insertion(+)
create mode 100644 D
$ git status
On branch dev
nothing to commit, working tree clean
$ git log --oneline --abbrev-commit
6a3a121 (HEAD -> dev) cherry-pickD
bc9f684 C
14f4789 F
eeb02b1 E
9c0305c B
4cd0c6d A
用法:
git cherry-pick -s
作用:在将某个提交A应用到当前分支后,在当前分支最新的提交message上加上作者信息。
示例:
//在master分支上创建一个新的提交
$ git checkout master
Switched to branch 'master'
$ echo "G">G
$ git add G
warning: LF will be replaced by CRLF in G.
The file will have its original line endings in your working directory
$ git commit -m "G"
[master e40c664] G
1 file changed, 1 insertion(+)
create mode 100644 G
$ git checkout dev
Switched to branch 'dev'
//将master分支上的新提交应用到dev分支上
$ git cherry-pick e40c664 -s
[dev 48b886c] G
Date: Sun Jan 20 10:50:53 2019 +0800
1 file changed, 1 insertion(+)
create mode 100644 G
$ git log
commit 48b886cdd77c9afe109a23f3c7a6aa877430f955 (HEAD -> dev)
Author: author
Date: Sun Jan 20 10:50:53 2019 +0800
G
Signed-off-by: author//作者信息
用法:
git cherry-pick -x
作用:在应用提交时,git会在提交的原始信息中添加一行信息,表示"源于哪个提交"
示例:
//在master分支上创建一个新的提交
$ git checkout master
Switched to branch 'master'
$ echo "H">H
$ git add .
warning: LF will be replaced by CRLF in H.
The file will have its original line endings in your working directory
$ git commit -m "H"
[master 8143abe] H
1 file changed, 1 insertion(+)
create mode 100644 H
$ git checkout dev
Switched to branch 'dev'
//将提交应用到dev分支上
$ git cherry-pick 8143abe -x
[dev de3e790] H
Date: Sun Jan 20 10:57:52 2019 +0800
1 file changed, 1 insertion(+)
create mode 100644 H
$ git log --abbrev-commit
commit de3e790 (HEAD -> dev)
Author: author
Date: Sun Jan 20 10:57:52 2019 +0800
H
(cherry picked from commit 8143abedef64b2dc79f359117ffcff0449e50157)//源提交的commitId
commit 48b886c
Author: author
Date: Sun Jan 20 10:50:53 2019 +0800
G
Signed-off-by: author //作者信息
用法:
git cherry-pick --ff
解释:如果当前正在应用的提交A的父提交P和当前分支的HEAD指向的提交H相同,那么使用fast-forward策略将HEAD快进到当前应用。
示例:
//从dev检出一个新分支dev2
$ git checkout -b dev2
Switched to a new branch 'dev2'
$ git log --oneline --abbrev-commit
de3e790 (HEAD -> dev2, dev) H
48b886c G
6a3a121 cherry-pickD
bc9f684 C
14f4789 F
eeb02b1 E
9c0305c B
4cd0c6d A
//在新分支上新建提交
$ echo "I">I
$ git add .
warning: LF will be replaced by CRLF in I.
The file will have its original line endings in your working directory
$ git commit -m "I"
[dev2 b715b64] I
1 file changed, 1 insertion(+)
create mode 100644 I
$ git log --oneline --abbrev-commit
b715b64 (HEAD -> dev2) I
de3e790 (dev) H
48b886c G
6a3a121 cherry-pickD
bc9f684 C
14f4789 F
eeb02b1 E
9c0305c B
4cd0c6d A
//切换回dev分支
$ git checkout dev
Switched to branch 'dev'
$ git log --oneline --abbrev-commit
de3e790 (HEAD -> dev) H
48b886c G
6a3a121 cherry-pickD
bc9f684 C
14f4789 F
eeb02b1 E
9c0305c B
4cd0c6d A
//执行--ff操作
$ git cherry-pick --ff b715b64
$ git log
commit b715b64f0ba65b2a656d73321b9cc4b1bd9581c4 (HEAD -> dev, dev2)
Author: author
Date: Sun Jan 20 11:10:29 2019 +0800
I
commit de3e7901cf5cbbd473b4fa43fa554eb4efa8b0e1
Author: author
Date: Sun Jan 20 10:57:52 2019 +0800
H
(cherry picked from commit 8143abedef64b2dc79f359117ffcff0449e50157)
commit 48b886cdd77c9afe109a23f3c7a6aa877430f955
Author: author
Date: Sun Jan 20 10:50:53 2019 +0800
G
Signed-off-by: author
git cherry-pick -m 1
解释:假设有一个提交A,是在dev3分支上合并了dev2分支时产生的提交。现在需要将A提交中来自与dev3分支的提交应用到dev4上时,通过指定-m的参数值实现该需求。-m后面的参数不超过合并时的分支数目。
//当前dev3最新提交时I,commit-id为b715b64
//现在要增加几个提交J、K、L、M
$ echo "J">J
$ git add J
$ git commit J -m "J"
warning: LF will be replaced by CRLF in J.
The file will have its original line endings in your working directory
[dev3 c946df1] J
1 file changed, 1 insertion(+)
create mode 100644 J
$ echo "K">K
$ git add K
warning: LF will be replaced by CRLF in K.
The file will have its original line endings in your working dir
$ git commit K -m "K"
warning: LF will be replaced by CRLF in K.
The file will have its original line endings in your working directory
[dev3 029496a] K
1 file changed, 1 insertion(+)
create mode 100644 K
$ echo "L">L
$ git add L
warning: LF will be replaced by CRLF in L.
The file will have its original line endings in your working directory
$ git commit -m "L" L
warning: LF will be replaced by CRLF in L.
The file will have its original line endings in your working directory
[dev3 506067a] L
1 file changed, 1 insertion(+)
create mode 100644 L
$ echo "M">M
$ git add M
warning: LF will be replaced by CRLF in M.
The file will have its original line endings in your working directory
$ git commit -m "M" M
warning: LF will be replaced by CRLF in M.
The file will have its original line endings in your working directory
[dev3 c02ef9d] M
1 file changed, 1 insertion(+)
create mode 100644 M
//产生一个合并的提交
$ git merge dev2
Merge made by the 'recursive' strategy.
B | 1 +
C | 1 +
D | 1 +
E | 1 +
F | 1 +
G | 1 +
H | 1 +
I | 1 +
8 files changed, 8 insertions(+)
create mode 100644 B
create mode 100644 C
create mode 100644 D
create mode 100644 E
create mode 100644 F
create mode 100644 G
create mode 100644 H
create mode 100644 I
//在合并的提交后面增加一个提交N
$ echo "N">N
$ git add N
warning: LF will be replaced by CRLF in N.
The file will have its original line endings in your working directory
$ git commit N -m "N"
warning: LF will be replaced by CRLF in N.
The file will have its original line endings in your working directory
[dev3 04c8735] N
1 file changed, 1 insertion(+)
create mode 100644 N
//从主分支切出一个dev4分支,只包含主分支的第一个提交
$ git checkout master
Switched to branch 'master'
$ git checkout -b dev4 HEAD~5
Switched to a new branch 'dev4'
$ git log --abbrev-commit --oneline
4cd0c6d (HEAD -> dev4) A
//将dev3分支中由从dev2分支合并而来的提交应用到当前分支,并且只应用dev3分支部分的代码
$ git cherry-pick -m 2 e1eda64
[dev4 2e37f16] Merge branch 'dev2' into dev3
Date: Sun Jan 20 13:49:25 2019 +0800
4 files changed, 4 insertions(+)
create mode 100644 J
create mode 100644 K
create mode 100644 L
create mode 100644 M
$ git log --oneline --abbrev-commit
2e37f16 (HEAD -> dev4) Merge branch 'dev2' into dev3
4cd0c6d A
//将dev3分支中由从dev2分支合并而来的提交应用到当前分支,并且只应用dev2分支部分的代码
//首先先移除刚刚应用到dev4的提交.
$ git reset HEAD~1 --hard
HEAD is now at 4cd0c6d A
//应用
$ git cherry-pick -m 1 e1eda64
[dev4 6104083] Merge branch 'dev2' into dev3
Date: Sun Jan 20 13:49:25 2019 +0800
8 files changed, 8 insertions(+)
create mode 100644 B
create mode 100644 C
create mode 100644 D
create mode 100644 E
create mode 100644 F
create mode 100644 G
create mode 100644 H
create mode 100644 I
用法:
git cherry-pick --continue
当执行cherry-pick指令发生冲突时,在解决冲突以后,先执行add执领,然后执行--continue指令,使cherry-pick操作成功,当前分支变为干净的分支,HEAD指向cherry-pick的提交。
用法
git cherry-pick --abort
解释:当执行cherry-pick发生冲突时,执行该指令可以放弃cherry-pick执行后引发的代码"合并",使得当前分支变为干净的分支,HEAD不变。
用法
git cherry-pick --quit
解释:放弃并清空cherry-pick失败或revert失败的操作,当前分支变为干净,并且HEAD不变。
git cherry-pick
将branchname分支的最新提交应用到当前分支。