版本控制系统Git学习笔记-Git分支操作

名人榜上天下第一辩
众生芸芸难貌相,海水滔滔难斗量,平凡不是平凡客,世情百态掌握中。
网图,侵删!
天下第三人时期造型。

概述

分支是所有版本控制系统都支持的的功能。可以从主线分离开任务,以进行独立的开发而不形象主线。

一、Git分支简介

1.1 基本概念

Git的分支采用的是指针记录每个文件的快照以及相应的结构信息,而不是直接复制文件,这样的特性决定了Git的分支非常的轻量,几乎可以瞬间创建分支。

Git 的默认分支名字是 master。 在多次提交操作之后,你其实已经有一个指向最后那个提交对象的 master 分支。 master 分支会在每次提交时自动向前移动。

Git 的 master 分支并不是一个特殊分支。 它就跟其它分支完全没有区别。 之所以几乎每一个仓库都有 master 分支,是因为 git init 命令默认创建它,并且大多数人都懒得去改动它。

1.2 创建分支

git branch branchname		# 创建分支,但是不会切换到新的分支
git checkout -b <newbranchname>			# 创建分支,同时切换到新建的分支

(1) 先查看当前的版本信息
先查看下当前分支信息:

D:\Desktops\Test>git log --oneline --decorate		# 查看日志信息
917573c (HEAD -> master) 添加readme					# HEAD缓存指针指向master

(2)创建分支
创建的是分支的指针,不会自动切换到新的分支。
新建的分支会在当前对象的基础上创建一个新指针,并指向当前对象。
在这里插入图片描述

此时标识位置的指针HEAD依然指向当前版本,而不是新的分支上。
在这里插入图片描述

D:\Desktops\Test>git log --oneline --decorate
917573c (HEAD -> master, testbranch) 添加readme		# 有两个分支,HEAD依然指向master

1.3 分支切换

使用checkout可以切换当前分支,每次提交指挥提交到HEAD所在的分支,而不会分支之间是独立的。
通过间的的切换分支和提交动作,可以快速的在不同分支之间切换,然后时机成熟时将分支合并起来。

git checkout <branchname> 		# 切换分支

(1) 使用指令直接切换分支:
在这里插入图片描述

D:\Desktops\Test>git checkout testbranch
Switched to branch 'testbranch'
A       Test1.txt
A       Test2.txt

D:\Desktops\Test>git log --oneline --decorate
917573c (HEAD -> testbranch, master) 添加readme

(2) 提交修改
提交只会提交到当前分支里,其他分支不会变化。
在这里插入图片描述

D:\Desktops\Test>git log --oneline --decorate		# 查看当前分支
917573c (HEAD -> testbranch, master) 添加readme

D:\Desktops\Test>git commit							# 提交资料
[testbranch f60127a] 添加新文件
 2 files changed, 1 insertion(+)
 create mode 100644 Test1.txt
 create mode 100644 Test2.txt

D:\Desktops\Test>git log --oneline --decorate
f60127a (HEAD -> testbranch) 添加新文件		# 新提交分分支
917573c (master) 添加readme					# 旧的分支一人保持旧的快照版本

(3) 切换到master分支,重新提交
切换master分支,重新提交,将会在master当前分支快照的基础上,延伸出先得的一个版本。
在这里插入图片描述
在这里插入图片描述

D:\Desktops\Test>git checkout master					# 切换到master分支
Switched to branch 'master'

D:\Desktops\Test>git log --oneline --decorate --all		# 查看所有分支
f60127a (testbranch) 添加新文件
917573c (HEAD -> master) 添加readme

D:\Desktops\Test>git add TestAdd.txt TestFile.txt		# 添加文件

D:\Desktops\Test>git commit -a -m "另一个提交版本"		# 提交修改
[master ea99183] 另一个提交版本
 2 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 TestAdd.txt
 create mode 100644 TestFile.txt

D:\Desktops\Test>git log --oneline --decorate --all		# 重新查看日志
ea99183 (HEAD -> master) 另一个提交版本					# 当前分支新版本
f60127a (testbranch) 添加新文件							# 另一个分支没有变化
917573c 添加readme											

1.4 删除分支

使用-d参数删除分支。

git branch -d <branchname>		# 删除分支

二、新建和合并分支

2.1 工作流程示意图

在这里插入图片描述

  1. 开发软件时有一个新需求1,那就在原来的基础上新建一个“新分支1”进行修改;
  2. 新需求1还没有改完的时候,来个个新需求2,要求先改新需求2;
  3. 这个时候就可以根据新需求2先新建一个分支“新分支2”进行修改,修改完之后合并到主分支上;
  4. 然后可以切换到新分支1上继续完成修改;
  5. 修改完成后再合并到主分支上;
  6. 这样就可以再各个分支上进行切换,而不会影响到各自的操作;

2.2 新建分支

使用-b参数可以新建分支的时候直接切换到新分支。

git checkout -b <branchname>  # 新建分支,同时切换到新的分支

2.3 合并分支

合并分支是以当前分支未主分支,然后把要合并的分支合并到当前分支中,也就是合并时将其他分支合并到HEAD执行的分支中。

$ git checkout master
$ git merge <branchname>

2.4 分支示例

2.4.1 当前除了主分支,再次创建了两个分支

D:\Desktops\Test>git log --oneline --decorate --all
7582919 (HEAD -> test1) add test1.txt
ea99183 (master) 另一个提交版本
f60127a (testbranch) 添加新文件
917573c 添加readme

在这里插入图片描述

  • 提交后再master的基础上,创建了2个分支test1和testbranch;
  • 然后2个分支各自有重新提交了一个版本;
  • 限制的HEAD执行test1分支;

2.4.2 先合并test1分支

这个分支是在master基础上修改的分支,操作就是快进(Fast-forward)master分支到最新版本。

注:

  • 被合并的分支来源于主分支时,会将主分支的指针往前移。
  • 没有创建新的快照版本。
D:\Desktops\Test>git checkout master		# 切换到主分支
Switched to branch 'master'

D:\Desktops\Test>git merge test1			# 合并test1分支
Updating ea99183..7582919
Fast-forward
 test1.txt | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 test1.txt

D:\Desktops\Test>git log --oneline --decorate --all		# 查看分支
7582919 (HEAD -> master, test1) add test1.txt			# 合并了分支,两个分支都还存在
ea99183 另一个提交版本
f60127a (testbranch) 添加新文件
917573c 添加readme

在这里插入图片描述
删除被合并的分支。
注意,如果分支未合并将无法删除。

D:\Desktops\Test>git branch -d test1		# 删除被合并的分支
Deleted branch test1 (was 7582919).

D:\Desktops\Test>git log --oneline --decorate --all
7582919 (HEAD -> master) add test1.txt
ea99183 另一个提交版本
f60127a (testbranch) 添加新文件
917573c 添加readme

在这里插入图片描述

2.4.3 合并testbranch分支

合并testbranch分支,由于两个分支不是延续的,所有会创建一个新的版本在主分支。
新的版本分支只在master分支上。

D:\Desktops\Test>git merge testbranch
Merge made by the 'ort' strategy.
 Test1.txt | 1 +
 Test2.txt | 0
 2 files changed, 1 insertion(+)
 create mode 100644 Test1.txt
 create mode 100644 Test2.txt

D:\Desktops\Test>git log --oneline --decorate --graph --all
 *   bc352f3 (HEAD -> master) Merge branch 'testbranch'
|\
| * f60127a (testbranch) 添加新文件
 * | 7582919 add test1.txt
 * | ea99183 另一个提交版本
|/
 * 917573c 添加readme

在这里插入图片描述

2.5 解决合并时的冲突

合并时有文件冲突是会停止合并,然后将文件标记为冲突。

  • 可以通过手动修改冲突文件,然后用add指令将文件修改为已解决冲突。
  • 也可以通过git mergetool指令调用默认的冲突解决工具修改差异解决冲突。

(1) test1分支修改test1.txt文件

D:\Desktops\Test>git branch test1		# 创建到test1分支

D:\Desktops\Test>git checkout test1		# 切换到test1分支
Switched to branch 'test1'
M       test1.txt

D:\Desktops\Test>git commit -a -m "修改test1文件"	# 修改test1文件,然后提交
[test1 01b290b] 修改test1文件
 1 file changed, 1 insertion(+)

D:\Desktops\Test>git log --oneline --decorate --graph --all		# 查看分支
* 01b290b (HEAD -> test1) 修改test1文件
*   bc352f3 (master) Merge branch 'testbranch'
|\
| * f60127a (testbranch) 添加新文件
* | 7582919 add test1.txt
* | ea99183 另一个提交版本
|/
* 917573c 添加readme

(2) master分支修改test1.txt文件

D:\Desktops\Test>git checkout master
Switched to branch 'master'
M       Test1.txt

D:\Desktops\Test>git commit -a -m "修改test1文件"
[master f2c82e1] 修改test1文件
 1 file changed, 1 insertion(+)

D:\Desktops\Test>git log --oneline --decorate --graph --all
* f2c82e1 (HEAD -> master) 修改test1文件
| * 01b290b (test1) 修改test1文件
|/
*   bc352f3 Merge branch 'testbranch'
|\
| * f60127a (testbranch) 添加新文件
* | 7582919 add test1.txt
* | ea99183 另一个提交版本
|/
* 917573c 添加readme

(3) 合并有分歧的两个分支

D:\Desktops\Test>git merge test1
Auto-merging test1.txt
CONFLICT (content): Merge conflict in test1.txt
Automatic merge failed; fix conflicts and then commit the result.

此时提示了合并冲突的文件名字。

(4) 使用“git mergetool”指令解决冲突

D:\Desktops\Test>git mergetool		# 使用默认工具解决冲突

This message is displayed because 'merge.tool' is not configured.
See 'git mergetool --tool-help' or 'git help config' for more details.
'git mergetool' will now attempt to use one of the following tools:
tortoisemerge emerge vimdiff nvimdiff
Merging:
test1.txt

Normal merge conflict for 'test1.txt':
  {local}: modified file
  {remote}: modified file
Hit return to start merge resolution tool (tortoisemerge): local # 选择解决方式

一下是弹出的对比工具的界面,下方是解决冲突后的文件内容。
在这里插入图片描述
保存退出后,重新提交(git commit)就可以完成合并了。

D:\Desktops\Test>git merge test1
fatal: You have not concluded your merge (MERGE_HEAD exists).
Please, commit your changes before you merge.

D:\Desktops\Test>git commit
[master a71a2a7] Merge branch 'test1'

D:\Desktops\Test>git merge test1		# 再次执行合并指令会提示已经全部更新。
Already up to date.

D:\Desktops\Test>git log --oneline --decorate --graph --all		# 查看分支装填显示已合并。
*   a71a2a7 (HEAD -> master) Merge branch 'test1'	
|\
| * 01b290b (test1) 修改test1文件
* | f2c82e1 修改test1文件
|/
*   bc352f3 Merge branch 'testbranch'
|\
| * f60127a (testbranch) 添加新文件
* | 7582919 add test1.txt
* | ea99183 另一个提交版本
|/
* 917573c 添加readme

三、分支管理

注: 下文示例分支状态见2.5

3.1 查看所有分支列表

git branch	# 不添加任何参数表示查看说有分支列表

示例:

D:\Desktops\Test>git branch
* master
  test1
  testbranch

“*” 字符:它代表现在检出的那一个分支(也就是说,当前 HEAD 指针所指向的分支)

3.2 查看每一个分支的最后一次提交

git branch -v

示例:

D:\Desktops\Test>git branch -v
* master     a71a2a7 Merge branch 'test1'
  test1      01b290b 修改test1文件
  testbranch f60127a 添加新文件

3.3 查看已经合并或尚未合并到当前分支的分支

git branch --merged		# 已合并到当前分支的分支
git branch --no-merged	# 未合并到当前分支的分支

示例:

D:\Desktops\Test>git branch --merge
* master
  test1
  testbranch

D:\Desktops\Test>git branch --no-merge

D:\Desktops\Test>

四、远程分支

远程引用是对远程仓库的引用(指针),包括分支、标签等等。

4.1 获取远程分支

git ls-remote <remote> 		# 显式地获得远程引用的完整列表
git remote show <remote> 	# 获得远程分支的更多信息
使用远程跟踪分支来看远程分支。

远程跟踪分支以<remote>/<branch> 的形式命名。

注: 所有的操作均在本地,只要不推送到远程分支或者拉取远程分支,那远程跟踪分支将不会更新。

4.2 推送

git push 									# 直接推动当前分支
git push <remote> <branch>					# 将本地分支推送到远程同名分支上
git push <remote> <branch>:<remotebranch>	# 将本地分支推送到远程指定分支上
D:\Desktops\TestClone\Clone2>git push
Enumerating objects: 7, done.
Counting objects: 100% (7/7), done.
Delta compression using up to 4 threads
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 579 bytes | 579.00 KiB/s, done.
Total 5 (delta 3), reused 0 (delta 0), pack-reused 0
To D:/Desktops/Test/.git/
   57a41ad..4ecf733  master -> master

4.3 跟踪远程分支

git checkout --track origin/branch		# 跟踪远程分支
git checkout <branchname>				# 当本地分支和远程分支有唯一一个匹配的分支时,会自动跟踪
git checkout -b <branch> <remote>/<branch>		# 指定本地分支和远程分支,两个分支名可以不一样
git branch -u <remote>/<branch>					# 设置本地分支跟踪刚刚拉取下来的远程分支
git branch -vv							# 查看所有的跟踪分支

4.4 拉取

git fetch		# 从服务器上抓取本地没有的数据时,它并不会修改工作目录中的内容
git pull		# 大多数情况下它的含义是一个 git fetch 紧接着一个 git merge 命令

注: git pull 的自动合并经常令人困惑,所以通常单独显式地使用 fetch 与 merge 命令会更好一些。

4.5 删除远程分支

使用–delete配合push可以删除远程分支(移除指针)。

git push <remote> --delete <branch>

五、变基(rebase)

用 rebase 命令将提交到某一分支上的所有修改都移至另一分支上,就好像“重新播放”一样。

git checkout <branch>					# 检出分支
git rebase <newbranch>				# 将当前分支变基到另一个分支上
git rebase --onto master server client		# 选中在 client 分支里但不在 server 分支里的修改(即 C8 和 C9),将它们在 master 分支上重放
git rebase <basebranch> <topicbranch> 		# 直接将topicbranch分支 变基到basebranch分支上。 这样做能省去你先切换到 server 分支,再对其执行变基命令的多个步骤。

合并和变基两种整合方法的最终结果没有任何区别,但是变基使得提交历史更加整洁。

注:

  • 如果提交存在于你的仓库之外,而别人可能基于这些提交进行开发,那么不要执行变基;
  • 变基操作的实质是丢弃一些现有的提交,然后相应地新建一些内容一样但实际上不同的提交。

如果你已经将提交推送至某个仓库,而其他人也已经从该仓库拉取提交并进行了后续工作,此时,如果你用 git rebase 命令重新整理了提交并再次推送,你的同伴因此将不得不再次将他们手头的工作与你的提交进行整合,如果接下来你还要拉取并整合他们修改过的提交,事情就会变得一团糟。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鱼听禅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值