当前位置: 首页 > news >正文

分支管理(一):创建、切换与合并,体验“平行宇宙”

1. 问题场景

假设你正在开发一个新功能,预计要花两周时间。在这个过程中,代码每天都处于“半成品”状态——功能没写完,运行不起来,甚至可能把现有功能搞崩。如果你直接在主分支(master)上开发,这些不完整的提交会污染整个项目历史,还可能影响其他同事的工作。但你又需要每天保存进度,不能等两周后才一次性提交。

解决这个矛盾的答案就是分支。你可以在一个独立的分支上自由实验、随时提交,完全不影响主分支的稳定性。等功能开发完成且测试通过,再把分支上的工作合并回主分支。这就像在“平行宇宙”里工作,互不干扰,随时可以汇合。

2. 核心概念

2.1 什么是分支

在 Git 里,分支仅仅是一个指向某个提交对象的可移动指针。创建一个新分支,其实就是创建了一个新的指针,让你可以在当前工作基础上分叉出一条独立的开发线。不同分支上的修改相互隔离,直到你明确将它们合并。

2.2 HEAD 指针

HEAD是一个特殊的指针,它始终指向你当前正在工作的分支(或者说当前分支的最新提交)。当你切换分支时,HEAD也会跟着移动。

2.3 为什么 Git 分支如此轻量

有些老旧的版本控制系统创建分支时需要完整拷贝一份代码,非常缓慢。Git 的分支只包含一个指针和极少量的元数据,创建和切换几乎瞬间完成。这也是 Git 强烈鼓励分支策略的原因——你可以毫无心理负担地为每一个小功能、每一次 Bug 修复新建分支。

3. 核心命令

以下是分支管理最基础的一组命令,先整体列出,后面会逐个演示。

# 查看所有本地分支,当前分支前会有 * 号gitbranch# 创建一个新分支(但不会切换过去)gitbranch<branch_name># 切换到指定分支gitcheckout<branch_name># 创建并切换到新分支(常用组合)gitcheckout-b<branch_name># 将指定分支合并到当前所在分支gitmerge<branch_name># 删除指定分支gitbranch-d<branch_name>

4. 实战演示

继续使用之前的myproject仓库,或者创建一个全新的仓库来练习。假设当前只有 master 分支,上面已经有一些提交记录。

4.1 查看分支

$gitbranch * master

输出显示只有一个master分支,前面的*表示当前HEAD指向它,也就是你正在这个分支上工作。

4.2 创建并切换到新分支

假设你要开发一个支付功能,需要创建一个专门的分支:

$gitcheckout-bfeature-payment Switched to a new branch'feature-payment'

这个命令等价于git branch feature-paymentgit checkout feature-payment,一步到位。再查看一下分支列表:

$gitbranch * feature-payment master

当前分支已经切换到feature-payment

4.3 在新分支上开发和提交

现在开始“开发新功能”。往ReadMe文件里添加一行标记性内容并提交:

$echo"Implement payment module">>ReadMe $gitaddReadMe $gitcommit-m"start payment module development"[feature-payment a2b3c4d]start payment module development1filechanged,1insertion(+)

这个提交记录到了feature-payment分支上,对 master 分支毫无影响。

4.4 切换回 master 分支

现在回到 master 分支看看:

$gitcheckout master Switched to branch'master'

查看ReadMe文件的内容:

$catReadMe# 没有 "Implement payment module" 这一行

新功能分支上的那行内容消失了,因为 master 分支的指针还停留在原来的提交点,没有包含支付分支上的修改。此时git log也看不到那条start payment module development的提交,除非你显式查看feature-payment分支的日志。

4.5 合并分支

支付功能已经开发完成,需要把它合并回主分支。确保你在 master 分支上,然后执行合并:

$gitmerge feature-payment Updating 14c12c3..a2b3c4d Fast-forward ReadMe|1+1filechanged,1insertion(+)

Git 提示采用了Fast-forward模式。这是因为 master 分支在分离之后没有产生新的提交,Git 只需要将 master 的指针直接“快进”到feature-payment指向的提交即可,无需额外的合并提交。合并后 master 分支就包含了支付功能的代码,ReadMe文件里那行内容也回来了。

4.6 删除分支

功能已经合并,feature-payment分支不再需要了,可以删掉以保持分支列表的整洁:

$gitbranch-dfeature-payment Deleted branch feature-payment(was a2b3c4d).

此时git branch只会显示master。注意,被删除的分支只是在本地被移除,如果已经推送到远程仓库,还需要额外的步骤删除远程分支(后面文章会讲)。

5. 分支策略建议

在实际项目中,直接在主分支(master)上开发是大忌。一个常用的策略是:

  • master 分支:始终保持稳定,只用来发布正式版本。任何人不直接在 master 上提交。
  • dev 分支:开发集成分支,日常开发的工作都在这个分支或其衍生分支上进行。
  • 个人功能分支:每个新功能、每个 Bug 修复,都从 dev 分支上拉出一个独立的分支。开发完成后合并回 dev,再删除该功能分支。

这种层级结构让项目历史清晰可追溯,也最大程度降低了多人协作时的冲突概率。

6. 注意事项

  • 分支的创建和切换非常轻量,不要怕多建分支。即使是一个极小的改动,也可以单独建分支,这样如果发现方向不对,直接删掉分支即可,主分支完全不受影响。
  • 在合并分支之前,建议先用git status确认当前处在正确的目标分支(通常是 master 或 dev)。很多人会把方向搞反,把主分支合并到了功能分支上。
  • 如果删除分支时 Git 提示 “the branch is not fully merged”,说明该分支上还有没有被合并到其他分支的提交。Git 是在保护你,防止不小心丢失工作成果。如果确认那些提交确实没用了,可以用git branch -D <branch_name>强制删除。

7. 要点总结

  • 分支是 Git 的核心功能,让你在隔离环境中自由开发,不影响主线。
  • git checkout -b <name>创建并切换分支,是最常用的操作之一。
  • git merge将分支上的工作合并到当前分支,默认采用快进模式。
  • 合并完成且确认不再需要后,应及时用git branch -d删除分支,保持仓库整洁。
  • 养成良好的分支习惯:为每个独立功能或修复都新建一个分支。

8. 练习题

一定要练习,玩起来,你可以随便玩,不需要局限于我举得例子,你想怎么搞就怎么搞,不要害怕搞坏了,只要你不用自己的真实项目,其他的,大不了把git删了重新下,搞起来,只有这样才学的扎实

  1. 在你的learning-git仓库中,创建一个feature-login分支并切换过去。
  2. 在该分支上新建一个login.py文件,写入一些模拟代码,然后addcommit
  3. 切换回 master 分支,确认login.py不存在。然后用git merge feature-login将其合并进来。
  4. 合并成功后,删除feature-login分支。
  5. 尝试创建一个新分支temp并做一次提交,然后不合并就直接用git branch -d temp删除它,观察 Git 的警告信息。再用git branch -D temp强制删除。
  6. (思考题)如果 master 分支在feature-login创建之后又有了新的提交,合并时还会是快进模式吗?试着模拟并观察结果。
http://www.jsqmd.com/news/849013/

相关文章:

  • 告别理论!5分钟用PyWavelets搞定二维离散小波变换(2D-DWT)的Python代码实战
  • 你的电机为什么抖?排查STM32F4 PWM驱动TB6612的5个常见硬件坑(附示波器实测)
  • 告别GDB依赖:在NEMU里打造专属调试器,我是如何搞定单步执行与内存扫描的
  • Rust内存安全:所有权、借用与生命周期深度解析
  • SWAT模型高阶十七项案例分析实践技术
  • 别再用理想模型了!用TINA-TI仿真μA741驱动容性负载,实测振铃现象与消除方案
  • AnyVisLoc:专为低空多视角无人机定位打造的全球首个统一评测基准
  • 如何监控 RabbitMQ 队列长度实现自动告警
  • 别再只会用关键词了!这10个Google搜索命令,让你找资料效率翻倍(附实战案例)
  • 插件:Custom Attachment Location 图片自定义
  • 不用真飞机!用BetaFlight遥控器玩转PX4无人机仿真:QGC配置与手动飞行入门
  • 别再死记硬背物联网四层架构了!用LoRa和ESP32手把手搭个智能花盆,实战理解每一层
  • ARM SPE统计性能分析扩展与缓冲区管理机制详解
  • 告别手动提交!用Bash脚本批量处理VASP+ShengBTE热输运计算的700+任务
  • 视频怎样在线去水印?免费在线视频去水印方法与网站盘点2026
  • 【独家首发】Gemini Ultra未公开API限流机制曝光:3类高频报错代码对应的真实QPS阈值与绕过方案
  • WandEnhancer:免费解锁WeMod高级功能的终极解决方案
  • 手把手教你无损转换:把老电脑的Legacy启动盘改成UEFI+GPT(附DiskGenius详细操作图)
  • Perplexity实时追踪offer状态?不,但你能用它反向验证录取概率——基于3年1,246条真实案例的数据建模法
  • 别再手动对齐了!Fusion360里用‘构造面’和‘对齐’工具,5分钟搞定外壳开孔居中
  • Rust并发编程:线程、通道与锁深度解析
  • 别再让电机‘刹不住车’:用ADRC的TD模块实现位置精准无超调控制(附STM32代码)
  • RIS辅助的模拟Air-ODE网络技术解析与应用
  • 蓝桥杯EDA国赛备赛避坑:从省赛PCB翻车案例,聊聊封装绑定与布局走线的那些细节
  • ARM Cortex-M软件浮点编译配置与实践
  • 国产高性能MCU如何破局?拆解先楫半导体RISC-V芯片的落地逻辑
  • Java程序员转行大模型开发:后端开发轻松转型大模型应用开发,
  • 告别轮询!用STM32F407的串口空闲中断+DMA,让你的串口通信效率翻倍(标准库实战)
  • ChromaControl终极指南:如何用一款软件统一控制所有RGB设备灯光效果
  • 拓璞数控明日上市:募资17亿港元 暗盘大涨51% 公司市值163亿港元