分支几乎是 Git 的必杀技,倒不是说其他的版本控制没有分支这个特性,而是 Git 分支早已把其它的版本控制系统分支功能甩了好几条街。这么说不是夸张,因为 Git 的实现与项目复杂度无关,它永远可以在几毫秒的时间内完成分支的创建和切换。同时,因为每次提交时都记录了祖先信息,将来要合并分支时,寻找恰当的合并基础的工作其实已经很显然的摆在那里,所以实现起来非常容易。Git 鼓励开发者频繁使用分支,正是仗着这些特性作保障。
本地分支
创建分支
1
2
3
4
5
6
| // 创建一个名称为 develop 的分支
$ git checkout -b develop
Switched to a new branch 'develop'
等价于
$ git branch develop
$ git checkout develop
|
删除分支
1
2
3
4
5
6
7
8
| // 删除一个已经有提交记录但还没有合并到 master 的分支
$ git branch -d develop
error: The branch 'develop' is not fully merged.
If you are sure you want to delete it, run 'git branch -D develop'.
// 确定不合并 develop 分支的任何提交并删除此分支
$ git branch -D develop
Deleted branch develop (was 833b688).
|
查看分支
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| // 查看分支列表
$ git branch
* develop
feature
master
// 查看每一个分支的最后一次提交
$ git branch -v
* develop 9ad35ee Add index.js
feature 992122d Add .editorconfig
master 23a0a9e Rename index.php to index.html
// 查看哪些分支已经合并到当前分支
$ git branch --merged
develop
* master
// 查看所有包含未合并工作的分支
$ git branch --no-merged
feature
|
合并分支
1
2
3
4
5
| $ git checkout master
$ git merge --no-ff develop
Merge made by the 'recursive' strategy.
README.md | 1 +
1 file changed, 1 insertion(+)
|
分支变基
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
| // 切换到要变基的分支
$ git checkout feature
Switched to branch 'feature'
// 进行变基
$ git rebase master
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: Add .editorconfig
Applying: Add releases link
Using index info to reconstruct a base tree...
M README.md
Falling back to patching base and 3-way merge...
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
error: Failed to merge in the changes.
Patch failed at 0002 Add releases link
Use 'git am --show-current-patch' to see the failed patch
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".
// 查看当前的补丁
$ git am --show-current-patch
commit 15539736e18fe133f5916a55e8f38ce7b734113a (feature)
Author: imajinyun <imajinyun@gmail.com>
Date: Mon Dec 31 21:24:59 2018 +0800
Add releases link
diff --git a/README.md b/README.md
index d467b4f..8ec2025 100644
--- a/README.md
+++ b/README.md
@@ -2,3 +2,4 @@
[2]: https://symfony.com/projects
[3]: https://symfony.com/doc/current/reference/requirements.html
[4]: https://symfony.com/doc/current/setup.html
+[5]: https://symfony.com/doc/current/contributing/community/releases.html
// 解决冲突完成变基
$ vim README.md
冲突的文件内容:
[1]: https://symfony.com
[2]: https://symfony.com/projects
[3]: https://symfony.com/doc/current/reference/requirements.html
[4]: https://symfony.com/doc/current/setup.html
<<<<<<< HEAD
[5]: http://semver.org
=======
[5]: https://symfony.com/doc/current/contributing/community/releases.html
>>>>>>> Add releases link
修复后的文件内容:
[1]: https://symfony.com
[2]: https://symfony.com/projects
[3]: https://symfony.com/doc/current/reference/requirements.html
[4]: https://symfony.com/doc/current/setup.html
[5]: http://semver.org
[6]: https://symfony.com/doc/current/contributing/community/releases.html
// 查看仓库状态
$ git status
rebase in progress; onto 4830059
You are currently rebasing branch 'feature' on '4830059'.
(fix conflicts and then run "git rebase --continue")
(use "git rebase --skip" to skip this patch)
(use "git rebase --abort" to check out the original branch)
Unmerged paths:
(use "git reset HEAD <file>..." to unstage)
(use "git add <file>..." to mark resolution)
both modified: README.md
no changes added to commit (use "git add" and/or "git commit -a")
$ git add README.md
$ git rebase --continue
Applying: Add releases link
// 合并此分支代码到 master 分支
$ git checkout master
$ git merge --no-ff feature
Merge made by the 'recursive' strategy.
.editorconfig | 0
README.md | 1 +
2 files changed, 1 insertion(+)
create mode 100644 .editorconfig
// 变基后的历史记录,可以看到变基使得提交历史更加整洁,日志就像是串行一样
$ git log --oneline --graph
* f686948 (HEAD -> master) Merge branch 'feature' to master
|\
| * 78a6bfc (feature) Add releases link
| * 34f8649 Add .editorconfig
|/
* 4830059 (develop) Merge branch 'develop' to master
|\
| * 04a75c1 Add semver link
* | 3bdd3fc Merge branch 'develop' to master
|\ \
| |/
| * d48ea11 Add setup link
|/
* 3513802 Merge branch 'develop' to master
|\
| * 9ad35ee Add index.js
| * 0bc04c2 Add index.css
|/
* 23a0a9e Rename index.php to index.html
* da3c74c Add index.php
* 7778db8 Add projects and requirements link
* facc111 Add symfony website link
* a384a2b Add README.md
|
其它操作
整合连续多次提交
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
| // 查看提交日志
$ git log --oneline --graph --all
* f686948 (HEAD -> master) Merge branch 'feature' to master
|\
| * 78a6bfc (feature) Add releases link
| * 34f8649 Add .editorconfig
|/
* 4830059 (develop) Merge branch 'develop' to master
|\
| * 04a75c1 Add semver link
* | 3bdd3fc Merge branch 'develop' to master
|\ \
| |/
| * d48ea11 Add setup link
|/
* 3513802 Merge branch 'develop' to master
|\
| * 9ad35ee Add index.js
| * 0bc04c2 Add index.css
|/
* 23a0a9e Rename index.php to index.html
* da3c74c Add index.php
* 7778db8 Add projects and requirements link
* facc111 Add symfony website link
* a384a2b Add README.md
// 整合最近提交的 2 次记录,commit-id 使用第二次之前的
$ git rebase -i 4830059
弹出的编辑界面内容为:
pick 34f8649 Add .editorconfig
s 78a6bfc Add releases link # 修改 pick 为 squash 或者 s
# Rebase 4830059..f686948 onto 4830059 (2 commands)
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
保存后会弹出另一个编辑界面,内容为:
# This is a combination of 2 commits.
Integrating submission logs # 添加本次的提交日志信息
# This is the 1st commit message:
Add .editorconfig
# This is the commit message #2:
Add releases link
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date: Mon Dec 31 20:39:09 2018 +0800
#
# interactive rebase in progress; onto 4830059
# Last commands done (2 commands done):
# pick 34f8649 Add .editorconfig
# squash 78a6bfc Add releases link
# No commands remaining.
# You are currently rebasing branch 'master' on '4830059'.
#
# Changes to be committed:
# new file: .editorconfig
# modified: README.md
#
[detached HEAD f9fa04a] Integrating submission logs
Date: Mon Dec 31 20:39:09 2018 +0800
2 files changed, 1 insertion(+)
create mode 100644 .editorconfig
Successfully rebased and updated refs/heads/master.
// 查看提交日志
* f9fa04a (HEAD -> master) Integrating submission logs
* 4830059 (develop) Merge branch 'develop' to master
|\
| * 04a75c1 Add semver link
* | 3bdd3fc Merge branch 'develop' to master
|\ \
| |/
| * d48ea11 Add setup link
|/
* 3513802 Merge branch 'develop' to master
|\
| * 9ad35ee Add index.js
| * 0bc04c2 Add index.css
|/
* 23a0a9e Rename index.php to index.html
* da3c74c Add index.php
* 7778db8 Add projects and requirements link
* facc111 Add symfony website link
* a384a2b Add README.md
|
整合间歇多次提交
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
| $ git log --oneline --graph
* f9fa04a (HEAD -> master) Integrating submission logs
* 4830059 (develop) Merge branch 'develop' to master
|\
| * 04a75c1 Add semver link
* | 3bdd3fc Merge branch 'develop' to master
|\ \
| |/
| * d48ea11 Add setup link
|/
* 3513802 Merge branch 'develop' to master
|\
| * 9ad35ee Add index.js
| * 0bc04c2 Add index.css
|/
* 23a0a9e Rename index.php to index.html
* da3c74c Add index.php
* 7778db8 Add projects and requirements link
* facc111 Add symfony website link
* a384a2b Add README.md
// 变基
$ git rebase -i 23a0a9e
弹出的编辑界面内容为:
pick 23a0a9e
s 0bc04c2 Add index.css # 修改 pick 为 squash 或 s
s 9ad35ee Add index.js # 修改 pick 为 squash 或 s
s d48ea11 Add setup link # 修改 pick 为 squash 或 s
s 04a75c1 Add semver link # 修改 pick 为 squash 或 s
pick f9fa04a Integrating submission logs
# Rebase 23a0a9e..f9fa04a onto 23a0a9e (5 commands)
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
正常情况下会提示成功,否则会出现如下情况:
The previous cherry-pick is now empty, possibly due to conflict resolution.
If you wish to commit it anyway, use:
git commit --allow-empty
Otherwise, please use 'git reset'
interactive rebase in progress; onto 23a0a9e
Last command done (1 command done):
pick 23a0a9e Add links and static file
Next commands to do (5 remaining commands):
squash 0bc04c2 Add index.css
squash 9ad35ee Add index.js
You are currently rebasing branch 'master' on '23a0a9e'.
nothing to commit, working tree clean
Could not apply 23a0a9e... Add links and static file
// 查看状态
$ git status
interactive rebase in progress; onto 23a0a9e
Last command done (1 command done):
pick 23a0a9e
Next commands to do (8 remaining commands):
squash 04a75c1 Add semver link
squash d48ea11 Add setup link
squash 9ad35ee Add index.js
squash 0bc04c2 Add index.css
(use "git rebase --edit-todo" to view and edit)
You are currently editing a commit while rebasing branch 'master' on '23a0a9e'.
(use "git commit --amend" to amend the current commit)
(use "git rebase --continue" once you are satisfied with your changes)
nothing to commit, working tree clean
// 继续变基
$ git rebase --continue
继续后弹出的编辑界面内容:
# This is a combination of 5 commits.
Add links and static file # 添加一行日志信息
# This is the 1st commit message:
Rename index.php to index.html
# This is the commit message #2:
Add index.css
# This is the commit message #3:
Add index.js
# This is the commit message #4:
Add setup link
# This is the commit message #5:
Add semver link
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date: Mon Dec 31 20:05:25 2018 +0800
#
# interactive rebase in progress; onto 23a0a9e
# Last commands done (5 commands done):
# squash d48ea11 Add setup link
# squash 04a75c1 Add semver link
# Next command to do (1 remaining command):
# pick f9fa04a Integrating submission logs
# You are currently rebasing branch 'master' on '23a0a9e'.
#
# Changes to be committed:
# modified: README.md
# renamed: index.php -> index.css
# new file: index.html
# new file: index.js
#
[detached HEAD 688088f] Add links and static file
Date: Mon Dec 31 20:05:25 2018 +0800
4 files changed, 2 insertions(+)
rename index.php => index.css (100%)
create mode 100644 index.html
create mode 100644 index.js
Successfully rebased and updated refs/heads/master.
// 查看日志信息
$ git log --oneline --graph
* fe3b3cf (HEAD -> master) Integrating submission logs
* 688088f Add links and static file
* da3c74c Add index.php
* 7778db8 Add projects and requirements link
* facc111 Add symfony website link
* a384a2b Add README.md
|