Git版本控制工具详解(二)https://developer.aliyun.com/article/1470456
(掌握)git分支-创建和切换多个分支和本质
Git master分支
- Git 的分支,其实本质上仅仅是指向提交对象的可变指针。
- Git 的默认分支名字是 master,在多次提交操作之后,你其实已经有一个指向最后那个提交对象的 master 分支
- master 分支会在每次提交时自动移动
- Git 的 master 分支并不是一个特殊分支
- 它就跟其它分支完全没有区别
- 之所以几乎每一个仓库都有 master 分支,是因为 git init 命令默认创建它(现在也可能叫main),并且大多数人都懒得去改动它
Git创建分支
- Git 是怎么创建新分支的呢?
- 很简单,它只是为你创建了一个可以移动的新的指针
- 比如,创建一个 testing 分支, 你需要使用 git branch 命令:
git branch testing//创建名为testing的新分支,但是当前分支没有切换过去
- 那么,Git 又是怎么知道当前在哪一个分支上呢?
- 也很简单,它也是通过一个名为 HEAD 的特殊指针
Git分支提交
- 如果我们指向某一个分支,并且在这个分支上提交:
- 你也可以切换回到master分支,继续开发:
创建分支同时切换
- 创建新分支的同时切换过去
- 通常我们会在创建一个新分支后立即切换过去
- 这可以用 git checkout -b 一条命令搞定
git branch
查看当前所有分支
git checkout -b <newbranchname> //本地分支跟远程仓库分支的名字一样的话,就不需要写本地跟远程两个仓库分支的名字,而是只需要写一个当成两个用就行了 //git checkout 命令用于切换分支或恢复工作区文件,这里用于切换分支。 //-b 参数表示要创建新分支。 //<newbranchname> 是新分支的名称。 //因此,运行 git checkout -b <newbranchname> 命令将会创建一个新的名为 <newbranchname> 的分支,并切换到该分支。如果当前分支上有未提交的更改,Git 会提示你先提交或保存这些更改,然后再创建新分支 //不创建新分支的话,只想单纯切换到已有分支也可以git checkout xxx,xxx是你想切过去的分支
(掌握)Git分支-实际工作中分支的使用演练
为什么需要使用分支呢?
- 让我们来看一个简单的分支新建与分支合并的例子,实际工作中你可能会用到类似的工作流
- 开发某个项目,在默认分支master上进行开发
- 实现项目的功能需求,不断提交
- 并且在一个大的版本完成时,发布版本,打上一个tag v1.0.0
- 继续开发后续的新功能,正在此时,你突然接到一个电话说有个很严重的问题需要紧急修补, 你将按照如下方式来处理:
- 切换到tag v1.0.0的版本,并且创建一个分支hotfix
- 想要新建一个分支并同时切换到那个分支上,你可以运行一个带有 -b 参数的 git checkout 命令:
git checkout –b hotfix //具体来说,git checkout 命令用于切换分支或恢复文件。-b 参数表示创建新分支,而 hotfix 是新分支的名称。因此,该命令的完整含义是创建名为 hotfix 的新分支,并切换到该分支。 //通常,开发人员会创建新分支来修复现有的 bug 或其他问题,以便在不影响主分支(通常是 master 分支)的情况下进行修改。然后,一旦修复完成并进行测试,他们可以将更改合并回主分支。
分支开发和合并
- 分支上开发、修复bug:
- 我们可以在创建的hotfix分支上继续开发工作或者修复bug
- 当完成要做的工作后,重新打上一个新的tag v1.0.1
- 切换回master分支,但是这个时候master分支也需要修复刚刚的bug:
- 所以我们需要将master分支和hotfix分支进行合并
git checkout master//切换到master分支 git merge hotfix//将分支hotfix合并到master
- 合并冲突
- 解决方案1:把冲突的地方删一删,然后重新提交一下
- 解决方案2:注意下图最上方的四个选项
Accept Current Change |
接收master里的代码 |
Accept Incoming Change |
接收合并进来的代码 |
Accept Both Changes |
两个代码都保留下来 |
Compare Changes |
比较两段代码的区别 |
第四个选项比较代码图
查看和删除分支
- 如果我们希望查看当前所有的分支,可以通过以下命令:
git branch # 查看当前所有的分支 git branch –v # 同时查看最后一次提交 git branch --merged # 查看所有合并到当前分支的分支 git branch --no-merged # 查看所有没有合并到当前分支的分支
- 如果某些已经合并的分支我们不再需要了,那么可以将其移除掉:
git branch –d hotfix # 删除当前分支(其实就是移除指针) git branch –D hotfix # 强制删除某一个分支
(理解)Git分支-Git的工作流中常见的分支
Git的工作流(git flow)
- 由于Git上分支的使用的便捷性,产生了很多Git的工作流:
- 也就是说,在整个项目开发周期的不同阶段,你可以同时拥有多个开放的分支
- 你可以定期地把某些主题分支合并入其他分支中
- 比如以下的工作流:
- master作为主分支
- develop作为开发分支,并且有稳定版本时,合并到master分支中
- topic作为某一个主题或者功能或者特性的分支进行开发(不知道能不能做到,单独进行拆分,如果不行就快速移除掉,可以就能够合并),开发完成后合并到develop分支中
比较常见的git flow
(掌握)Git分支-远程分支的使用操作
Git的远程分支
- 远程分支是也是一种分支结构:
- 以 / 的形式命名的
//添加远程仓库 git remote add origin xxxx //建立本地跟远程仓库的关系,通过上游方式 git pull/push 上游分支//使本地master分支去跟远程仓库main分支。这样在我们git merge类似操作的时候,看似操作master,其实是操作上游分支
- 如果我们刚刚clone下来代码,分支的结构如下:
- 如果其他人修改了代码,那么远程分支结构如下:
- 你需要通过fetch来获取最新的远程分支提交信息
远程分支的管理
- 操作一:推送分支到远程
- 当你想要公开分享一个分支时,需要将其推送到有写入权限的远程仓库上
运行 git push <remote> <branch> //例如 git push origin <branch>
- 操作二:跟踪远程分支
- 当克隆一个仓库时,它通常会自动地创建一个跟踪 origin/master 的 master 分支
- 如果你愿意的话可以设置其他的跟踪分支,可以通过运行 git checkout --track /
- 如果你尝试检出的分支 (a) 不存在且 (b) 刚好只有一个名字与之匹配的远程分支,那么 Git 就会为你创建一个跟踪分支
git checkout --track <remote>/<branch> //从远程仓库(remote)检出(checkout)一个新的本地分支(branch)并将其与远程分(remote/<branch>)关联起来 git checkout <branch> //切换到指定的本地分支(branch),并将工作目录和暂存区更新为该分支的最新状态。如果该分支不存在,则会报错。这个命令也可以用于切换到之前创建的与远程分支关联的本地分支
- 操作三:删除远程分支
- 如果某一个远程分支不再使用,我们想要删除掉,可以运行带有 --delete 选项的 git push 命令来删除一个远程分支
git push origin --delete <branch>
(了解)Git分支合并-rebase和merge的区别
Git rebase用法
- 在 Git 中整合来自不同分支的修改主要有两种方法:merge 以及 rebase
- 什么是rebase呢?
- 在上面的图例中,你可以提取在 C4 中引入的补丁和修改,然后在 C3 的基础上应用一次
- 在 Git 中,这种操作就叫做 变基(rebase)
- 你可以使用 rebase 命令将提交到某一分支上的所有修改都移至另一分支上,就好像“重新播放”一样
- rebase这个单词如何理解呢?
- 我们可以将其理解成改变当前分支的base
- 比如在分支experiment上执行rebase master,那么可以改变experiment的base为master
git checkout experiment //作用是将当前工作目录和暂存区切换到名为experiment的本地分支,即切换到experiment分支 git rebase master //作用是将当前分支(即experiment分支)在基于master分支的基础上进行变基(rebase)。具体来说,这个命令会将experiment分支上的提交历史重新应用到master分支的顶部,使得experiment分支的提交历史变得更加线性、整洁
rebase的原理
达成效果前
达成效果后,更加简洁
- rebase是如何工作的呢?
- 它的原理是首先找到这两个分支(即当前分支 experiment、变基操作的目标基底分支 master) 的最近共同祖先 C2
- 然后对比当前分支相对于该祖先的历次提交,提取相应的修改并存为临时文件
- 然后将当前分支指向目标基底 C3
- 最后以此将之前另存为临时文件的修改依序应用
- 我们可以再次执行master上的合并操作:
$ git checkout master $ git merge experiment
rebase和merge的选择
- 开发中对于rebase和merge应该如何选择呢?
- 事实上,rebase和merge是对Git历史的不同处理方法:
- merge用于记录git的所有历史,那么分支的历史错综复杂,也全部记录下来
- rebase用于简化历史记录,将两个分支的历史简化,整个历史更加简洁
- 了解了rebase的底层原理,就可以根据自己的特定场景选择merge或者rebase
- 注意:rebase有一条黄金法则:永远不要在主分支上使用rebase
- 如果在main上面使用rebase,会造成大量的提交历史在main分支中不同
- 而多人开发时,其他人依然在原来的main中,对于提交历史来说会有很大的变化
Git常见命令速查表