Git是目前最流行的分布式版本控制系统,几乎是程序员的必备技能。很多人只会用Git的基本命令(add、commit、push、pull),但是对Git的分支管理和工作流却不太了解。掌握Git的分支管理和工作流,能让我们的团队协作更加高效,代码管理更加规范。今天就来分享Git的进阶教程,重点讲解分支管理和常见的工作流。

Git分支基础

分支是Git最强大的功能之一。Git的分支非常轻量,创建和切换分支几乎是瞬间完成的。这使得Git鼓励开发者频繁使用分支进行开发。

1. 查看分支

# 查看本地分支
git branch

# 查看所有分支(包括远程分支)
git branch -a

# 查看分支的最后一次提交
git branch -v

2. 创建分支

# 创建新分支
git branch feature/login

# 创建并切换到新分支
git checkout -b feature/login

# Git 2.23+ 推荐使用switch
git switch -c feature/login

3. 切换分支

# 切换到指定分支
git checkout feature/login

# Git 2.23+ 推荐使用switch
git switch feature/login

# 切换到上一个分支
git checkout -
git switch -

4. 合并分支

# 切换到主分支
git checkout master

# 合并指定分支到当前分支
git merge feature/login

# 合并时禁用快进,生成合并提交
git merge --no-ff feature/login

5. 删除分支

# 删除已合并的本地分支
git branch -d feature/login

# 强制删除本地分支(未合并也删除)
git branch -D feature/login

# 删除远程分支
git push origin --delete feature/login

分支合并详解

Git有两种合并方式:快进合并(Fast-forward)和三方合并(Three-way merge)。

1. 快进合并: 当主分支没有新的提交,而特性分支有新的提交时,合并时Git只是将主分支的指针移动到特性分支的最新提交,这就是快进合并。这种合并不会产生新的提交记录。

git checkout master
git merge feature/login
# Fast-forward

2. 三方合并: 当主分支和特性分支都有新的提交时,Git会进行三方合并,生成一个新的合并提交。这种合并会保留分支的历史记录。

git checkout master
git merge feature/login
# Merge made by the 'recursive' strategy.

3. 合并冲突: 当两个分支修改了同一个文件的同一部分时,合并会产生冲突。需要手动解决冲突后再提交。

# 合并时产生冲突
git merge feature/login
# Auto-merging app.js
# CONFLICT (content): Merge conflict in app.js
# Automatic merge failed; fix conflicts and then commit the result.

# 查看冲突文件
git status

# 手动编辑冲突文件,解决冲突
# 冲突标记:
# <<<<<<< HEAD
# 当前分支的内容
# =======
# 合并分支的内容
# >>>>>>> feature/login

# 解决冲突后,标记为已解决
git add app.js

# 提交合并
git commit

Rebase(变基)

Rebase是另一种合并分支的方式,它可以将一个分支的提交"重新播放"到另一个分支上,使得提交历史更加线性、整洁。

1. 基本用法

# 切换到特性分支
git checkout feature/login

# 将特性分支变基到主分支
git rebase master

# 变基完成后,切换到主分支,进行快进合并
git checkout master
git merge feature/login

2. 交互式Rebase: 交互式Rebase可以对提交进行编辑、删除、合并、重新排序等操作。

# 交互式Rebase最近3次提交
git rebase -i HEAD~3

# 会打开编辑器,显示提交列表:
# pick 1a2b3c4 commit message 1
# pick 4d5e6f7 commit message 2
# pick 8g9h0i1 commit message 3

# 可以修改pick为其他命令:
# pick:保留该提交
# reword:保留提交,但修改提交信息
# edit:保留提交,但暂停以便修改
# squash:将该提交合并到上一个提交
# fixup:类似squash,但丢弃该提交的信息
# drop:删除该提交

3. Rebase vs Merge

  • Merge:保留完整的提交历史,包括分支和合并记录,历史比较复杂。不会修改已有提交,安全。
  • Rebase:提交历史线性、整洁,但是会修改已有提交的哈希值。只应该在本地分支上使用,不要在共享分支上使用。

黄金法则:不要对已经推送到远程仓库的提交进行Rebase。

常见的Git工作流

1. Git Flow

Git Flow是最经典的Git工作流,由Vincent Driessen在2010年提出。它定义了严格的分支模型,适合有计划发布周期的项目。

分支模型

  • master:主分支,存放随时可部署的生产代码
  • develop:开发分支,存放最新的开发代码
  • feature/*:特性分支,从develop分支创建,开发完成后合并回develop
  • release/*:发布分支,从develop分支创建,用于发布前的准备和测试,完成后合并到master和develop
  • hotfix/*:热修复分支,从master分支创建,用于修复生产环境的紧急bug,完成后合并到master和develop

工作流程

  1. 日常开发在develop分支进行
  2. 开发新功能时,从develop创建feature分支
  3. 功能开发完成后,将feature分支合并回develop
  4. 准备发布时,从develop创建release分支
  5. release分支测试通过后,合并到master(打标签)和develop
  6. 生产环境出现bug时,从master创建hotfix分支
  7. bug修复完成后,合并到master和develop

优缺点

  • 优点:分支模型清晰,适合有计划发布周期的中大型项目
  • 缺点:分支较多,流程复杂,不适合快速迭代的小项目

2. GitHub Flow

GitHub Flow是GitHub提出的简化版工作流,适合持续部署的项目。它比Git Flow简单很多,只有一个长期分支master。

工作流程

  1. 从master分支创建特性分支
  2. 在特性分支上进行开发和提交
  3. 提交Pull Request(合并请求)
  4. 团队成员进行代码审查(Code Review)
  5. 代码审查通过后,将特性分支合并到master
  6. 部署到生产环境

优缺点

  • 优点:简单、灵活,适合快速迭代、持续部署的项目
  • 缺点:不适合有明确发布周期的项目,需要完善的自动化测试和部署

3. GitLab Flow

GitLab Flow是GitLab提出的工作流,结合了Git Flow和GitHub Flow的优点。它在master分支之外,增加了环境分支(如pre-production、production)。

工作流程

  1. 从master分支创建特性分支
  2. 在特性分支上进行开发和提交
  3. 提交Merge Request
  4. 代码审查通过后,合并到master
  5. 将master合并到pre-production分支进行预发布测试
  6. 测试通过后,将pre-production合并到production分支进行生产部署

优缺点

  • 优点:兼顾了简单性和环境隔离,适合有多个部署环境的项目
  • 缺点:比GitHub Flow复杂,需要维护多个环境分支

4. Trunk-Based Development(主干开发)

主干开发是一种极端的工作流,所有开发者都直接在master分支上提交代码,不使用长期特性分支。为了保证代码质量,通常配合特性开关(Feature Flag)和持续集成。

工作流程

  1. 所有开发者直接在master分支上提交代码
  2. 小步提交,每次提交都是小的、可工作的变更
  3. 未完成的功能用特性开关隐藏
  4. 每次提交都触发自动化测试
  5. 测试通过后自动部署

优缺点

  • 优点:合并冲突少,迭代速度快,适合小团队和快速迭代的项目
  • 缺点:对自动化测试和持续集成要求高,不适合大型团队

分支管理最佳实践

  1. 分支命名规范

- 特性分支:feature/xxx - 修复分支:fix/xxxbugfix/xxx - 热修复分支:hotfix/xxx - 发布分支:release/xxx - 实验分支:experiment/xxx

  1. 小步提交:每次提交应该是一个小的、完整的、可工作的变更,不要把多个不相关的变更放在一个提交里。
  1. 写好提交信息:提交信息应该清晰、简洁,说明本次提交做了什么。推荐使用Conventional Commits规范:type(scope): subject,如feat(auth): add login functionality
  1. 定期同步主分支:在特性分支开发时,定期从主分支合并或变基,避免分支差异过大,减少合并冲突。
  1. 代码审查:合并分支前进行代码审查,保证代码质量。通过Pull Request/Merge Request进行代码审查。
  1. 删除已合并分支:分支合并后,及时删除已合并的分支,保持仓库整洁。
  1. 保护主分支:保护master和develop等重要分支,禁止直接推送,必须通过Pull Request合并。

常用Git技巧

1. 暂存当前工作

# 暂存当前工作
git stash

# 查看暂存列表
git stash list

# 恢复最近的暂存
git stash pop

# 恢复指定的暂存
git stash apply stash@{0}

2. 撤销修改

# 撤销工作区的修改(未add)
git checkout -- file.txt
git restore file.txt

# 撤销暂存区的修改(已add未commit)
git reset HEAD file.txt
git restore --staged file.txt

# 撤销最近一次提交(保留修改)
git reset --soft HEAD~1

# 撤销最近一次提交(丢弃修改)
git reset --hard HEAD~1

3. 查看历史

# 查看提交历史
git log

# 查看简洁的提交历史
git log --oneline

# 查看图形化的分支历史
git log --oneline --graph --all

# 查看指定文件的修改历史
git log -p file.txt

# 查看指定行的修改历史
git blame file.txt

4. Cherry-pick

# 将指定提交应用到当前分支
git cherry-pick 1a2b3c4

# 将多个提交应用到当前分支
git cherry-pick 1a2b3c4 4d5e6f7

总结

Git的分支管理和工作流是团队协作的基础。选择合适的工作流,遵循分支管理最佳实践,能让我们的团队协作更加高效,代码管理更加规范。

  • 小团队、快速迭代:推荐GitHub Flow或主干开发
  • 中大型团队、有计划发布:推荐Git Flow
  • 多环境部署:推荐GitLab Flow

掌握Git的进阶用法,能让我们在日常开发中更加得心应手,避免很多常见的问题。希望这篇教程能帮助大家更好地使用Git。