Git学习笔记(三) - 分支管理

本文深入浅出地介绍了Git的分支管理,包括分支的概念、创建与切换分支的方法、合并分支的过程及解决冲突的技巧,旨在帮助读者理解并掌握Git分支管理的核心技能。

几乎每种VCS(Version Control System)都提供各自不同的分支方案。分支可以让你暂时离开主线,进行你自己的试验性工作而不会扰乱开发。Git的分支操作是Git和其他VCS相比的杀手锏,既方便又快捷,Git所倡导的工作方式是经常创建和合并分支,甚至一天几次都不为过。


什么是分支

要想真正理解Git是如何分支的,我们有必要回顾Git如何存储数据。
Git以快照(snapshot)的形式存储数据,而不记录改变或差异。每当你commit时,Git就存储一个commit对象,这个对象包含一个指针,而这个指针指向staged状态下的改变

所谓staged状态,就是执行git add之后的状态。

另外,commit对象还包含作者的名字和邮箱、commit message,以及指向父commit的指针

所谓父commit,就是你所修改的版本。
* 首次commit没有父commit;
* 普通的commit只有一个父commit,也就是上一个commit;
* 对于merge之后的commit,有多个父commit。

假设我们新建了一个本地repo,写了三个新文件READMEtest.rbLICENSE,添加并提交这三个文件。

$ git add README test.rb LICENSE
$ git commit -m 'initial commit of my project'

Git会构建如下的数据结构
这里写图片描述

图片中出现了三种对象,我按照自底向上的思路来分别解释这三种对象:
1. blob对象:代表一个普通文件,上面5b1d3的字样是它的SHA-1码,是一个blob对象的唯一ID。
2. tree对象:代表一个目录,有自己的ID,同时也存储了下属blob和tree的ID。
3. commit对象:代表一次commit,有自己的ID,同时存储了根节点的ID等信息。而这个根节点所形成的树形结构就是刚才说的快照(snapshot)

多个commit对象会形成一张链表。
这里写图片描述

分支就是这张链表上的一个指针。每次提交代码都会在指针后面插入新的commit对象,并移动到新插入的对象
这里写图片描述
每个Git项目有一个默认的分支master


如何创建分支

创建一个新分支就是在刚才的链表上创建一个新指针。假设创建一个名为testing的分支

$ git branch testing

这个命令创建一个指向当前版本的新指针。
这里写图片描述

问题来了,Git怎么知道你当前所在的commit是哪个?原来,Git还维护一个HEAD指针,指向当前所在的branch指针。
这里写图片描述


如何切换分支

切换分支在Git中的术语叫checkout。熟悉SVN的同学会认为这和svn switch比较像。

$ git checkout testing

这个命令会做两件事:
* 将HEAD指针切换到testing分支
* 将工作目录的内容整体替换为testing分支所指的commit对象。
这里写图片描述

切换分支以后,你的commit就提交在testing分支而不是master分支了(假设你切换之前在master)。
这里写图片描述

再用git checkout master切换回master,让你的HEAD指针回到master分支,
这里写图片描述

并做一个commit,如此一来,f30ab就有了两个“下游commit”。
这里写图片描述


合并分支(一) 处理bug分支

合并分支在Git中叫做merge。毕竟,做项目的时候搞出那么多侧重点不同的branches,最终总要合并的。
试想,你在工作的时候接到PM的通知,有一个紧急bug需要修复,那么你需要做:
1. 暂存:暂存(stash)当前分支的更改。
2. 修改:在生产分支(主分支或者feature分支)上创建并切换到hotfix分支,在hotfix分支上改bug。
3. 提交:hotfix通过测试之后,提交hotfix分支。
4. 合并:合并hotfix分支并推送到远程repo。
3. 还原:切换到自己的branch上面,从暂存区恢复工作。

假设你自己的工作branch叫iss53,生产分支是主分支,你已经在iss53上提交过一个版本,并且还有未提交的更改。

这里写图片描述

首先暂存当前分支的工作,

$ git stash

然后在master分支上创建并切换到hotfix分支,

$ git checkout master
$ git checkout -b hotfix

在hotfix上改完bug、测试成功后,提交hotfix分支。版本树如下。
这里写图片描述

$ git checkout master
$ git merge hotfix

合并分支之后的情况如下。
这里写图片描述

现在可以删除hotfix分支了。之后是否提交到远程repo是自愿的。

$ git branch -d hotfix
$ git push

终于改完了bug,可以回到自己的工作了。

$ git checkout iss53

这个chechout只是切换分支,并没有将你暂存的更改还原回来。你需要用

$ git stash pop

来把暂存区的工作取回来。

关于暂存命令git stash有很多有用的用法。刚才的pop是“取出并删除”。还有一种取出方法是git stash apply,这个是“取出不删除”。
stash命令的详细用法请查看廖雪峰Git教程 - Bug分支

合并分支(二) 合并工作分支

上一个例子中,hotfix分支是master分支的后继(downstream)。合并的结果就是master指针向下移动一个节点。这种情况下merge命令会提示Fast-forward
另外一种情况就是两个分支不构成后继关系,如图
这里写图片描述
假设你要把iss53合并到master上面,由于master和iss53不构成后继关系,Git会帮你创建一个merge commit,这个commit有两个父commit,如图
这里写图片描述

合并分支(三) 处理冲突

假如不同分支的同一个文件的同一部分有不同的改动,就会发生合并冲突(merge conflict)。Git会暂停合并工作,直到你手动处理冲突。

怎么看冲突小结

Git发现合并冲突之后,会在你的工作文件文件里有冲突的地方做一些标志,不过别担心,Git会保留原文件的备份的。这种标志姑且称之为“冲突小结”。一个冲突小结的示例如下

<<<<<<< HEAD: main.cpp
int dfs(char** maze) {
=======
template <class T>
int dfs(T** maze) {
>>>>>>> wenke: main.cpp

夹在 <<<<<<<======= 之间的代码是HEAD版本中main.cpp的代码,而=======>>>>>>> 之间的是wenke分支的main.cpp的代码。一种解决方法就是修改HEAD/main.cpp,根据需要选取二者之一的内容,把整个冲突小结替换掉。这回再merge就不会有冲突了。


后记

浏览了几本Git教材,如《Git in Practice》、《Version Control with Git》、《Pro Git》等,发现《Pro Git》是最对我胃口的。它用简洁的图例、深入浅出地讲解了Git的原理,使你具备举一反三地使用Git的能力;第二本秉承了Oreilly家族一贯的风格,很严谨,很学究气,因此不适合初学,而适合给熟练工对抗遗忘;第一本起名很吸引人,但是结构略显散乱,一共涉及六十多个Git技巧,可以给熟练工看一看,补充一下自己没想到的用法。
本文内容不全是《Pro Git》的原文,部分掺杂了我自己的理解,希望各位大大们不吝赐教。
个人认为,学完了分支管理,就可以上马做项目了。在项目中发现问题,回到书中进行验证,这样才能学到真知。
推荐一个很强的Git博客,就是廖雪峰Git教程,比我不知道高到哪里去了。

<think>好的,用户想要寻找关于Git的学习资料,特别是搭建相关的教程或指南。首先,我需要回顾用户提供的引用内容。 引用[1]提到了Git教程,推荐了Gitee和GitLab,适合国内用户使用,因为GitHub可能有访问速度问题。用户可能需要基础教程和替代平台的信息。引用[2]详细说明了如何在本地搭建Git服务器,包括初始化仓库和客户端上传步骤。用户对搭建自己的Git服务器感兴趣,比如公司内部使用GitLab的情况。 接下来,我需要整理这些信息,分步骤回答。首先,推荐基础学习资料,包括官方文档和中文教程。然后,介绍搭建私有仓库的教程,包括GitLab和Gitea。用户可能还需要了解自建服务器的步骤,比如使用git init --bare创建裸仓库,以及客户端如何连接。此外,可能还需要推荐书籍和视频教程,帮助用户深入学习。 用户的问题可能还涉及如何选择适合自己团队的解决方案,比如GitLab适合企业,而Gitea适合轻量级需求。需要解释不同工具的优缺点。另外,基础操作和进阶资源也需要覆盖,确保用户从入门到进阶都有资料参考。 检查是否有遗漏点,比如权限管理分支策略等高级主题,是否需要提及?根据引用内容,用户主要关注搭建教程,但可能也需要一些进阶资源。因此,在推荐资料时,应包括基础和进阶内容,满足不同层次的需求。 最后,生成相关问题,帮助用户深入探索Git的搭建和使用。例如,如何选择自建Git服务,或者Git仓库的权限管理方法。这些问题能引导用户进一步学习,解决实际操作中可能遇到的问题。</think>以下是关于Git学习资料及搭建教程的整理和推荐,结合引用内容和实际需求: --- ### 一、Git基础学习资料 1. **官方文档** Git官方提供完整的英文文档,涵盖所有基础命令和原理:[Git Book](https://git-scm.com/book/en/v2) *适合系统性学习,但需要一定英语基础。* 2. **中文快速入门教程** - 廖雪峰Git教程:[Git教程](https://www.liaoxuefeng.com/wiki/896043488029600) *从安装到分支管理,内容通俗易懂,适合新手。* - 菜鸟教程Git篇:[Git简明指南](https://www.runoob.com/git/git-tutorial.html) *提供命令速查和基础操作演示。* --- ### 二、Git私有仓库搭建教程 #### 1. **自建Git服务器** - **引用[2]的方法**: 在服务器上执行 `sudo git init --bare sample.git` 创建裸仓库,客户端通过SSH或HTTP协议连接上传代码[^2]。 *适用于小型团队或个人项目,无需复杂配置。* - **详细步骤**: ```bash # 服务器端 mkdir /opt/git && cd /opt/git sudo git init --bare myproject.git chown -R git:git myproject.git # 设置权限 # 客户端 git remote add origin user@server:/opt/git/myproject.git git push origin master ``` #### 2. **企业级解决方案** - **GitLab搭建** - 官方文档:[GitLab Omnibus安装指南](https://docs.gitlab.com/ee/install/) *提供Docker、Linux等多种安装方式,适合企业级代码管理。* - 国内优化方案: *替换Gem源为阿里云镜像以加速安装,解决依赖问题。* - **轻量级替代:Gitea** - 官网教程:[Gitea快速部署](https://docs.gitea.io/en-us/) *单二进制文件部署,资源占用低,适合中小团队[^1]。* #### 3. **国内代码托管平台** - **Gitee(码云)** - 官方教程:[Gitee帮助中心](https://gitee.com/help) *提供Git基础操作、仓库管理及CI/CD集成,访问速度快。* --- ### 、进阶学习资源 1. **分支策略与协作** - 《Pro Git》第5章:[分布式Git工作流](https://git-scm.com/book/en/v2/Distributed-Git-Distributed-Workflows) *深入讲解Git Flow、GitHub Flow等协作模型。* 2. **权限管理** - GitLab权限配置:[Project Members权限说明](https://docs.gitlab.com/ee/user/permissions.html) *细化开发者、维护者角色权限,保障代码安全。* 3. **书籍推荐** -Git权威指南》:全面覆盖Git底层原理和高级技巧。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值