Git版本控制工具(二)

三、分支管理

何为分支管理?

就是通过创建、切换、合并不同的分支,让不同开发任务可以在相互隔离的环境中并行进行,最后将代码变化合并到目标分支。

比如:现在公司要求:开发新登录功能、修复线上支付 Bug、开发新的订单模块

如果所有人直接改 master。

会出现问题:

  • 新功能代码和 Bug 修复混在一起
  • 一个功能没完成,不能提交
  • 多人修改容易冲突
  • 线上版本不稳定
    所以引入分支管理,多个任务就可以并行处理了。

1.查看当前版本库的分支和工作分支

命令 :git branch

master前面有一个*,表示当前HEAD指向的分支,为当前的工作分支。

查看远程分支

命令 :git branch -r

查看远程和本地的所有分支:

命令 : git branch -a

查看本地关联的远程分支

命令 :git branch -vv

上图显示,本地的master分支与远程的master分支建立了连接。

本地分支与远程分支建立连接关系(tracking relationship)后,就可以直接使用简短的:git push和git pull,因为在没有建立连接时,Git 不知道:我要把本地分支推到远程哪个分支?

2.分支创建

命令 :git branch 分支名

在.git隐藏文件中也新增了一个分支:

发现新增加的dev分支与master分支执行的commit id一样。这是因为我们是基于最新版本之下创建的分支。

3.切换分支

HEAD所指向的分支就是当前的工作分支,现在要求在dev分支下做开发,所以要分支切换。

命令 :git checkout 分支名

现在我们已切换到了dev分支下了。

我们对README.md文件做一下修改,然后再提交到版本库中。

切换到master分支下,查看README.md文件是否发生了变化。

发现并没有变化,这说明了不同分支之间 能相互的隔离。

创建新分支并切换到该新分支上:

git checkout -b 新分支名

4.合并分支

本质 :就是合并提交(commit),更准确地说,是把一个分支上的提交历史合入当前分支,使当前分支包含另一个分支的提交所带来的代码变化。

命令 :git merge 目标分支

比如:

复制代码
git checkout A
git merge B
#含义:
把 B 合并到 A

分支合并的三种情况:

1)情况一:

基于master分支创建了dev分支,在dev分支上修改并提交代码后,回到master分支上,合并dev分支。

合并时,可以看到是fast forward模式,即master 直接移动到 dev 的最新提交,结果就是master和dev分支指向了同一个commit id。

2)情况二:(不产生冲突)

基于master分支创建了dev分支,在dev分支上修改并提交代码后,master分支也修改并提交了代码,但是两分支修改的是不同的地方的代码 (即不会产生冲突),回到master上,合并dev分支。

3)情况三:(产生冲突)

基于master分支创建了dev分支,在dev分支上修改并提交代码后,master分支也修改并提交了代码,**但是两分支修改的地方有重复(即会产生冲突),回到master上,合并dev分支。

5.删除分支

合并分支后,被合并的分支就没用了,使用git branch -d 删除分支名

注意:要删除dev分支,只能切换其他分支下删除,不能在dev分支下,删除dev分支。

6.合并冲突

产生冲突的原因:

Git 在合并两个分支时,发现同一个文件的同一范围内容被两个分支分别修改,并且无法自动判断应该保留哪个修改。需要开发者手动选择,然后 add + commit 完成合并。

产生冲突的条件:

口诀:同文件 + 同区域 + 两边改 + Git无法判断

  • 修改同一个文件

  • 修改同一位置附近(同一行修改)

  • 两个分支都做修改

  • git无法判断该留那一部分
    Git冲突不是看有没有修改同一句话,而是看两个分支的修改范围是否产生重叠。
    案例 :
    原本README.md文件中的内容。

    在master分支修改README.md文件,并提交:

    在dev分支修改README.md文件,并提交:

    在master分支下合并dev分支:

    合并分支在README.md文件中发生冲突。查看README.md文件。

    需要手动编辑,决定保留的部分,然后删除这些标记。

    <<<<<<< HEAD

    =======

    dev

然后需要git add ,git commit提交到版本库中,冲突才算解决。

合并冲突时的状态:

以图形结构查看提交历史

使用git log --graph --abbrev-commit也可以把Git提交历史 + 分支关系 + 合并关系 用字符画出来。

  • --abbrev-commit 的作用:显示短版本 commit id
  • --graph 的作用:用 ASCII 字符画出 Git 提交分支图
为该命令设置别名,方便调用:
shell 复制代码
git config --global alias.lg "log --graph --abbrev-commit --oneline"

以后执行git lg,就等价于执行git log --graph --abbrev-commit --oneline

7.合并模式

1)fast forword 快速合并模式:

fast forword模式,看不出来最新一次的提交到底是merge进来的,还是正常提交的。

上图中master分支实际上merge了dev分支,但是在图形结构提交历史图中只能看出此时master和dev分支指向了同一次提交,不能看出是否发生了merge操作。

2)no fast forward模式(只要涉及到merge,建议加上--no-ff):

使用 --no-ff 强制禁用快进模式合并,Git 会生成一个新的 commit,这样从历史上就能看出来最新一次的提交到底是merge进来的,还是正常提交的。

如果想使用这种模式:需要在git merge时,加上--no-ff -m "合并描述信息"

shell 复制代码
git merge --no-ff -m "m描述信息" 合并分支

注 :合并冲突默认就是no fast forward 模式,因为能从结构提交图清晰的看出发生了合并。

示例 :

在dev修改README.md文件,并进行一次提交,然后切回到master分支下,使用no fast forward模式合并dev分支。

能从上图看出dev分支先提交了一次代码,然后master分支与dev分支发生了合并。此时HEAD执行的是master分支最新一次合并提交,dev指向的还是自己的提交。

8.使用分支的策略(工作中常用)

master主分支是稳定的,上面的代码是运行在线上的,比如发布的APP和网站等,所以不能在master分支上直接提交代码。

我们日常开发是在dev分支上,dev分支上的代码需要经过严格的测试,最终才能合并到master分支上。

1)情况一:master分支出现Bug的解决办法?

在dev分支下开发代码,dev分支是基于master分支创建的,此时master分支下出现了bug,如何解决bug还能保证开发的正常进行?

解决方式一:

可以先将开发的代码提交到版本库,再在master的最新一次提交下创建一个fix_bug分支修复bug,修复完bug后,master分支与fix_bug分支合并,解决了BUG,然后切换到dev分支下,继续开发代码,最后开发完成,由于dev分支下还存在BUG,所以先在dev分支下与master分支合并,解决完代码冲突后,再切回到master分支下,合并dev分支。最终代码开发完成,bug也修复了。

解决方式二:

在master分支发现BUG时,dev分支并没有提交代码,而是将开发的代码存到了缓存区,在解决完bug后,在回到dev分支,将之前开发的代码恢复,然后继续进行后面的开发,最后开发完成,由于dev分支下还存在BUG,所以先在dev分支下与master分支合并,解决完代码冲突后,再切回到master分支下,合并dev分支。最终代码开发完成,bug也修复了。

代码提交至缓存的命令 :git stash

  • 注意 :git stash 默认只保存已经被 Git 跟踪的文件修改;如果需要保存新创建但未提交的文件,需要使用 git stash -u;如果连 .gitignore 忽略的文件也需要保存,则使用 git stash -a。
  • 什么是跟踪(tracked) 文件 :曾经执行过 git add 并提交到版本库的文件。
  • 什么是未跟踪(untracked) 文件 :从来没有被添加到版本库。
    从缓存区恢复代码到工作区 :git stash -pop
    为什么需要将代码先保存到缓存区 ?
    dev 分支未提交的修改虽然被 Git 跟踪,但仍属于工作区状态。如果直接切换分支,这些修改可能污染 master 分支,甚至导致提交时把两个任务的代码一起提交。stash 的作用是暂时把未完成代码移走,让修复 bug 的分支保持干净。

9.强制删除分支

如果我们新创建了一个分支,在分支上提交了代码,但是没有与其他分支合并 ,如果此时使用git branch -d 分支名,删除该分支,git是不允许,因为git认为,你既然创建了分支,也进行了代码提交,就是有用的,不能随便删除。如果你确实想删除,git也提供了命令:git branch -D 分支名,表示强制删除该分支。

相关推荐
YIN_尹2 小时前
【git原理与使用】git基本操作及底层原理(二)
大数据·git·elasticsearch
程序员爱德华7 小时前
Git 命令
git
Cry丶21 小时前
Git Rebase 操作备忘
git·rebase
你叶不叶1 天前
abap git 如何从 gitee上在线拉取数据(上一步已经配置好证书)
git·gitee·sap·abapgit
kuroomi2 天前
Git入门
git·kubernetes
daliucheng2 天前
lazygit 上手:日常 git 操作一篇讲完
git
codigger2 天前
大厂git提交规范
git·程序员
挖掘狂人2 天前
六条分支,一条主干:我的 Git 分支管理心得
git·后端·程序员
Brookty2 天前
Git与GitHub系统学习|本地Git工作模型:终端与进程、CWD、HEAD/Index/工作树及Git对象
git·github
2301_767113983 天前
点过“不再询问”就要检查:Claude Code权限文件也可能存着密钥
git·信息安全·claude code