Git是目前最流行的分布式版本控制系统,几乎所有的软件开发项目都在使用Git。但是很多人只会用git add、git commit、git push这些基础命令,对Git的分支、合并、工作流等高级功能了解不多。今天就来分享Git版本控制的进阶知识,包括分支管理、合并策略、常见工作流以及实战技巧。

Git分支基础

分支是Git最强大的功能之一。分支本质上是指向提交对象的可变指针,默认分支是master(现在很多项目改名为main)。使用分支可以让我们在开发过程中从主线上分离出来,在不影响主线的情况下进行开发、实验、修复bug等工作。

1. 查看分支

# 查看本地分支
git branch

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

# 查看分支详情(最后一次提交)
git branch -v

# 查看已经合并到当前分支的分支
git branch --merged

# 查看还没有合并到当前分支的分支
git branch --no-merged

2. 创建和切换分支

# 创建分支
git branch feature-login

# 切换分支
git checkout feature-login

# 创建并切换分支(推荐)
git checkout -b feature-login

# Git 2.23+ 新命令
git switch -c feature-login
git switch feature-login

3. 删除分支

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

# 强制删除分支(不管是否合并)
git branch -D feature-login

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

4. 分支命名规范

  • master/main:主分支,保持稳定,随时可发布
  • develop:开发分支,集成所有开发功能
  • feature/xxx:功能分支,开发新功能
  • bugfix/xxx:bug修复分支,修复非紧急bug
  • hotfix/xxx:紧急修复分支,修复线上紧急bug
  • release/xxx:发布分支,准备发布新版本

Git合并

合并是将一个分支的修改整合到另一个分支的操作。Git有两种主要的合并方式:快速合并(Fast-forward)和三方合并(Three-way merge)。

1. 快速合并(Fast-forward): 当当前分支的提交历史是目标分支提交历史的直接祖先时,Git会直接将当前分支的指针移动到目标分支的最新提交,这就是快速合并。快速合并不会产生新的合并提交。

git checkout master
git merge feature-login
# 如果feature-login是在master基础上开发的,且master没有新提交,就会快速合并

2. 三方合并(Three-way merge): 当两个分支都有新的提交,无法快速合并时,Git会进行三方合并。Git会找到两个分支的共同祖先,然后将两个分支的修改合并在一起,产生一个新的合并提交。

git checkout master
git merge feature-login
# 如果两个分支都有新提交,就会进行三方合并,产生合并提交

3. 合并冲突: 当两个分支修改了同一个文件的同一部分时,Git无法自动合并,就会产生合并冲突。这时候需要手动解决冲突。

# 合并时产生冲突
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

4. 合并策略

  • --no-ff:禁止快速合并,总是产生合并提交。这样可以保留分支的历史记录,方便查看功能分支的开发过程。推荐在合并功能分支时使用。

``bash git merge --no-ff feature-login ``

  • --squash:将目标分支的所有提交压缩成一个提交,合并到当前分支。这样可以保持提交历史简洁,但是会丢失分支的详细提交记录。

``bash git merge --squash feature-login git commit ``

  • --rebase:变基,将当前分支的提交在目标分支的基础上重新应用。这样可以保持线性的提交历史,但是会修改提交历史。

``bash git checkout feature-login git rebase master # 然后切换到master,快速合并 git checkout master git merge feature-login ``

Git变基(Rebase)

变基是另一种整合修改的方式。和合并不同,变基会将当前分支的提交在目标分支的基础上重新应用,产生新的提交,从而保持线性的提交历史。

1. 基本变基

# 在feature-login分支上,将提交变基到master
git checkout feature-login
git rebase master

# 变基过程中如果有冲突,解决冲突后继续
git add <冲突文件>
git rebase --continue

# 如果想放弃变基
git rebase --abort

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

# 对最近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:删除提交

# 修改后保存退出,Git会按照你的要求处理提交

3. 变基 vs 合并: | 特性 | 合并(Merge) | 变基(Rebase) | |------|--------------|---------------| | 提交历史 | 保留完整的分支历史,有合并提交 | 线性历史,没有合并提交 | | 安全性 | 安全,不修改已有提交历史 | 会修改提交历史,有风险 | | 适用场景 | 公共分支合并,保留完整历史 | 个人分支整理,保持线性历史 | | 冲突处理 | 一次解决所有冲突 | 逐个提交解决冲突 |

变基的黄金法则:不要对已经推送到公共仓库的提交进行变基!因为变基会修改提交历史,会给其他协作者带来混乱。

常见Git工作流

1. Git Flow: Git Flow是最经典的Git工作流,适合有计划发布周期的项目。它定义了五种分支:

  • master:主分支,存放正式发布版本
  • develop:开发分支,集成所有开发功能
  • feature/xxx:功能分支,从develop创建,开发完成后合并回develop
  • release/xxx:发布分支,从develop创建,准备发布,发布后合并到master和develop
  • hotfix/xxx:紧急修复分支,从master创建,修复后合并到master和develop

Git Flow的优点是流程清晰,适合大型团队和有计划发布的项目;缺点是分支较多,流程相对复杂。

2. GitHub Flow: GitHub Flow是更简单的工作流,适合持续部署的项目。它只有两种分支:

  • master:主分支,随时可部署
  • feature/xxx:功能分支,从master创建,开发完成后通过Pull Request合并回master

GitHub Flow的流程:

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

GitHub Flow的优点是简单、灵活,适合持续部署和小团队;缺点是没有明确的版本概念,不适合有计划发布周期的项目。

3. GitLab Flow: GitLab Flow是GitHub Flow的改进版,结合了Git Flow和GitHub Flow的优点。它在GitHub Flow的基础上增加了环境分支(如pre-production、production),适合有多个部署环境的项目。

4. 主干开发(Trunk-Based Development): 主干开发是一种更激进的工作流,所有开发者都直接在主干(master/main)上开发,或者使用生命周期很短的功能分支(一般不超过1天)。这种工作流适合采用持续集成、持续部署的敏捷团队。

主干开发的关键是:

  • 小步提交,每次提交都是完整的、可工作的
  • 使用特性开关(Feature Flag)控制未完成功能的可见性
  • 持续集成,每次提交都自动运行测试
  • 代码审查,保证代码质量

Git高级技巧

1. 储藏(Stash): 当我们在一个分支上工作到一半,需要切换到另一个分支处理紧急任务,但是又不想提交未完成的工作时,可以使用git stash将修改储藏起来。

# 储藏当前修改
git stash

# 储藏时添加描述
git stash save "work in progress"

# 查看储藏列表
git stash list

# 应用最近的储藏(不删除)
git stash apply

# 应用指定的储藏
git stash apply stash@{1}

# 应用最近的储藏并删除
git stash pop

# 删除最近的储藏
git stash drop

# 删除指定的储藏
git stash drop stash@{1}

# 删除所有储藏
git stash clear

2. 撤销修改

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

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

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

# 撤销最近一次提交(不保留修改,谨慎使用)
git reset --hard HEAD~1

# 修改最近一次提交信息
git commit --amend

# 修改最近一次提交(添加遗漏的文件)
git add forgotten-file
git commit --amend

3. 查看历史

# 查看提交历史
git log

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

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

# 查看最近N次提交
git log -n 5

# 查看指定文件的提交历史
git log -- file.txt

# 查看指定作者的提交
git log --author="username"

# 查看指定时间范围的提交
git log --since="2016-01-01" --until="2016-12-31"

# 查看提交详情
git show commit-id

# 查看某行代码是谁写的
git blame file.txt

4. 标签(Tag): 标签用于标记重要的提交,如版本发布。

# 查看标签
git tag

# 创建轻量标签
git tag v1.0.0

# 创建附注标签(推荐)
git tag -a v1.0.0 -m "Release version 1.0.0"

# 查看标签详情
git show v1.0.0

# 推送标签到远程
git push origin v1.0.0

# 推送所有标签
git push origin --tags

# 删除本地标签
git tag -d v1.0.0

# 删除远程标签
git push origin --delete v1.0.0

5. 远程仓库操作

# 查看远程仓库
git remote -v

# 添加远程仓库
git remote add origin https://github.com/user/repo.git

# 修改远程仓库URL
git remote set-url origin https://github.com/user/new-repo.git

# 删除远程仓库
git remote remove origin

# 从远程拉取修改(不合并)
git fetch origin

# 从远程拉取修改并合并
git pull origin master

# 推送本地提交到远程
git push origin master

# 推送本地分支到远程并设置上游
git push -u origin feature-login

实战经验和最佳实践

1. 提交规范

  • 每次提交只做一件事,保持提交的原子性
  • 提交信息要清晰、有意义,说明做了什么、为什么做
  • 推荐使用Conventional Commits规范:type(scope): subject

- feat:新功能 - fix:修复bug - docs:文档修改 - style:代码格式修改 - refactor:代码重构 - perf:性能优化 - test:测试相关 - chore:构建/工具相关

2. 分支管理

  • 主分支(master/main)保持稳定,随时可发布
  • 功能分支从主分支或开发分支创建,开发完成后及时合并并删除
  • 不要在功能分支上停留太久,及时合并避免冲突
  • 合并前先拉取最新代码,解决冲突后再合并

3. 协作规范

  • 推送前先拉取最新代码,避免冲突
  • 使用Pull Request/Merge Request进行代码审查
  • Code Review要认真,不仅要看代码,还要理解业务逻辑
  • 不要直接推送强制修改(git push --force)到公共分支
  • 定期和团队同步,避免分支偏离太远

4. 安全注意事项

  • 不要将敏感信息(密码、密钥、配置)提交到Git仓库
  • 使用.gitignore忽略不需要版本控制的文件
  • 如果不小心提交了敏感信息,要及时修改并清理历史
  • 定期备份仓库,防止数据丢失

总结

Git是现代开发者的必备技能,掌握Git的分支、合并、变基、工作流等高级功能,能让我们的开发工作更加高效、规范。

本文介绍了Git分支基础、合并、变基、常见工作流(Git Flow、GitHub Flow、GitLab Flow、主干开发)、高级技巧(储藏、撤销修改、查看历史、标签、远程仓库操作)以及实战经验和最佳实践。

Git的功能很强大,但是核心是版本控制和协作。我们不需要记住所有的命令,只需要掌握常用的命令和工作流,在实际使用中不断学习和积累。遇到问题时,可以查阅Git文档或者使用git --help查看帮助。

希望这篇文章能帮助大家更好地使用Git,提升开发效率和协作质量。版本控制是软件开发的基础,打好这个基础,我们的开发之路会走得更稳、更远。