最简单Git进阶教程

什么是分支

在版本控制过程中,同时推进多个任务,为每个任务,我们就可以创建每个任务的单独分支。使用分支意味着程序员可以把自己的工作从开发主线上分离开来,开发自己分支的时候,不会影响主线分支的运行。对于初学者而言,分支可以简单理解为副本,一个分支就是一个单独的副本。(分支底层其实也是指针的引用)

git分支操作流程

分支的好处

同时并行推进多个功能开发,提高开发效率。
各个分支在开发过程中,如果某一个分支开发失败,不会对其他分支有任何影响。失败的分支删除重新开始即可。

Git分支的操作

命令名称作用
git branch 分支名创建分支
git branch -v查看分支
git branch -d name删除分支
git branch -b name创建分支并切换到这个分支
git checkout 分支名切换分支
git merge 分支名把指定的分支合并到当前分支上

查看当前分支

1
2
3
4
[root@boysec.cn ~/git_data]$git branch 
* master
[root@boysec.cn ~/git_data]$git branch -v
* master 562b1b9 add boysec

创建分支

1
2
3
4
[root@boysec.cn ~/git_data]$git branch testing
[root@boysec.cn ~/git_data]$git branch -v
* master 562b1b9 add boysec
testing 562b1b9 add boysec

创建新分支并切换到指定分支

1
2
3
4
5
6
[root@boysec.cn ~/git_data]$git checkout -b tes  # 会创建新分支斌切换,分支存在则会报错。
Switched to branch 'testing'
[root@boysec.cn ~/git_data]$git branch -v
master 562b1b9 add boysec
* test 562b1b9 add boysec
testing 562b1b9 add boysec

查看分支指向

1
2
3
4
[root@boysec.cn ~/git_data]$git log --oneline --decorate
562b1b9 (HEAD, testing, test, master) add boysec
a6576d2 modified a
d3dfcbb commit a

切换到指定分支

切换到test分支

1
2
3
4
5
[root@boysec.cn ~/git_data]$git checkout  test
[root@boysec.cn ~/git_data]$git branch
master
* test
testing

在当前分支创建文件并提交到本地仓库

1
2
3
4
5
6
7
[root@boysec.cn ~/git_data]$git commit -m "commit test"
[test 6f13b3a] commit test
2 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 b
create mode 100644 test
[root@boysec.cn ~/git_data]$ls
a b test

切换到master分支查看文件

1
2
3
4
5
6
7
8
[root@boysec.cn ~/git_data]$git checkout master
Switched to branch 'master'
[root@boysec.cn ~/git_data]$git branch -v
* master 562b1b9 add boysec
test 6f13b3a commit test
testing 562b1b9 add boysec
[root@boysec.cn ~/git_data]$ls
a

在master分支下创建文件

1
2
3
4
5
6
7
8
9
10
[root@boysec.cn ~/git_data]$touch master
[root@boysec.cn ~/git_data]$git add .
[root@boysec.cn ~/git_data]$git commit -m "commit master"
[master a543b45] commit master
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 master
[root@boysec.cn ~/git_data]$ll
total 4
-rw-r--r-- 1 root root 7 Dec 6 22:54 a
-rw-r--r-- 1 root root 0 Dec 8 11:53 master

合并分支

将test和master分支合并

1
2
3
4
5
6
7
8
9
10
11
[root@boysec.cn ~/git_data]$git branch 
* master
test
testing
[root@boysec.cn ~/git_data]$git merge test
Merge made by the 'recursive' strategy.
b | 0
test | 0
2 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 b
create mode 100644 test

查看提交日志

1
2
3
4
5
6
7
[root@boysec.cn ~/git_data]$git log --oneline --decorate
04bfdc1 (HEAD, master) Merge branch 'test'
a543b45 commit master
6f13b3a (test) commit test
562b1b9 (testing) add boysec
a6576d2 modified a
d3dfcbb commit a

查看文件

1
2
3
4
5
6
[root@boysec.cn ~/git_data]$ll
total 4
-rw-r--r-- 1 root root 7 Dec 6 22:54 a
-rw-r--r-- 1 root root 0 Dec 8 11:55 b
-rw-r--r-- 1 root root 0 Dec 8 11:53 master
-rw-r--r-- 1 root root 0 Dec 8 11:55 test

冲突合并

在master分支下编辑a文件并提交

1
2
3
4
5
6
7
[root@boysec.cn ~/git_data]$echo "master" >> a
[root@boysec.cn ~/git_data]$cat a
boysec
master
[root@boysec.cn ~/git_data]$git commit -am "modified a on master"
[master bacb118] modified a
1 file changed, 1 insertion(+)

切换到test分支下编辑文件并提交

1
2
3
4
5
6
7
[root@boysec.cn ~/git_data]$git checkout test
Switched to branch 'test'
[root@boysec.cn ~/git_data]$echo test >> a
[root@boysec.cn ~/git_data]$cat a
boysec
test
[root@boysec.cn ~/git_data]$git commit -am "modified a on test"

切换到master分支并合并test分支,此时两个分支的文件内容是有冲突的

1
2
3
4
5
6
[root@boysec.cn ~/git_data]$git checkout master 
Switched to branch 'master'
[root@boysec.cn ~/git_data]$git merge test
自动合并 a
冲突(内容):合并冲突于 a
自动合并失败,修正冲突然后提交修正的结果。

此时冲突内容会自动写到文件里

1
2
3
4
5
6
7
[root@boysec.cn ~/git_data]$cat a 
boysec
<<<<<<< HEAD
master # 当前分支的代码
=======
test # 合并过来的代码
>>>>>>> test

冲突产生的原因:

合并分支时,两个分支在 同一个文件的同一个位置有两套完全不同的修改。Git 无法替我们决定使用哪一个。必须 人为决定新代码内容。

要想解决冲突,我们需要手动修改文件,保留最终的文件,然后重新提交

1
2
3
[root@boysec.cn ~/git_data]$vim a
[root@boysec.cn ~/git_data]$git commit -am "merge test to master"
[master f712a5c] merge test to master

查看提交日志

1
2
3
4
5
6
7
8
9
10
[root@boysec.cn ~/git_data]$git log --oneline --decorate
f712a5c (HEAD, master) merge test to master
2acf568 (test) modified a on test
bacb118 modified a
04bfdc1 Merge branch 'test'
a543b45 commit master
6f13b3a commit test
562b1b9 (testing) add boysec
a6576d2 modified a
d3dfcbb commit a

删除指定分支

1
2
[root@boysec.cn ~/git_data]$git branch -d testing 
Deleted branch testing (was 562b1b9).

创建分支和切换分支图解

  • master、test 其实都是指向具体版本记录的指针。当前所在的分支,其实是由 HEAD决定的。所以创建分支的本质就是多创建一个指针。
  • HEAD 如果指向 master,那么我们现在就在 master 分支上。
  • HEAD 如果指向 test,那么我们现在就在 test 分支上。
  • 所以切换分支的本质就是移动 HEAD 指针。

git标签使用

给当前版本创建标签

1
[root@boysec.cn ~/git_data]$git tag v1.0 -m "a b master test version v1.0"

给指定版本打标签

1
2
3
4
5
6
7
8
9
10
11
[root@boysec.cn ~/git_data]$git log --oneline 
f712a5c merge test to master
2acf568 modified a on test
bacb118 modified a
04bfdc1 Merge branch 'test'
a543b45 commit master
6f13b3a commit test
562b1b9 add boysec
a6576d2 modified a
d3dfcbb commit a
[root@boysec.cn ~/git_data]$git tag -a v2.0 562b1b9 -m "add boysec version v2.0"

查看标签

1
2
3
[root@boysec.cn ~/git_data]$git tag 
v1.0
v2.0

回滚到指定标签

首先查看当前版本文件

1
2
3
4
5
6
[root@boysec.cn ~/git_data]$ll
total 4
-rw-r--r-- 1 root root 14 Dec 8 12:45 a
-rw-r--r-- 1 root root 0 Dec 8 11:55 b
-rw-r--r-- 1 root root 0 Dec 8 11:59 master
-rw-r--r-- 1 root root 0 Dec 8 11:55 test

回滚到指定版本

1
2
[root@boysec.cn ~/git_data]$git reset --hard v2.0
HEAD is now at 562b1b9 add boysec

再次查看文件

1
2
3
[root@boysec.cn ~/git_data]$ll
total 4
-rw-r--r-- 1 root root 7 Dec 8 12:59 a

git