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 分支名,表示强制删除该分支。

相关推荐
Brookty4 小时前
Git 与 GitHub|第一阶段:仓库、版本历史与 Git 对象模型(上篇)
git·github
Kimnol18 小时前
我的第一次 Git 贡献:从 fork 到合并 PR #3130
git
鬼手点金1 天前
消息的四种角色
java·前端·人工智能·git·深度学习
齐 飞2 天前
idea中git误操作撤回git reset --hard ‘HEAD@{1}‘
java·git·intellij-idea
长成一棵参天树2 天前
React15 vs React16 核心区别
git·vscode
驭渊的小故事2 天前
Git 基础操作与对象观察
git
Hvitur2 天前
Gitea 版本控制服务端【Red Hat 离线安装】
git
flytalei2 天前
逐浪笔记 GitOps 实战:Jenkins 构建、Argo CD 同步与 Git 回滚
笔记·git·jenkins
熊出没2 天前
CommitLoom 使用教程:在 IntelliJ IDEA 中自动生成 Git 提交信息
java·git·intellij-idea