Git是2016年最流行的分布式版本控制系统,几乎所有的软件开发团队都在使用Git。无论是开源项目还是商业项目,无论是大公司还是小团队,Git都已经成为版本控制的标准。掌握Git,是每个程序员的必备技能。

但是,很多人虽然会用Git的基本命令(add、commit、push、pull),但是对Git的工作流和团队协作并不熟悉。不知道该怎么分支管理,不知道该怎么处理冲突,不知道该怎么做代码审查,不知道团队协作的最佳实践。结果就是,Git用得一团糟,分支混乱,冲突频繁,代码质量无法保证。

这些年,我在不同的团队使用过Git,经历过不同的工作流,从Git Flow到GitHub Flow,从集中式到分布式,踩过不少坑,也积累了不少经验。今天就来系统地讲解Git工作流与团队协作,从基础概念到高级工作流,从个人使用到团队协作,帮助你高效地使用Git进行团队协作开发。

一、Git简介

1. 什么是Git

Git是一个分布式版本控制系统,由Linus Torvalds(Linux之父)在2005年创建,用于管理Linux内核的开发。Git的设计目标是速度、分布式架构、支持非线性开发(大量并行分支)。

版本控制系统(VCS)的作用:

  • 记录文件的变更历史,可以回溯到任意版本
  • 支持多人协作开发,合并不同人的修改
  • 支持分支管理,可以并行开发不同功能
  • 可以追溯谁在什么时候改了什么,为什么改

2. Git vs SVN

2016年,Git已经基本取代SVN(Subversion)成为主流。两者的核心区别:

  • 架构:Git是分布式的,每个开发者都有完整的版本库;SVN是集中式的,只有服务器有完整版本库,开发者只有工作副本。
  • 性能:Git大部分操作在本地完成,速度快;SVN需要联网,速度慢。
  • 分支:Git的分支是轻量级的,创建和切换分支很快;SVN的分支是目录拷贝,比较重。
  • 离线工作:Git可以离线提交、查看历史、切换分支;SVN离线只能编辑文件,不能提交。
  • 安全性:Git的内容是哈希校验的,不容易损坏;SVN相对容易损坏。

3. Git的核心概念

  • 工作区(Working Directory):你在电脑里能看到的目录,存放正在编辑的文件。
  • 暂存区(Staging Area/Index):.git目录下的index文件,存放下次要提交的文件快照。
  • 版本库(Repository):.git目录,存放所有的版本数据和元数据。
  • 提交(Commit):一次提交就是一个版本快照,有唯一的哈希值(SHA-1),包含作者、时间、提交信息、父提交等。
  • 分支(Branch):分支是指向某个提交的可变指针,默认分支是master。
  • 标签(Tag):标签是指向某个提交的不可变指针,常用于标记版本号(如v1.0.0)。
  • 远程仓库(Remote):托管在网络上的版本库,如GitHub、GitLab、公司内部Git服务器。
  • HEAD:指向当前分支最新提交的指针。

4. Git的工作流程

基本工作流程:

  1. 在工作区修改文件
  2. 将修改添加到暂存区(git add)
  3. 将暂存区的内容提交到版本库(git commit)
  4. 将本地提交推送到远程仓库(git push)
  5. 从远程仓库拉取别人的更新(git pull/fetch)

二、Git常用命令

1. 基础命令

# 初始化仓库
git init                    # 在当前目录初始化Git仓库
git clone <url>             # 克隆远程仓库到本地
git clone <url> <dir>      # 克隆到指定目录

# 配置
git config --global user.name "Your Name"       # 设置用户名
git config --global user.email "you@example.com" # 设置邮箱
git config --global color.ui auto                 # 开启颜色
git config --list                                  # 查看所有配置

# 查看状态和历史
git status                  # 查看工作区状态
git log                     # 查看提交历史
git log --oneline           # 一行显示一个提交
git log --graph             # 图形化显示分支合并历史
git log --author="name"     # 查看指定作者的提交
git log --since="2016-01-01" --until="2016-12-31" # 查看指定时间范围的提交
git diff                    # 查看工作区和暂存区的差异
git diff --staged           # 查看暂存区和版本库的差异
git diff <commit1> <commit2> # 查看两个提交之间的差异
git show <commit>           # 查看某个提交的详细信息

# 添加和提交
git add <file>              # 添加指定文件到暂存区
git add .                   # 添加所有修改和新增文件到暂存区
git add -A                  # 添加所有修改、新增、删除文件
git add -p                  # 交互式添加,可选择部分修改
git commit -m "message"     # 提交暂存区内容,附带提交信息
git commit -am "message"    # 自动添加所有已跟踪文件的修改并提交(不包括新增文件)
git commit --amend          # 修改上一次提交(修改提交信息或添加遗漏的文件)

# 撤销和重置
git checkout -- <file>      # 撤销工作区的修改(恢复到暂存区状态)
git reset HEAD <file>       # 撤销暂存区的添加(恢复到工作区修改状态)
git reset --soft <commit>   # 软重置,保留工作区和暂存区修改,HEAD回退到指定提交
git reset --mixed <commit>  # 混合重置(默认),保留工作区修改,清空暂存区
git reset --hard <commit>   # 硬重置,丢弃工作区和暂存区修改,完全恢复到指定提交(危险!)
git revert <commit>         # 新建一个提交来撤销指定提交(安全,不会修改历史)
git reflog                   # 查看所有HEAD移动记录(找回丢失的提交)

2. 分支命令

# 分支管理
git branch                  # 查看本地分支
git branch -a               # 查看所有分支(本地+远程)
git branch -v               # 查看分支及最新提交
git branch <name>           # 创建分支
git branch -d <name>        # 删除已合并的分支
git branch -D <name>        # 强制删除分支(未合并也删除)
git branch -m <old> <new>   # 重命名分支

# 切换分支
git checkout <branch>       # 切换到指定分支
git checkout -b <branch>    # 创建并切换到新分支
git switch <branch>         # 切换分支(Git 2.23+,更直观)
git switch -c <branch>      # 创建并切换(Git 2.23+)

# 合并分支
git merge <branch>          # 将指定分支合并到当前分支
git merge --no-ff <branch>  # 禁用快进合并,生成合并提交(保留分支历史)
git merge --squash <branch> # 压缩合并,将分支的所有提交压缩成一个提交
git rebase <branch>          # 将当前分支的提交变基到指定分支之上(重写历史)
git rebase -i <commit>      # 交互式变基,可以合并、修改、删除提交

# 冲突解决
# 合并/变基冲突时,手动编辑冲突文件,然后:
git add <file>               # 标记冲突已解决
git commit                   # 完成合并(merge冲突)
git rebase --continue        # 继续变基(rebase冲突)
git rebase --abort           # 放弃变基,恢复到变基前状态
git merge --abort            # 放弃合并

3. 远程仓库命令

# 远程仓库管理
git remote                  # 查看远程仓库
git remote -v               # 查看远程仓库及URL
git remote add <name> <url> # 添加远程仓库
git remote remove <name>    # 删除远程仓库
git remote rename <old> <new> # 重命名远程仓库
git remote set-url <name> <url> # 修改远程仓库URL

# 推送和拉取
git push <remote> <branch>  # 推送本地分支到远程
git push -u <remote> <branch> # 推送并设置上游跟踪分支(之后可直接git push)
git push --all               # 推送所有分支
git push --tags              # 推送所有标签
git push <remote> --delete <branch> # 删除远程分支

git fetch <remote>           # 从远程获取更新,但不合并(只更新远程跟踪分支)
git pull <remote> <branch>   # 从远程获取更新并合并(= git fetch + git merge)
git pull --rebase <remote> <branch> # 用rebase方式拉取(更干净的历史)

# 跟踪分支
git branch --set-upstream-to=<remote>/<branch> <local-branch> # 设置本地分支跟踪远程分支
git branch -vv               # 查看分支跟踪关系

4. 标签命令

git tag                      # 查看所有标签
git tag <name>               # 创建轻量标签
git tag -a <name> -m "message" # 创建附注标签(推荐,包含作者、时间、信息)
git tag -a <name> <commit>   # 给指定提交打标签
git show <tag>               # 查看标签信息
git push <remote> <tag>      # 推送指定标签
git push --tags              # 推送所有标签
git tag -d <tag>             # 删除本地标签
git push <remote> :refs/tags/<tag> # 删除远程标签

5. 储藏(Stash)

git stash                    # 储藏当前工作区和暂存区的修改
git stash save "message"     # 储藏并添加描述
git stash list               # 查看所有储藏
git stash apply              # 应用最近的储藏(不删除储藏记录)
git stash apply stash@{1}    # 应用指定的储藏
git stash pop                # 应用最近的储藏并删除(= apply + drop)
git stash drop               # 删除最近的储藏
git stash drop stash@{1}     # 删除指定的储藏
git stash clear              # 清空所有储藏
git stash show -p            # 查看储藏的具体内容

三、Git分支管理策略

分支是Git最强大的功能之一,合理的分支管理是团队协作的基础。

1. 分支类型

常见的分支类型:

  • 主分支(master/main):稳定的生产环境代码,随时可以部署。只接受合并,不直接提交。
  • 开发分支(develop):日常开发的集成分支,包含最新的开发代码。功能开发完成后合并到develop。
  • *功能分支(feature/)**:开发新功能的分支,从develop创建,完成后合并回develop。如feature/user-login、feature/payment。
  • *发布分支(release/)**:发布新版本的准备分支,从develop创建,用于测试、修复bug、准备发布。发布后合并到master和develop。如release/1.0.0。
  • *热修复分支(hotfix/)**:修复生产环境紧急bug的分支,从master创建,修复后合并到master和develop。如hotfix/security-patch。
  • *Bug修复分支(bugfix/)**:修复非紧急bug的分支,从develop创建,修复后合并回develop。

2. 分支命名规范

好的分支命名能让人一眼看出分支的用途:

master                    # 主分支
develop                   # 开发分支
feature/user-login        # 功能分支
feature/payment-integration
release/1.0.0             # 发布分支
hotfix/critical-bug       # 热修复分支
bugfix/login-error        # Bug修复分支
experiment/new-ui         # 实验分支

命名规范建议:

  • 使用小写字母和连字符(kebab-case)
  • 前缀表明分支类型(feature/、hotfix/、release/等)
  • 名称简洁明了,描述分支用途
  • 可以关联Issue编号,如feature/123-user-login

3. 提交信息规范

好的提交信息能让历史记录清晰可读,方便追溯和生成变更日志。

推荐的提交信息格式(Conventional Commits):

<type>(<scope>): <subject>

<body>

<footer>

类型(type):

  • feat:新功能
  • fix:修复bug
  • docs:文档修改
  • style:代码格式修改(不影响代码运行)
  • refactor:重构(既不是新增功能也不是修bug)
  • perf:性能优化
  • test:测试相关
  • chore:构建过程或辅助工具的变动
  • ci:CI配置相关
  • revert:撤销之前的提交

示例:

feat(user): 添加用户登录功能

- 添加登录页面
- 添加登录API接口
- 添加表单验证

Closes #123
fix(payment): 修复支付金额计算错误

修复了优惠券叠加时金额计算错误的问题。

好的提交信息应该:

  • 标题简洁(不超过50字符)
  • 描述清楚改了什么、为什么改
  • 一个提交只做一件事(原子提交)
  • 关联Issue编号

四、常见Git工作流

不同的团队有不同的工作流,选择适合自己团队的工作流很重要。下面介绍几种常见的工作流。

1. Git Flow

Git Flow是Vincent Driessen在2010年提出的工作流,是最经典、最严格的工作流。

核心分支

  • master:生产环境代码,稳定
  • develop:开发集成分支

辅助分支

  • feature/*:功能分支,从develop创建,合并回develop
  • release/*:发布分支,从develop创建,合并到master和develop
  • hotfix/*:热修复分支,从master创建,合并到master和develop

工作流程

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

优点

  • 结构清晰,职责明确
  • 适合有明确发布周期的团队
  • master分支始终稳定
  • 支持多个版本并行维护

缺点

  • 分支多,流程复杂,学习成本高
  • 合并频繁,容易冲突
  • 不适合持续部署/持续交付的团队
  • develop和master长期并行,容易产生差异

适合:有明确发布周期、版本需要长期维护、团队较大、流程规范的团队。

2. GitHub Flow

GitHub Flow是GitHub提出的工作流,比Git Flow简单,适合持续部署的团队。

核心原则

  1. master分支始终是可部署的
  2. 新功能从master创建分支
  3. 在分支上开发和提交
  4. 通过Pull Request(PR)进行代码审查和讨论
  5. 代码审查通过后,合并到master
  6. 合并后立即部署

工作流程

  1. 从master创建功能分支(如feature/user-login)
  2. 在功能分支上开发,频繁提交
  3. 开发完成后,提交Pull Request
  4. 团队成员代码审查、讨论、提出修改建议
  5. 根据反馈修改代码,更新PR
  6. 代码审查通过后,合并到master
  7. 合并后立即部署到生产环境

优点

  • 简单,只有master+功能分支,学习成本低
  • 适合持续部署/持续交付
  • PR机制促进代码审查和团队协作
  • 分支生命周期短,冲突少
  • master始终可部署

缺点

  • 不适合有多个版本并行维护的团队
  • 没有专门的测试和发布分支,测试需要在分支上完成
  • 依赖自动化测试和部署
  • 生产环境bug修复和普通功能开发流程一样

适合:Web应用、SaaS产品、持续部署、小团队、快速迭代的团队。

3. GitLab Flow

GitLab Flow是GitLab提出的工作流,结合了Git Flow和GitHub Flow的优点,增加了环境分支。

核心分支

  • master:主分支,代码合并入口
  • pre-production:预发布环境分支
  • production:生产环境分支

工作流程

  1. 从master创建功能分支
  2. 开发完成后,通过Merge Request(MR)合并到master
  3. master通过MR合并到pre-production进行测试
  4. 测试通过后,pre-production通过MR合并到production部署
  5. 生产环境bug从production创建分支,修复后合并到production,然后cherry-pick到master和pre-production

优点

  • 比Git Flow简单,比GitHub Flow多了环境隔离
  • 适合有多个环境(开发、测试、预发布、生产)的团队
  • 支持持续交付
  • 环境分支清晰,部署流程明确

缺点

  • 环境分支可能长期不同步
  • 需要cherry-pick操作
  • 比GitHub Flow复杂

适合:有多个部署环境、需要环境隔离、持续交付的团队。

4. Trunk Based Development(主干开发)

Trunk Based Development(TBD)是一种极简的工作流,所有开发者都直接在主干(master/trunk)上提交,或者创建生命周期极短的分支(几小时内合并)。

核心原则

  1. 主干始终可构建、可部署
  2. 开发者直接在主干提交,或创建短生命周期分支(不超过1-2天)
  3. 频繁提交,小步迭代
  4. 使用特性开关(Feature Flag)控制未完成功能的可见性
  5. 依赖自动化测试保证质量
  6. 代码审查通过结对编程或提交后审查完成

优点

  • 极简,没有复杂的分支管理
  • 合并冲突少(因为频繁集成)
  • 适合持续集成/持续部署
  • 开发速度快,反馈快
  • 避免长期分支带来的合并地狱

缺点

  • 对自动化测试要求高(必须有完善的测试套件)
  • 需要特性开关管理未完成功能
  • 不适合新手多、代码质量不稳定的团队
  • 主干可能不稳定(如果测试不完善)

适合:成熟团队、有完善自动化测试、持续集成/持续部署、追求快速迭代的团队(如Google、Facebook)。

5. 工作流选择建议

  • 小团队、快速迭代、Web应用:GitHub Flow(简单、高效)
  • 大团队、有发布周期、多版本维护:Git Flow(规范、严谨)
  • 多环境部署、持续交付:GitLab Flow(环境隔离)
  • 成熟团队、完善测试、追求速度:Trunk Based Development(极简、快速)
  • 个人项目/开源项目:GitHub Flow(简单,PR机制好)

没有最好的工作流,只有最适合自己团队的工作流。可以根据团队规模、项目类型、发布频率、测试能力等因素选择,也可以根据实际情况调整和混合。

五、团队协作最佳实践

1. 代码审查(Code Review)

代码审查是保证代码质量、知识共享、团队成长的重要手段。

代码审查的方式

  • Pull Request/Merge Request:最常用的方式,功能分支合并到主分支前发起PR,团队成员审查
  • 结对编程:两个人一起写代码,实时审查
  • 提交后审查:代码已经合并,定期审查历史提交
  • 工具辅助:使用SonarQube、ESLint等静态分析工具自动检查

代码审查的要点

  • 审查代码逻辑是否正确,有没有bug
  • 审查代码是否符合团队规范(命名、格式、注释)
  • 审查代码是否有安全漏洞
  • 审查代码是否有性能问题
  • 审查测试是否充分
  • 提出建设性的建议,而不是批评
  • 尊重作者,对事不对人
  • 及时审查,不要让PR等太久

PR/MR的最佳实践

  • PR要小,一个PR只做一件事(不超过400行改动)
  • PR标题和描述清晰,说明改了什么、为什么改、怎么测试的
  • 关联Issue编号
  • 截图/录屏(UI改动)
  • 至少1-2人审查通过才能合并
  • CI通过(测试、lint、构建)才能合并
  • 合并后删除分支

2. 冲突解决

多人协作时,合并冲突是难免的。正确处理冲突很重要。

冲突产生的原因

  • 两个人修改了同一个文件的同一行
  • 一个人删除了文件,另一个人修改了文件
  • 分支分叉太久,差异太大

预防冲突的方法

  • 频繁从主分支拉取更新(git pull --rebase)
  • 分支生命周期短,及时合并
  • 小步提交,原子提交
  • 合理分配任务,避免多人同时改同一个文件
  • 提前沟通,知道别人在改什么

解决冲突的步骤

  1. 合并/变基时Git提示冲突,用git status查看冲突文件
  2. 打开冲突文件,找到冲突标记(<<<<<<<、=======、>>>>>>>)
  3. 分析冲突,决定保留哪个版本,或者合并两者
  4. 删除冲突标记,保存文件
  5. git add标记冲突已解决
  6. git commit(merge)或git rebase --continue(rebase)
  7. 测试确保代码正常运行

冲突标记说明

<<<<<<< HEAD
当前分支的内容
=======
要合并的分支的内容
>>>>>>> branch-name

3. 提交规范

  • 原子提交:一个提交只做一件事,不要把不相关的修改放在一个提交里
  • 频繁提交:小步迭代,不要攒一大堆修改才提交
  • 提交前测试:确保提交的代码能正常运行,不要提交有bug的代码
  • 提交信息规范:使用Conventional Commits格式,清晰描述改动
  • 不要提交敏感信息:密码、密钥、配置文件等不要提交到Git
  • 使用.gitignore:忽略不需要版本控制的文件(node_modules、.env、IDE配置等)

4. .gitignore规范

.gitignore文件指定哪些文件不需要Git跟踪。

常见的.gitignore内容:

# 依赖
node_modules/
vendor/
*.egg-info/

# 环境配置
.env
.env.local
.env.*.local

# IDE
.idea/
.vscode/
*.swp
*.swo
*~

# 操作系统
.DS_Store
Thumbs.db

# 构建产物
dist/
build/
*.log

# 测试覆盖率
coverage/
.nyc_output/

# 临时文件
*.tmp
*.temp

5. 大文件管理

Git不适合管理大文件(二进制文件、媒体文件、数据集等),大文件会让仓库变得臃肿,克隆和拉取变慢。

解决方案:

  • Git LFS(Large File Storage):Git大文件存储,将大文件存储在远程服务器,Git只保存指针。GitHub、GitLab都支持。
  • 外部存储:将大文件存储在对象存储(OSS、S3)、CDN、网盘等,代码中只引用URL。
  • 避免提交大文件:构建产物、依赖包、媒体文件等不要提交到Git。

6. 安全实践

  • 不要提交密码、密钥、Token等敏感信息
  • 使用环境变量管理敏感配置
  • 如果不小心提交了敏感信息,立即修改密码/密钥,并使用git filter-branch或BFG Repo-Cleaner清除历史
  • 私有仓库设置好访问权限
  • 定期审查仓库访问权限
  • 使用GPG签名提交(验证提交者身份)
  • 依赖安全扫描(npm audit、composer audit等)

六、常用Git工具

1. 托管平台

  • GitHub:最大的开源代码托管平台,2016年被微软收购。功能强大,社区活跃,PR机制好。免费账户可以创建公开仓库,私有仓库需要付费(2016年)。
  • GitLab:开源的Git托管平台,可以自建。功能全面,内置CI/CD、Issue、Wiki等。社区版免费,企业版付费。很多公司自建GitLab。
  • Bitbucket:Atlassian旗下的Git托管平台,和Jira、Confluence集成好。免费账户可以创建5人以下的私有仓库。
  • Gitee(码云):国内的Git托管平台,访问速度快,适合国内团队。
  • Coding.net:国内的开发协作平台,Git托管+CI/CD+项目管理。

2. 图形化客户端

  • SourceTree:Atlassian出品的免费Git图形化客户端,支持Windows和Mac。功能强大,界面友好,适合不喜欢命令行的用户。
  • Tower:Mac上的付费Git客户端,界面优雅,功能强大。
  • GitKraken:跨平台的Git客户端,界面美观,支持GitHub/GitLab/Bitbucket集成。有免费版和付费版。
  • GitHub Desktop:GitHub官方的桌面客户端,简单易用,和GitHub集成好。
  • SmartGit:跨平台的Git客户端,功能全面,有免费版(非商业用途)。
  • TortoiseGit:Windows上的Git客户端,集成到资源管理器右键菜单,类似TortoiseSVN。

3. IDE集成

几乎所有主流IDE都集成了Git功能:

  • VS Code:内置Git支持,有丰富的Git扩展(GitLens等)
  • JetBrains系列(IDEA、PHPStorm、WebStorm等):强大的Git集成,可视化diff、合并、历史
  • Sublime Text:通过插件支持Git
  • Vim/Neovim:通过插件(fugitive.vim等)支持Git
  • Eclipse:EGit插件

4. 其他工具

  • git-quick-stats:Git统计工具,查看提交统计、贡献者统计等
  • git-secrets:扫描提交中的敏感信息(密码、密钥等)
  • BFG Repo-Cleaner:快速清除Git历史中的大文件或敏感信息
  • git-filter-repo:Git官方推荐的历史重写工具
  • Husky:Git钩子工具,在提交前自动运行lint、测试等
  • commitlint:检查提交信息是否符合规范
  • standard-version:自动生成版本号和变更日志

七、常见问题与解决方案

1. 提交错了分支怎么办?

# 如果还没push,撤销提交,切换到正确分支重新提交
git reset --soft HEAD~1   # 撤销最近一次提交,保留修改在暂存区
git stash                  # 储藏修改
git checkout correct-branch # 切换到正确分支
git stash pop              # 恢复修改
git commit -m "message"    # 重新提交

# 或者用cherry-pick
git log                    # 找到错误提交的哈希
git checkout correct-branch
git cherry-pick <commit-hash> # 将指定提交应用到当前分支
git checkout wrong-branch
git reset --hard HEAD~1   # 删除错误分支上的提交(如果还没push)

2. 不小心提交了敏感信息怎么办?

  1. 立即修改密码/密钥(最重要!)
  2. 从Git历史中清除敏感信息:
# 使用git filter-branch(较慢)
git filter-branch --force --index-filter \
  'git rm --cached --ignore-unmatch path/to/file' \
  --prune-empty --tag-name-filter cat -- --all

# 或使用BFG Repo-Cleaner(更快,推荐)
bfg --delete-files file-with-secrets
bfg --replace-text passwords.txt  # 替换文本中的敏感信息

# 清除后强制推送
git push --force --all
git push --force --tags

# 清理本地仓库
rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --prune=now --aggressive
  1. 通知团队成员重新克隆仓库(因为历史被重写了)
  2. 以后使用环境变量和.gitignore管理敏感信息

3. 合并冲突太多怎么办?

  • 预防:频繁从主分支rebase,分支生命周期短,小步提交
  • 解决:耐心逐个文件解决冲突,解决后测试
  • 工具:使用IDE的可视化合并工具(VS Code、JetBrains都有),比手动编辑方便
  • 如果冲突太多无法解决,可以放弃合并,重新基于最新主分支开发:
git merge --abort   # 放弃合并
# 或
git rebase --abort  # 放弃变基

4. push被拒绝(non-fast-forward)怎么办?

这是因为远程分支有新的提交,你的本地分支不是最新的。

# 先拉取远程更新,合并后再推送
git pull --rebase origin branch-name  # 推荐用rebase,历史更干净
# 解决冲突(如果有)
git push origin branch-name

# 如果你确定要覆盖远程(危险!会丢失别人的提交)
git push --force origin branch-name
# 更安全的强制推送(只在远程没有新提交时才覆盖)
git push --force-with-lease origin branch-name

5. 怎么撤销已经push的提交?

# 方法1:用git revert新建一个提交来撤销(安全,推荐,不会修改历史)
git revert <commit-hash>
git push

# 方法2:用git reset回退然后强制推送(危险,会修改历史,只在确定没人基于这些提交开发时使用)
git reset --hard <commit-before-bad-commit>
git push --force-with-lease origin branch-name

# 方法3:如果只是最近一次提交有问题,修改后重新提交
git commit --amend  # 修改上一次提交
git push --force-with-lease

6. 怎么查看某行代码是谁改的?

git blame <file>           # 查看文件每一行的最后修改者和提交
git blame -L 10,20 <file>  # 查看指定行范围
git blame -C <file>         # 检测代码移动(从其他文件复制过来的)

7. 怎么找到引入bug的提交?

# 使用git bisect二分查找
git bisect start
git bisect bad              # 标记当前提交有bug
git bisect good <commit>    # 标记某个已知没有bug的提交
# Git会自动切换到中间提交,测试后标记good或bad
git bisect good             # 如果这个提交没有bug
git bisect bad              # 如果这个提交有bug
# 重复直到找到引入bug的提交
git bisect reset            # 结束bisect,恢复到原来的分支

8. Git仓库太大怎么办?

  • 清除历史中的大文件:使用BFG Repo-Cleaner或git filter-repo
  • 使用Git LFS管理大文件
  • 浅克隆(只需要最近的历史):git clone --depth 1 <url>
  • 只克隆指定分支:git clone -b branch --single-branch <url>
  • 定期清理:git gc --prune=now --aggressive

总结

Git是2016年最流行的分布式版本控制系统,是每个程序员的必备技能。掌握Git的工作流和团队协作,能大幅提升开发效率和代码质量。

本文从Git简介、核心概念、常用命令、分支管理策略、常见工作流(Git Flow、GitHub Flow、GitLab Flow、Trunk Based Development)、团队协作最佳实践(代码审查、冲突解决、提交规范、.gitignore、大文件管理、安全实践)、常用工具、常见问题与解决方案等方面,系统讲解了Git工作流与团队协作。

Git学习的核心要点:

  1. 理解Git的核心概念(工作区、暂存区、版本库、提交、分支)
  2. 掌握常用命令(add、commit、push、pull、branch、merge、rebase、stash)
  3. 选择适合团队的工作流(GitHub Flow简单高效,Git Flow规范严谨)
  4. 规范分支命名和提交信息
  5. 重视代码审查(PR/MR机制)
  6. 学会解决合并冲突
  7. 频繁提交、小步迭代、及时合并
  8. 不要提交敏感信息和大文件
  9. 使用.gitignore忽略不需要的文件
  10. 遇到问题用git reflog找回丢失的提交

Git的学习,没有捷径,只有多用多练。在实际项目中使用Git,遇到问题解决问题,慢慢就能熟练掌握。希望本文能帮助你更好地使用Git,高效地进行团队协作开发。

最后,记住Git的核心精神:版本控制不是为了束缚,而是为了自由。有了Git,你可以放心地尝试、大胆地重构、自由地分支,因为你知道随时可以回退、可以追溯、可以合并。用好Git,让它成为你开发的得力助手。