当前位置:   article > 正文

超详细的万字Git分支教程(保姆级别)_git 创建分支

git 创建分支

HEAD是一个活动指针,指向的是正在活跃的分支。

【在当前HEAD指针指向的位置创建分支】

git branch b1

  • 1
  • 2

查看.git\refs\heads目录:

【继续使用master分支开发】

echo '444' > aaa.txt
git commit -m '444' ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git log --oneline
2920850 (HEAD -> master) 444
57a8f94 (b1) 333
3ac4fa8 222
afb705d 111

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

1.2.2 指定提交对象创建分支

【指定提交对象来创建分支】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git branch b2 3ac4fa8					# 根据指定的提交对象来创建分支

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git log --oneline
2920850 (HEAD -> master) 444
57a8f94 (b1) 333
3ac4fa8 (b2) 222
afb705d 111

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ cat .git/refs/heads/b2
3ac4fa83b8c224518758b2b4ef7d2f214ac0224a

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

1.3 切换分支

1.3.1 checkout分支切换

创建好了分支之后,我们可以使用git checkout切换到其他分支进行开发;

  • 语法:
git checkout {branchName}

  • 1
  • 2

【准备环境】

rm -rf .git ./*
git init
echo '111' >> aaa.txt
git add ./
git commit -m '111' ./
echo '222' >> aaa.txt
git commit -m '222' ./
echo '333' >> aaa.txt
git commit -m '333' ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git log --oneline
2130f83 (HEAD -> master) 333
86cbe2b 222
dad9d1a 111

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

【创建分支】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)		# 在当前位置创建b1分支
$ git branch b1

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)		# 指定提交对象来创建分支
$ git branch b2 86cbe2b

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)		
$ git log --oneline
2130f83 (HEAD -> master, b1) 333		# b1分支的位置
86cbe2b (b2) 222						# b2分支的位置
dad9d1a 111

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

【切换到b1分支进行开发】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)		# 切换到b1分支
$ git checkout b1
Switched to branch 'b1'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)			# HEAD指针指向了b1分支
$ git log --oneline
2130f83 (HEAD -> b1, master) 333
86cbe2b (b2) 222
dad9d1a 111

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)		# 编辑文件
$ echo "444" >> aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)		# 提交
$ git commit -m "b1 444" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)		# 查看文件内容
$ cat aaa.txt
111
222
333
444

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)		# 查看日志
$ git log --oneline
51b41c0 (HEAD -> b1) b1 444				# b1分支正在开发
2130f83 (master) 333					# master和b2分支留在原地
86cbe2b (b2) 222
dad9d1a 111

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)		# 切换到master分支
$ git checkout master
Switched to branch 'master'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)	# 查看日志
$ git log --oneline
2130f83 (HEAD -> master) 333		# HEAD指针指向了master分支
86cbe2b (b2) 222
dad9d1a 111

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)	# 查看master分支工作状态的文件内容(文件内容是旧版本的)
$ cat aaa.txt
111
222
333

  • 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

【查看所有版本情况】

默认情况下使用git log查询日志只能查询到之前的版本的日志,无法查询到比自身分支版本还要新的版本,通过--all可以查询所有版本的提交日志;

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git log --oneline				# 只能查询master分支之前版本的日志信息
2130f83 (HEAD -> master) 333
86cbe2b (b2) 222
dad9d1a 111

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)		# 查询所有日志信息
$ git log --oneline --all
51b41c0 (b1) b1 444
2130f83 (HEAD -> master) 333
86cbe2b (b2) 222
dad9d1a 111

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
1.3.2 checkout原理

通常情况下,当前分支如果存在未提交的操作时,则无法切换到其他分支;所以我们切换分支时最好保证当前工作空间的状态为nothing to commit;即:所有操作均已提交

在切换分支时,Git会对以下地方进行修改:

  • 1)HEAD指针:将HEAD指针指向最新的分支
  • 2)工作空间的内容:将当前工作空间的内容更新为之前的分支的内容

【代码示例】

rm -rf .git ./*
git init
echo '111' >> aaa.txt
git add ./
git commit -m '111' ./
git branch b1						
echo '222' >> aaa.txt
git add ./
git commit -m '222' ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git log --oneline --all
464d580 (HEAD -> master) 222
cc3429a (b1) 111

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

【操作master分支的文件但不提交,切换到b1分支发现切换失败】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)			# 编辑文件
$ echo "333" >> aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   aaa.txt

no changes added to commit (use "git add" and/or "git commit -a")

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git checkout b1
error: Your local changes to the following files would be overwritten by checkout:
        aaa.txt
Please commit your changes or stash them before you switch branches.
Aborting

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

可以看出,如果当前分支存在未提交的操作时,Git不允许切换分支。但是有2种情况是例外的:

  • 1)新分支的情况:当该分支是一个新创建的分支时,当前分支存在未提交的操作依旧可以切换到新分支,并且会将未提交的操作影响到新分支;
  • 2)新文件的情况:当操作的文件是一个新的文件时,当前分支未提交依旧是可以切换到其他分支,并将操作影响到其他分支;

如果存在以上两种行为进行切换分支,则切换分支时不仅会对HEAD指针、工作空间等地方修改,还会对如下地方进行修改:

  • 1)工作空间的状态:将当前分支的工作空间状态更新为之前分支
  • 2)暂存区的内容:将当前暂存区内容更新为之前的分支

Tips:我们在切换分支时,要保证当前分支是提交的状态,否则会对其他分支造成不必要的影响;

1) 影响工作空间

新分支、新文件的操作都会影响工作空间和暂存区;

【演示新分支影响工作空间】

初始化仓库

rm -rf ./* .git
git init
echo '111' >> aaa.txt
git add ./
git commit -m '111' ./
git branch b1						
Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)	# b1分支创建后整个工作空间还没有提交过任何一次文件,属于新分支
$ git log --oneline --all
4b3c6bc (HEAD -> master, b1) 111			# 指针还是指向master分支的

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

在master分支编辑文件,然后切换到b1分支,查看工作空间的内容,发现变更了(影响了b1分支的工作空间内容):

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 编辑master分支的文件内容
$ echo "222" >> aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# master分支的状态
$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   aaa.txt

no changes added to commit (use "git add" and/or "git commit -a")

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 切换到b1分支,发现能够切换成功
$ git checkout b1
Switched to branch 'b1'
M       aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (b1)			# b1分支的文件内容
$ cat aaa.txt
111
222

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (b1)			# b1分支的状态
$ git status
On branch b1
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   aaa.txt

no changes added to commit (use "git add" and/or "git commit -a")

  • 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

可以看到在遇到新分支时,当前工作空间的操作即使未提交也可以切换到其他分支,而且影响其他分支的工作空间状态及工作空间内容;注意,此时将master未提交的数据也影响到了b1分支,当分支切换到master然后提交,b1分支被影响的内容就消失了;

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (b1)			# 切换到master分支
$ git checkout master
Switched to branch 'master'
M       aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 提交操作
$ git commit -m "222" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 切换到b1分支
$ git checkout b1
Switched to branch 'b1'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (b1)			# 查看内容,发现影响消失了
$ cat aaa.txt
111

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

重新切换到master分支,编辑文件未提交,切换到b1分支失败(此时b1分支不属于新分支了):

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (b1)
$ git checkout master
Switched to branch 'master'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ echo "333" >> aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)			# 切换到b1分支失败,此时b1分支不属于新分支了;
$ git checkout b1
error: Your local changes to the following files would be overwritten by checkout:
        aaa.txt
Please commit your changes or stash them before you switch branches.
Aborting

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

【演示新文件影响工作空间】

把之前编辑的内容删除,将工作空间恢复到干净状态

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 把之前编辑的内容删除
$ vi aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ cat aaa.txt
111
222

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 工作空间又回到了干净状态(所有的操作均已提交)
$ git status
On branch master
nothing to commit, working tree clean

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

使用master创建一个新的文件,切换到b1分支,查看b1分支的工作空间内容,发现也多了一个bbb.txt文件(影响了b1分钟的工作空间):

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 编辑一个新的文件
$ echo "333" >> bbb.txt		# 注意,此时创建了一个新的文件bbb.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        bbb.txt

nothing added to commit but untracked files present (use "git add" to track)

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 切换到b1分支,发现切换成功
$ git checkout b1
Switched to branch 'b1'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (b1)
$ ll
total 2
-rw-r--r-- 1 Adminstrator 197121 5 Oct 23 09:23 aaa.txt
-rw-r--r-- 1 Adminstrator 197121 4 Oct 23 09:23 bbb.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (b1)			# b1的工作空间多了一个文件
$ git status
On branch b1
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        bbb.txt

nothing added to commit but untracked files present (use "git add" to track)

  • 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

切换到master分支,提交操作,然后切换回b1分支,发现b1分支的bbb.txt文件清除了:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (b1)			# 切换回master分支
$ git checkout master
Switched to branch 'master'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git add ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 提交操作
$ git commit -m "333-bbb" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 切换到b1分支
$ git checkout b1
Switched to branch 'b1'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (b1)
$ git status
On branch b1
nothing to commit, working tree clean

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (b1)		# b1工作空间的bbb.txt文件清除了
$ ll
total 1
-rw-r--r-- 1 Adminstrator 197121 5 Oct 23 09:26 aaa.txt

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
2) 影响暂存区

【演示新分支影响暂存区】

初始化仓库:

rm -rf ./* .git
git init
echo '111' >> aaa.txt
git add ./
git commit -m '111' ./
git branch b1			

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# b1分支创建后整个工作空间还没有提交过任何一次文件,属于新分支
$ git log --oneline --all
19fd84b (HEAD -> master, b1) 111		# 指针还是指向master分支的

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

在master分支编辑文件,然后添加到暂存区,切换到b1分支,查看b1分支的暂存区内容,发现变更了(影响了b1分支的暂存区);

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ echo "222" >> aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git add ./
warning: LF will be replaced by CRLF in aaa.txt.
The file will have its original line endings in your working directory

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git checkout b1
Switched to branch 'b1'
M       aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (b1)
$ git ls-files -s
100644 a30a52a3be2c12cbc448a5c9be960577d13f4755 0       aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (b1)
$ git cat-file -p a30a52a3
111
222

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

重新切换回master,提交之前的操作,然后再切换回b1分支,查看暂存区内容,发现影响消除了(此时b1不再属于新分支了):

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (b1)
$ git checkout master
Switched to branch 'master'
M       aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git commit -m "222" ./
warning: LF will be replaced by CRLF in aaa.txt.
The file will have its original line endings in your working directory
[master 2ae7cda] 222
 1 file changed, 1 insertion(+)

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git checkout b1
Switched to branch 'b1'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (b1)
$ git ls-files -s
100644 58c9bdf9d017fcd178dc8c073cbfcbb7ff240d6c 0       aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (b1)
$ git cat-file -p 58c9bdf9
111

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

切换回master分支,编辑文件,还没有提交,切换到b1分钟发现出错(此时b1分支不属于新分支了):

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ echo "333" >> aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git add ./
warning: LF will be replaced by CRLF in aaa.txt.
The file will have its original line endings in your working directory

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git checkout b1
error: Your local changes to the following files would be overwritten by checkout:
        aaa.txt
Please commit your changes or stash them before you switch branches.
Aborting

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

【演示新文件影响工作空间】

提交之前的操作,将工作空间恢复到干净状态

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git commit -m "333" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git log --oneline --all
f5d54ea (HEAD -> master) 333
2ae7cda 222
e9b98e3 (b1) 111

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

创建一个新文件,添加到暂存区,然后切换到b1分支,发现b1分支的暂存区也多了一个文件(影响了b1分支的暂存区):

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ echo "444-bbb" >> bbb.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git add ./
warning: LF will be replaced by CRLF in bbb.txt.
The file will have its original line endings in your working directory

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git checkout b1
Switched to branch 'b1'
A       bbb.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (b1)		# b1分支的暂存区也多了一个文件
$ git ls-files -s
100644 58c9bdf9d017fcd178dc8c073cbfcbb7ff240d6c 0       aaa.txt
100644 a864cef2a0696aabcc85e6e55f04dc12230bab84 0       bbb.txt

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

切换回master,提交之前的操作,然后再切换回b1分支,查询b1分支的暂存区内容被消除了(消除影响):

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (b1)
$ git checkout master
Switched to branch 'master'
A       bbb.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git commit -m "444-bbb" ./
warning: LF will be replaced by CRLF in bbb.txt.
The file will have its original line endings in your working directory
[master d76cc6f] 444-bbb
 1 file changed, 1 insertion(+)
 create mode 100644 bbb.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git checkout b1
Switched to branch 'b1'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (b1)
$ git ls-files -s
100644 58c9bdf9d017fcd178dc8c073cbfcbb7ff240d6c 0       aaa.txt

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

此时bbb.txt文件已经不属于新文件了,回到master分支,编辑bbb.txt文件,未提交,然后切换到b1分支,发现切换不了:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (b1)
$ git checkout master
Switched to branch 'master'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ echo "555-bbb" >> bbb.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git add ./
warning: LF will be replaced by CRLF in bbb.txt.
The file will have its original line endings in your working directory

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git checkout b1
error: Your local changes to the following files would be overwritten by checkout:
        bbb.txt
Please commit your changes or stash them before you switch branches.
Aborting

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
1.3.3 switch切换分支

git switch是Git 2.23版本推出的一个新的命令,专门用于分支的切换,而git checkout除了做分支的切换还有一些其他的功能,如恢复文件,恢复暂存区等;

初始化仓库:

rm -rf ./* .git
git init
echo '111' >> aaa.txt
git add ./
git commit -m '111' ./

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

使用git checkout恢复文件:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ echo "222" >> aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   aaa.txt

no changes added to commit (use "git add" and/or "git commit -a")

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git checkout aaa.txt
Updated 1 path from the index

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git status
On branch master
nothing to commit, working tree clean

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

使用git checkout恢复暂存区:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ echo "222" >> aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 添加到暂存区
$ git add ./
warning: LF will be replaced by CRLF in aaa.txt.
The file will have its original line endings in your working directory

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   aaa.txt


Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git reset aaa.txt
Unstaged changes after reset:
M       aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git checkout aaa.txt
Updated 1 path from the index

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 成功恢复
$ git status		
On branch master
nothing to commit, working tree clean

  • 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

git switch命令是专门用于切换分支的,并且git switch切换分支也会存在我们探究的新分支、新文件切换时所带来的影响问题;

使用git switch命令切换分支:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 ((89dda87...))
$ git log --oneline --all
033f6b5 (master) 222
89dda87 (HEAD) 111

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 ((89dda87...))
$ git branch b1

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 ((89dda87...))
$ git switch b1
Switched to branch 'b1'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (b1)
$ git log --oneline --all
033f6b5 (master) 222
89dda87 (HEAD -> b1) 111

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

1.4 分支合并

建立好分支后,我们可以使用分支进行开发功能,开发功能趋于成熟稳定后,我们可以将master分支与当前分支进行合并,这样其他分支的功能就集成到主分支上了,这也是当前主流的开发方式。

使用分支开发功能从角度上划分一般为同轴开发非同轴开发

  • 分支合并语法:
git merge {branchName}

  • 1
  • 2
  • 解释:将branchName分支的代码合并到当前分支
1.4.1 快进合并
  • 同轴开发的快进合并:

同轴开发:创建一个新分支,使用新分支开发,等待开发功能趋于成熟稳定后,我们可以将master分支与新分支进行合并,这样其他分支的功能就集成到主分支上了,这也是企业里面经常用的一种开发方式;

对于前面的版本想要合并后面的版本,我们称为快进合并

在同轴开发中,多个分支处于同一根开发轴上,后面版本的代码包含前面版本的代码,因此同轴开发一般只会存在快进合并;

  • 如图所示:

  • 首先创建一个新分支(login分支)
  • 切换到新分支,在新分支开发上功能代码

【示例代码】

初始化项目:

rm -rf .git ./*
git init
echo '用户名+密码登录' >> login.txt
git add ./
git commit -m '用户名+密码登录功能完成' ./

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

①创建login分支

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git branch login

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git log --oneline --all
2f5d87a (HEAD -> master, login) 用户名+密码登录功能完成

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

②切换到login分支

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git checkout login
Switched to branch 'login'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (login)
$ git log --oneline --all
2f5d87a (HEAD -> login, master) 用户名+密码登录功能完成

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

③使用login分支开发:集成QQ登录

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (login)
$ echo "集成QQ登录" >> login.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (login)
$ git commit -m "集成QQ登录" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (login)
$ git log --oneline --all
a879a6c (HEAD -> login) 集成QQ登录
2f5d87a (master) 用户名+密码登录功能完成

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

④使用login分支开发:集成微信登录

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (login)
$ echo "集成微信登录" >> login.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (login)
$ git commit -m "集成微信登录" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (login)
$ git log --oneline --all
c5a2584 (HEAD -> login) 集成微信登录
a879a6c 集成QQ登录
2f5d87a (master) 用户名+密码登录功能完成

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

当login分支基于稳定后,将功能集成到maste分支:

  • 如图所示:

⑤切换回master分支,将login分支的代码合并到master分支:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (login)
$ git checkout master
Switched to branch 'master'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ cat login.txt
用户名+密码登录

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git merge login
Updating 2f5d87a..c5a2584
Fast-forward
 login.txt | 2 ++
 1 file changed, 2 insertions(+)

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ cat login.txt
用户名+密码登录
集成QQ登录
集成微信登录

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

将login分支的代码合并到master分支,其实本质上就是让master也指向与login一样的提交对象;

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)		# master与login分支指向的是同一个Commit对象
$ cat .git/refs/heads/login
c5a258428f0bec398017159126f0b87b0d05a1e4
Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ cat .git/refs/heads/master
c5a258428f0bec398017159126f0b87b0d05a1e4

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
1.4.2 典型合并
  • 非同轴开发的典型合并:

非同轴开发:创建一个新分支,使用新分支开发,与此同时master分支也在开发行功能,等到新分支开发的功能完毕后,将master分支与新分支进行合并,将新分支集成到master分支中,但是新分支在开发过程中master分支也进行了一部分开发。

==在非同轴开发中,后面的版本(v3)需要合并前面的版本(v2),这种合并方式称为典型合并;==由于典型合并存在于非同轴

  • 如图所示:

需要注意的是,如果是同轴开发,后面版本的内容肯定包含前面版本的内容,因此==同轴开发不存在典型合并==,只存在快进合并。另外,非同轴开发也存在快进合并,例如上图中的③步骤中,前面的版本(v2)想要合并后面的版本(v3),这也是一种快进合并。

总结:

  • 同轴开发:只存在快进合并
  • 非同轴开发:
    • 前面的版本合并后面的版本:快进合并
    • 后面的版本合并前面的版本:典型合并

Tips:典型合并必定是非同轴,快进合并可以是非同轴也可以是同轴。

【示例代码】

初始化项目:

rm -rf .git ./*
git init
echo '用户名+密码登录' >> project.txt
git add ./
git commit -m '用户名+密码登录功能完成' ./

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

①创建login分支:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git branch login

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)			# 查看不同轴的日志需要加上--graph
$ git log --oneline --all --graph
* 7c0b2a3 (HEAD -> master, login) 用户名+密码登录功能完成

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

②切换到login分支,使用login分支进行开发:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git checkout login
Switched to branch 'login'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (login)
$ echo "集成QQ登录" >> project.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (login)
$ git commit -m "集成QQ登录" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (login)
$ git log --oneline --all --graph
* 9c968e0 (HEAD -> login) 集成QQ登录
* 7c0b2a3 (master) 用户名+密码登录功能完成

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

③切换回master分支添加注册功能:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (login)
$ git checkout master
Switched to branch 'master'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)		# 查看master分支的project.txt文件,代码并没有合并过来
$ cat project.txt
用户名+密码登录
添加头像上传功能

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)		# 查看日志,处于不同轴开发路径
$ git log --oneline --all --graph
* fecdb41 (HEAD -> master) 添加头像上传功能
| * 9c968e0 (login) 集成QQ登录
|/
* 7c0b2a3 用户名+密码登录功能完成

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

④将login分支的合并到master分支:产生代码冲突

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git merge login
Auto-merging project.txt
CONFLICT (content): Merge conflict in project.txt
Automatic merge failed; fix conflicts and then commit the result.

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master|MERGING)
$ cat project.txt
用户名+密码登录
<<<<<<< HEAD
添加头像上传功能
=======
集成QQ登录
>>>>>>> login

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

解决代码冲突:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master|MERGING)
$ cat project.txt
用户名+密码登录
<<<<<<< HEAD
添加头像上传功能
=======
集成QQ登录
>>>>>>> login

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master|MERGING)
$ vi project.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master|MERGING)
$ cat project.txt
用户名+密码登录
添加头像上传功能
集成QQ登录

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master|MERGING)
$ git commit -a -m "合并login分支,并解决代码冲突"
[master 9ccdde2] 合并login分支,并解决代码冲突

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git log --oneline --all --graph
*   9ccdde2 (HEAD -> master) 合并login分支,并解决代码冲突			# 解决冲突后提交产生一次新的版本
|\
| * 9c968e0 (login) 集成QQ登录
* | fecdb41 添加头像上传功能
|/
* 7c0b2a3 用户名+密码登录功能完成

  • 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

经过上一次合并后,master与login属于同轴了,当切换为login分支,可以使用快进合并来合并master分支;

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)			# 切换为login分支
$ git checkout login
Switched to branch 'login'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (login)			# login分支的代码
$ cat project.txt
用户名+密码登录
集成QQ登录

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (login)
$ git log --oneline --all --graph
*   9ccdde2 (master) 合并login分支,并解决代码冲突
|\
| * 9c968e0 (HEAD -> login) 集成QQ登录			
* | fecdb41 添加头像上传功能
|/
* 7c0b2a3 用户名+密码登录功能完成

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (login)			# 合并master分支
$ git merge master
Updating 9c968e0..9ccdde2
Fast-forward
 project.txt | 1 +
 1 file changed, 1 insertion(+)

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (login)			# 查看login分支的代码,发现master的代码被合并过来了
$ cat project.txt
用户名+密码登录
添加头像上传功能
集成QQ登录

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (login)
$ git log --oneline --all --graph
*   9ccdde2 (HEAD -> login, master) 合并login分支,并解决代码冲突
|\
| * 9c968e0 集成QQ登录
* | fecdb41 添加头像上传功能
|/
* 7c0b2a3 用户名+密码登录功能完成

  • 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

1.5 Git的代码冲突

1.5.1 Git的代码冲突的分类与特点

Git存在代码冲突的情况分为协同开发时的代码冲突分支合并时的代码冲突;其中分支合并时的代码冲突又分为快进合并代码冲突典型合并代码冲突

另外还需要注意的是,Git与SVN的代码冲突逻辑不一致。

Tips:我们本章主要讨论分支合并时的代码冲突。

  • 在SVN中:只要两个用户编辑的不是同一行则不会出现代码冲突。
  • 在Git中:只要两个文件内容不一致,在合并分支时必定会产生冲突,无论两个文件是否编辑的是同一行。不过具体情况还得细分如下:
    • 快进合并:两个分支属于不同轴开发,前面版本合并后面版本时,只要两个文件不一致,合并时必定出现冲突,不管两个分支编辑的是不是同一行。
    • 典型合并:由于典型合并两个分支属于不同的开发轴,而后面的分支想要合并前面的分支,两个文件必定不一致,因此典型合并必定出现代码冲突。

Tips:同轴开发的快进合并是不会产生冲突的。

【SVN代码冲突模拟】

SVN的情况:两个用户编辑的代码是同一行则出现冲突

xiaohuixiaolan
创建abc.txt
内容为:
111
222
执行add
执行commit
执行update
修改内容为:
111aaa
222
执行commit
修改内容为:
111bbb
222
执行update(冲突)

如果"xiaolan"用户最后更改的文件内容为:

111
222bbb

  • 1
  • 2
  • 3

然后再执行update,则不会出现代码冲突,因为SVN判断代码冲突的代码单元为行,即:两个用户编辑的不是同一行就不会出现代码冲突。

1.5.2 快进合并代码冲突

快进合并属于前面的版本合并后面的版本,需要注意的是==前面的版本并非是"旧版本",后面的版本并非是"新版本"==,这主要取决于是否是同轴开发。对于同轴开发,后面的版本自然是新版本,其内容肯定包含前面版本的内容。但对于非同轴开发,后面的版本内容大概率是不包含前面的版本内容的;

在同轴开发情况下,快进合并不会产生代码冲突,但如果在非同轴开发情况下,快进合并就会产生代码冲突了。我们观察下列操作:

master分支test分支
创建abc.txt
内容为:
111
222
执行add
执行commit
创建分支 – 此时test分支的abc.txt的内容也是111、222
修改内容为:
111aaa
222
执行commit
切换到test分支
修改内容为:
111
222bbb
执行commit – 此时test分支和master分支已经不同轴了
切换回master分支,合并test分支,属于快进合并,但会出现冲突

Tips:注意,上述操作在SVN中则不会认为是冲突,因为SVN判断是否冲突的标准是操作同一个文件的同一行记录;

  • 快进合并冲突演示:

【使用Git演示代码冲突】

①初始化项目

rm -rf .git ./*
git init

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ vi aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ cat aaa.txt
111
222

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git add ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git commit -m "111 222" ./

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

②创建test分支

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git branch test

  • 1
  • 2
  • 3

③继续使用master分支开发

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git log --oneline --all --graph
* d40d605 (HEAD -> master, test) 111 222

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ vi aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ cat aaa.txt
111aaa
222

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git commit -m "aaa" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git log --oneline --all --graph
* 09fe9cb (HEAD -> master) aaa
* d40d605 (test) 111 222

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

④切换到test分支开发

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git checkout test
Switched to branch 'test'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test)
$ vi aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test)			# 注意,和master分支修改的文件内容不是同一行
$ cat aaa.txt
111
222bbb

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test)
$ git commit -m "bbb" ./
[test dfe1b42] bbb
 1 file changed, 1 insertion(+), 1 deletion(-)

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test)			# 查看日志,test与master分支已经不同轴
$ git log --oneline --all --graph	
* dfe1b42 (HEAD -> test) bbb
| * 09fe9cb (master) aaa
|/
* d40d605 111 222

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

⑤切换回master分支,合并test分支,出现冲突:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test)			# 切换回master分支
$ git checkout master
Switched to branch 'master'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)		# 合并test分支,属于快进合并,但是会产生冲突
$ git merge test
Auto-merging aaa.txt
CONFLICT (content): Merge conflict in aaa.txt
Automatic merge failed; fix conflicts and then commit the result.

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master|MERGING)
$ cat aaa.txt
<<<<<<< HEAD
111aaa
222
=======
111
222bbb
>>>>>>> test

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master|MERGING)
$ vi aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master|MERGING)
$ cat aaa.txt
111aaa
222bbb


Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master|MERGING)			# 解决冲突
$ git commit -a -m "master合并test分支"
[master adaec78] master合并test分支

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git log --oneline --all --graph
*   adaec78 (HEAD -> master) master合并test分支
|\
| * 7b14536 (test) bbb
* | eeca4c9 aaa
|/
* 5f41035 111 222

  • 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

需要注意的是:此时切换回test分支,合并master分支内容不会出现冲突(属于快进合并,但是内容不一致,但不会出现冲突):因为master分支的内容是刚刚解决了冲突之后用户确定了的内容。

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git checkout test
Switched to branch 'test'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git log --oneline --all --graph
*   adaec78 (master) master合并test分支
|\
| * 7b14536 (HEAD -> test) bbb
* | eeca4c9 aaa
|/
* 5f41035 111 222

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test)
$ cat aaa.txt
111
222bbb

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test)
$ git merge master
Updating 7b14536..adaec78
Fast-forward
 aaa.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test)
$ cat aaa.txt
111aaa
222bbb

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git log --oneline --all --graph
*   adaec78 (HEAD -> test, master) master合并test分支
|\
| * 7b14536 () bbb
* | eeca4c9 aaa
|/
* 5f41035 111 222

  • 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
1.5.3 典型合并代码冲突

典型合并时的代码冲突就是我们之前遇到的那种情况,典型合并属于不同轴的开发,并且后面版本需要合并前面版本的情况,由于不同轴,因此后面版本的内容不一定包含前面版本的内容,由于Git代码冲突的特点,因此典型合并必定会出现代码冲突,因为后面版本的内容不可能和前面版本内容一致。

我们观察下列操作:

master分支test分支
创建abc.txt
内容为:
111
222
执行add
执行commit
创建分支 – 此时test分支的abc.txt的内容也是111、222
修改内容为:
111aaa
222
执行commit
切换到test分支
修改内容为:
111
222bbb
执行commit – 此时test分支和master分支已经不同轴了
合并master分支的代码,属于典型合并,出现代码冲突。
  • 典型合并冲突演示:

【使用Git演示代码冲突】

①初始化项目:

rm -rf .git ./*
git init

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ vi aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ cat aaa.txt
111
222

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git add ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git commit -m "111 222" ./

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

②创建test分支

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git branch test

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git log --oneline --all --graph
* 45fa06b (HEAD -> master, test) 111 222

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

③继续使用master分支开发

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git checkout master
Already on 'master'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ vi aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ cat aaa.txt
111aaa
222

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git commit -m "aaa" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git log --oneline --all --graph
* c86283b (HEAD -> master) aaa
* 45fa06b (test) 111 222

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

④切换到test分支,继续开发

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git checkout test
Switched to branch 'test'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test)
$ vi aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test)
$ cat aaa.txt
111
222bbb

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test)
$ git commit -m "bbb" ./
[test e61df5a] bbb
 1 file changed, 1 insertion(+), 1 deletion(-)

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test)
$ git log --oneline --all --graph
* e61df5a (HEAD -> test) bbb
| * c86283b (master) aaa
|/
* 45fa06b 111 222

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

⑤使用test分支合并master分支(属于典型合并)

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test)
$ git merge master
Auto-merging aaa.txt
CONFLICT (content): Merge conflict in aaa.txt
Automatic merge failed; fix conflicts and then commit the result.

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test|MERGING)
$ cat aaa.txt
<<<<<<< HEAD
111
222bbb
=======
111aaa
222
>>>>>>> master

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test|MERGING)
$ vi aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test|MERGING)
$ cat aaa.txt
111aaa
222bbb

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test|MERGING)
$ git commit -a -m "合并master分支,并解决冲突"
[test 448d619] 合并master分支,并解决冲突

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test)
$ git log --oneline --all --graph
*   448d619 (HEAD -> test) 合并master分支,并解决冲突
|\
| * c86283b (master) aaa
* | e61df5a bbb
|/
* 45fa06b 111 222

  • 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

同样的,如果此时切换回master分支,合并test分支虽然属于快进合并并且不同轴,但合并依旧不会出现冲突,因为test分支的内容是解决冲突并且经过用户确认之后的内容。

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test)
$ git log --oneline --all --graph
*   448d619 (HEAD -> test) 合并master分支,并解决冲突


### 给大家的福利


**零基础入门**


对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。


![](https://img-blog.csdnimg.cn/img_convert/95608e9062782d28f4f04f821405d99a.png)


同时每个成长路线对应的板块都有配套的视频提供:


![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/a91b9e8100834e9291cfcf1695d8cd42.png#pic_center)


因篇幅有限,仅展示部分资料

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化资料的朋友,可以点击这里获取](https://bbs.csdn.net/topics/618540462)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 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
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/790426
推荐阅读
相关标签
  

闽ICP备14008679号