热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

git深入理解(九):git分支管理与应用

此处以github平台为例。branch查看分支的情况,前面带*号的就是当前分支gitbranch创建分支gitbranch分支名删除分支gitbranch-

此处以github平台为例。

branch

查看分支的情况,前面带*号的就是当前分支
git branch

创建分支
git branch 分支名

删除分支
git branch -d 分支名

checkout

切换当前分支到指定分支
git checkout 分支名

创建分支并切换到创建的分支
git checkout -b 分支名

merge

合并某分支的内容到当前分支
git merge 分支名

如果两个分支同时进行了同一个文件的修改和提交,在merge时就会产生冲突,首先要手动打开文件解决冲突,再提交。

查看分支合并图
git log --graph

红色和绿色的虚线分别代表两个分支。

git merge 的原理:
我们知道分支文件中存储的是当前分支的最新一次提交的commitID,也就是版本号,而每一个版本号对应的 objects 文件中都存储着 parent 版本号(首次提交没有 parent),以此将版本串起来,每一个分支都有自己的串。

比如将分支A合并到分支B,其实就意味着使分支B和分支A的内容完全一致,那么要达到这个目的最快的方式就是将分支A中的最新的commitID复制到分支B的文件中,这样分支B也就拥有了分支A的串,就达到了合并的效果。

如果在合并的时候出现了冲突,需要手动编辑解决冲突,然后提交一个commit,但是分支A上还是之前的内容。

创建 b2 分支
git checkout -b b2
修改 t1.txt 文件,并提交回到 master 分支,修改 t1.txt,并提交分别查看 log
$ git log -3 --pretty=oneline
2a09fbe5794df384dab0cf0a95751a969a5ae057 (HEAD -> master) yy
4052f8d1f053d8b486673b5e1c79c3720ff2316f del
0d3d0d430b2fb9f5788cde925319f718eaddd61d add$ git log b2 -3 --pretty=oneline
837a61a1e32de4bf25ced7ff6b8dc2820968100c (b2) xx
4052f8d1f053d8b486673b5e1c79c3720ff2316f del
0d3d0d430b2fb9f5788cde925319f718eaddd61d add可见是在 4052f8d1f053d8b486673b5e1c79c3720ff2316f 时产生的分支,之后各自有一个提交。试图将 b2 合并到 master
$ git merge b2
Auto-merging t1.txt
CONFLICT (content): Merge conflict in t1.txt
Automatic merge failed; fix conflicts and then commit the result.手动修复 master 冲突文件,然后提交
$ git add .
$ git commit -m 'fix'
[master 19bf978] fix再次查看 log
$ git log -3 --pretty=oneline
19bf97852267733011f5f4bf5793d4a22224f71b (HEAD -> master) fix
2a09fbe5794df384dab0cf0a95751a969a5ae057 yy
837a61a1e32de4bf25ced7ff6b8dc2820968100c (b2) xx$ git log b2 -3 --pretty=oneline
837a61a1e32de4bf25ced7ff6b8dc2820968100c (b2) xx
4052f8d1f053d8b486673b5e1c79c3720ff2316f del
0d3d0d430b2fb9f5788cde925319f718eaddd61d add可以看到分支 b2 并没有什么变化,而分支 master 变化较大,首先 b2 的 837a61a1e3 插入到了 master 的 2a09fbe579 的前面去了
(那是因为 b2 比 master 先提交的);其次 master 多出了一个新提交 19bf978522。此时,对于 b2,如果不需要了则可以删掉这个本地分支;如果还有用那么就应该使 b2 同步,防止以后出现差错。
$ git checkout b2
$ git merge master
Updating 837a61a..19bf978
Fast-forwardt1.txt | 2 +-1 file changed, 1 insertion(+), 1 deletion(-)将 master 同步到 b2,并不会有冲突发生,那是因为 master 最新的提交晚于 b2 最新的提交,Git 认为可以直接覆盖。所以,当你准备
将“早期”代码合并到“晚期”代码中时才可能出现冲突,反之则不会。最后再查看一次 log
$ git log master -6 --pretty=oneline
19bf97852267733011f5f4bf5793d4a22224f71b (HEAD -> b2, master) fix
2a09fbe5794df384dab0cf0a95751a969a5ae057 yy
837a61a1e32de4bf25ced7ff6b8dc2820968100c xx
4052f8d1f053d8b486673b5e1c79c3720ff2316f del
0d3d0d430b2fb9f5788cde925319f718eaddd61d add
71243b890c66751d8b32d547f0a0f6150775903c rm$ git log b2 -6 --pretty=oneline
19bf97852267733011f5f4bf5793d4a22224f71b (HEAD -> b2, master) fix
2a09fbe5794df384dab0cf0a95751a969a5ae057 yy
837a61a1e32de4bf25ced7ff6b8dc2820968100c xx
4052f8d1f053d8b486673b5e1c79c3720ff2316f del
0d3d0d430b2fb9f5788cde925319f718eaddd61d add
71243b890c66751d8b32d547f0a0f6150775903c rm

默认情况下Git会使用Fast-forward的方式来merge,这样的好处是快,当然也有不好的地方,比如

$ git log master -5 --pretty=oneline
f3e1527aa1b7a44d4a34efcd15cbe48f3148ed1e (HEAD -> master) qqq
4a573a96f86a404fe22745ffd71c5341f636438d (b5) 555
fd0ef1ad99851b0871b6544eab1c5dd051c63882 444
069ec4544846898724d7c8cf8de6f8e0dcaaf408 merge from b3
31d8a05af468dc14dd5d1cfbdd8e8b6ca3b3db0b 333现在你可以清楚的看到 555 是从 b5 merge 来的,但是如果我把 b5 分支删掉了
$ git branch -d b5
Deleted branch b5 (was 4a573a9).再次查看,你就不知道 555 是来自 merge,因此 fast-forward 模式会丢掉分支信息。
$ git log master -5 --pretty=oneline
f3e1527aa1b7a44d4a34efcd15cbe48f3148ed1e (HEAD -> master) qqq
4a573a96f86a404fe22745ffd71c5341f636438d 555
fd0ef1ad99851b0871b6544eab1c5dd051c63882 444
069ec4544846898724d7c8cf8de6f8e0dcaaf408 merge from b3
31d8a05af468dc14dd5d1cfbdd8e8b6ca3b3db0b 333鉴于此,在 merge 的时候加上 --no-ff 参数即可避免掉这个问题,他会产生一个新的commit。
$ git merge --no-ff b3 -m 'merge from b3'

操作示例

当前目录有 aaa.txt, bbb.txt ,且是干净状态。
当前为master分支。

创建分支
git branch test-branch

切换分支
git checkout test-branch

当前目录具有和master分支一样的结构,可见 test-branch 分支会继承当时创建它的分支的状态。

编辑文件
vi ccc.txt
提交
git add .
git commit -m ‘add ccc’
该分支第一次提交
git push -u origin test-branch
在Gitlab服务器查看我们推送的分支,它会自动创建分支 test-branch

此时 test-branch 分支有ccc.txt文件,而master分支是没有的。

切换到master
git checkout master

目录下没有ccc.txt文件。

合并 test-branch 分支到master分支,首先要pull到最新版本。
git pull origin master
git merge test-branch
git push origin master
在Gitlab服务器查看master

删除所创建的分支
git push origin --delete test-branch
git branch
发现 test-branch 依然存在本地,而远程仓库不存在此分支了。
git branch -d test-branch
git branch
发现 test-branch 已经不存在了

可见git的多分支是共用一个working copy,当前是那个分支就显示那个分支的内容。

push到线上

将新建的分支以及分支代码提交到线上,第一次Push的时候,需要将本地分支和远端origin绑定,使用it push origin test_branch -u,这样远端会新建一个分支并接受此次提交。后面再提交就只需要git push即可

测试合并冲突

git branch test-branch
git checkout test-branch
git push -u origin test-branch
修改ccc.txt文件
git add .
git commit -m ‘modify ccc 2’
git push origin test-branch
git checkout master
修改ccc.txt文件
git status
git merge test-branch

error: Your local changes to the following files would be overwritten by merge:ccc.txtPlease commit your changes or stash them before you merge.Aborting

显然,如果有改动未提交,是不让merge的。
git add .
git commit -m ‘modify ccc 3’
git merge test-branch

Auto-merging ccc.txtCONFLICT (content): Merge conflict in ccc.txtAutomatic merge failed; fix conflicts and then commit the result

此时test-branch分支已经合并过来了,只是出现了冲突,打开ccc.txt解决冲突内容,然后提交。
git add .
git commit -m ‘resolve conflict’
git push origin master
git status
git log --graph

之前svn解决玩冲突还需要执行resolved命令,而git则不需要,直接提交即可。

多人开发分支设计

master developtestingtask1task2

master 主干,线上处于此分支,有权限控制
develop 过度分支
testing 测试专用分支
task1 任务1
task2 任务1

1、管理员在master分支创建develop,并负责将develop合并到master。

2、开发的时候在develop分支创建task1,在task1中开发,将task1合并到develop,为了减少冲突应经常将develop合并到task1,将task1合并到develop操作。

3、测试的时候去到测试服务器将develop合并到testing。

4、发布的时候去到线上服务器将develop合并到master。

如何修复线上Bug

比如你正在 task1 上开发一个功能,而且开发了一段时间了,这个时候突然线上报出一个bug,你需要立即修复,这个时候应该先保护好现场(使用 git stash 命令),不然切换分支后你的心该滴血了;然后从 master 创建一个分支bug-100,为什么不能从 develop 创建呢?因为在多人开发模式下 develop 分支上经常会有一些暂时不需要同步到 master 上的提交。

修复好之后将分支 bug-100 的提交 merge 到 master (加上 --no-ff 参数),然后发布到线上,删除 bug-100 分支。

总感觉哪里还少了点啥,是的,你的 develop 分支上同样存在这个bug,而且我是在 bug-100 分支上修复的,不是在 task1 分支,所以如果不修复之,日后将 develop 上的提交同步到 master 上的时候是不是会把这个 bug 也带过去了呢?

既然如此,有人会说,这还不简单,将 master 同步到 develop 不就行了。显然不能这么干,因为 develop 上面还有一些提交没有同步到 master ,开头就提到过,这样做将会是一场悲剧。 又有人说了,那我在 develop 分支再重复修复一遍总行吧,这个当然可以。不过 Git 专门提供了一个cherry-pick命令,让我们能复制一个特定的提交到当前分支:git cherry-pick commitID并且 Git 会替当前分支做一次提交。

此时就可以回到 task1 分支上,恢复之前保存的现场,并且要从 develop 同步一次,然后接着开发了。

关于 git stash 命令可以参考 https://blog.csdn.net/raoxiaoya/article/details/111456361


推荐阅读
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • YOLOv7基于自己的数据集从零构建模型完整训练、推理计算超详细教程
    本文介绍了关于人工智能、神经网络和深度学习的知识点,并提供了YOLOv7基于自己的数据集从零构建模型完整训练、推理计算的详细教程。文章还提到了郑州最低生活保障的话题。对于从事目标检测任务的人来说,YOLO是一个熟悉的模型。文章还提到了yolov4和yolov6的相关内容,以及选择模型的优化思路。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 怀疑是每次都在新建文件,具体代码如下 ... [详细]
author-avatar
Sadness_小妖_619
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有