Git
本文范围
这篇把 Git 当成团队交付链路来讲,不是单纯背命令。重点是开发机和服务器怎么安装配置、代码怎么拉取、分支怎么隔离、tag 怎么作为发布基线、公共历史怎么回退、冲突怎么处理、内网和离线环境怎么同步仓库。
本文会覆盖:
- Windows、Linux、企业内网和离线环境下的 Git 安装、基础配置、SSH key、代理和换行符治理。
- 工作区、暂存区、提交、分支、fetch/pull/push、merge/rebase、stash、cherry-pick、tag。
- 发布基线、制品回滚、
revert、restore、reset的边界和公共历史治理。 git bundle、git archive、内网 Git 服务和源码快照的交付风险。- 多人协作规范、分支保护、提交前检查、常见故障和发布前清单。
本文不展开 Git 对象存储源码、GitLab/GitHub/Gitee 的完整平台治理,也不讲 CI/CD 平台语法。流水线要依赖 Git 的 commit、tag、分支和变更范围,但流水线本身放到 CI/CD 专题里讲。
前置条件
建议准备一台开发机和一个可测试的远端仓库。Windows 用户需要 PowerShell 和 Git Bash;Linux 用户需要 SSH 客户端和能访问仓库的网络路径。生产发布相关操作前,必须先确认当前分支、工作区状态、远端状态和发布 tag,不要在脏工作区里做发布。
先执行:
git --version
git config --list --show-origin
ssh -V
git status --short --branch
git remote -v企业内网需要提前确认 Git 服务、代理、证书、SSH key、安装包和镜像仓库;离线环境需要准备 git bundle 或源码归档,并保留 commit id、tag、校验和和交付记录。本文所有仓库地址和分支名都是示例,不要暴露真实仓库、账号或 token。
先把场景说清楚
很多团队刚开始用 Git 时,问题不在于不会敲 git commit。真正麻烦的是人一多、分支一多、环境一多,大家开始说不清楚:这个功能到底在哪个分支,测试环境跑的是哪个提交,线上出问题应该回滚制品还是回滚代码,冲突文件到底该保留谁的逻辑。
所以这篇文章不把 Git 当成命令背诵表来讲,而是把它当成团队交付工具来用。我们从一台新电脑怎么装、怎么拉代码讲起,一直讲到发布打 tag、线上回滚、公共分支保护和内网离线同步。你照着做,至少能把团队里最常见的 Git 事故挡住一大半。
这里先约定三类环境:
- Windows 开发机:Windows 10/11,PowerShell、Git Bash、IDEA 或 VS Code,重点看 Git for Windows、SSH key、代理、换行符和凭据。
- Linux 开发机或服务器:Ubuntu/Debian、RHEL/CentOS Stream/Rocky/Alma,重点看包管理器、SSH、权限、服务器拉代码和 CI 执行。
- 企业内网和离线环境:不能默认 GitHub、Git 官网、国外软件源都能访问,需要准备内网 Git 服务、安装包、代理、镜像仓库或
git bundle。
这里不讲 Git 对象模型大论文,也不展开 GitLab、Jenkins、GitHub Actions 的完整流水线。流水线当然重要,但这篇只讲 Git 应该给流水线提供哪些稳定输入,比如分支、tag、提交号和变更范围。
截至 2026-07-09,官方安装页显示 Git 源码版本为 2.55.0,Git for Windows 维护构建为 2.55.0(2)。实际落地时,以你安装当天的官方页面、企业软件源和安全基线为准,不要拿旧教程里的安装包地址直接复制到生产机器上。
先记住一条团队 Git 交付闭环:
安装配置 -> 拉取代码 -> 创建分支 -> 提交变更 -> 同步主线 -> 合并评审 -> 打 tag 发布 -> 验证回滚这条链路的意思很简单:代码不是写完就结束,必须能说清楚它从哪里来、合到哪里去、发布到哪里、出问题怎么退回来。
团队 Git 交付闭环
后面的命令都围绕这条闭环来讲。每一节都会尽量说清楚四件事:这个命令解决什么问题,执行后怎么看结果,失败时怎么排查,放到生产团队里要加什么约束。
Git 对象和发布基线图
上面的闭环讲的是团队动作,落到 Git 里还要再看一层对象关系。Git 不是把“版本号”当成魔法保存起来,而是把文件内容、目录结构、提交关系和引用组织成对象图。发布 tag 只是一个稳定入口,真正决定线上版本的是它最终指向的 commit,以及这个 commit 对应的 tree 和 blob。
这张图要配合发布流程一起看:分支是会移动的,tag 原则上不应该移动;commit 是一次完整快照,不是某个文件补丁;制品必须能反查到 tag 和 commit。线上排障时,如果只知道“发了 main 最新版”,就等于没有基线。
验证这条对象链路可以用这些命令:
git rev-parse HEAD
git show --stat --oneline HEAD
git cat-file -t HEAD
git cat-file -p HEAD
git ls-tree --name-only HEAD
git show v1.4.0
git rev-parse v1.4.0^{commit}
git show-ref --tags v1.4.0
git describe --tags --always正常情况下,git cat-file -t HEAD 应该看到 commit,git cat-file -p HEAD 能看到 tree 和 parent,git rev-parse v1.4.0^{commit} 能解析到发布 tag 对应的提交。构建系统应该把这个 commit id 写入制品元信息,至少能通过版本接口、镜像标签、jar manifest 或发布记录查回来。
常见坑有三个。第一,把分支名当发布基线,结果 main 往前移动以后无法复现当时那次发布。第二,发布后删除或移动远程 tag,导致 CI、回滚脚本和审计记录互相对不上。第三,只保存源码 zip,不保存 tag、commit id 和制品校验值,离线现场出了问题只能靠文件时间猜版本。
生产约束很明确:发布 tag 不可随意移动;每次发布记录必须包含 tag、commit id、构建号、制品地址和 checksum;公共分支修复优先 revert,不要用 reset --hard 加强推改写团队共同历史。
安装与基础配置
Windows 安装
Windows 开发机一般安装 Git for Windows。这里不要只看安装向导有没有点完,至少要验证三个点:命令能不能找到、版本是不是预期、SSH 客户端能不能用。
PowerShell 中执行:
git --version
where git
ssh -V执行后应该看到 Git 版本号、git.exe 的实际路径和 OpenSSH 版本。where git 如果输出多个路径,要注意顺序,排在前面的那个才是当前真正执行的 Git。很多 Windows 机器上会同时存在 Git for Windows、IDE 内置 Git、旧版本 Git,排障时先把路径确认清楚。
如果企业允许使用 winget,可以这样安装:
winget install --id Git.Git -e --source winget
git --version如果命令提示找不到 winget,不要在生产网络里临时找网盘安装包。一般需要由运维或研发效能团队统一下载 Git for Windows 安装包,放到内网软件仓库里,并记录安装包版本、发布时间和校验值。
这里要注意:Windows 上建议同时保留 PowerShell 和 Git Bash。PowerShell 适合日常命令和自动化脚本,Git Bash 适合执行类 Linux 命令和排查 SSH 问题。团队文档里最好明确“示例命令在哪个 Shell 执行”,否则路径、引号、环境变量都容易出问题。
Linux 安装
Linux 服务器上安装 Git,先看发行版。Ubuntu / Debian 用 apt:
sudo apt update
sudo apt install -y git
git --version
command -v git执行后,git --version 应该输出版本号,command -v git 应该输出 Git 所在路径,一般是 /usr/bin/git。如果 apt update 失败,先查软件源、DNS、代理和内网镜像,不要急着换一堆未知源。
RHEL / CentOS Stream / Rocky / Alma 用 dnf:
sudo dnf install -y git
git --version
command -v git旧系统可能使用 yum:
sudo yum install -y git
git --version生产服务器不建议每台机器各装各的。更稳妥的方式是统一系统镜像、统一基础软件源、统一 Git 版本范围。CI 节点尤其要记录 git --version,因为 switch、restore、sparse-checkout、partial clone 等能力都和版本有关。如果一台 CI 节点支持 git switch,另一台不支持,脚本就会出现“本机没问题、流水线失败”的情况。
WSL 注意事项
Windows + WSL 最容易踩坑的是同一个仓库被两套 Git 混着操作。
一般建议这样分:
- 放在 Windows 文件系统里的仓库,用 Windows Git 操作。
- 放在 WSL Linux 文件系统里的仓库,用 WSL Git 操作。
- 不要一会儿用 Windows IDEA 改,一会儿用 WSL Git 提交同一个工作区。
- 团队统一换行符规则,避免每次提交出现全文件 diff。
如果你已经不确定当前仓库是被哪套 Git 操作的,先执行:
git --version
git config --show-origin --get core.autocrlf
git config --show-origin --get core.filemode这里重点看配置来自哪里。--show-origin 会告诉你配置是系统级、用户级还是仓库级。多人协作时,仓库级规则优先写清楚,个人全局配置不要和仓库规则打架。
用户信息和默认分支
每台开发机先配置用户信息,这一步很小,但生产排障时非常关键:
git config --global user.name "zhangsan"
git config --global user.email "zhangsan@example.com"
git config --global init.defaultBranch main
git config --global --list执行后用 git config --global --list 检查输出里有没有 user.name、user.email、init.defaultbranch。user.name 和 user.email 会进入提交记录,不要在公司项目里随便用个人昵称、临时邮箱或共享账号。提交历史是排障证据,也是审计证据。
换行符治理
跨 Windows、Linux 协作时,换行符必须统一。否则一个人只是打开文件保存,另一个人看到的可能是全文件变更。这个问题一旦进了代码评审,会把真正的业务 diff 淹没掉。
推荐在仓库里放 .gitattributes,由仓库规则控制换行符:
* text=auto
*.sh text eol=lf
*.bash text eol=lf
*.yml text eol=lf
*.yaml text eol=lf
*.md text eol=lf
*.bat text eol=crlf
*.cmd text eol=crlf
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.ico binary
*.jar binary
*.zip binary
*.tar.gz binary如果仓库已经有大量文件,新增 .gitattributes 后需要做一次规范化提交:
git add --renormalize .
git status --short
git commit -m "统一仓库换行符规则"执行后用 git status --short 看看变更范围。如果一次出现几百个文件,先确认是不是预期的换行符规范化,不要和业务代码混在一起提交。这里一般单独开一个 MR,标题就写“统一仓库换行符规则”,让评审的人知道这是基础治理,不是业务改动。
代理和 SSH key
企业网络常见两种访问方式:HTTPS 代理和 SSH。先别急着怀疑 Git,很多拉不下代码的问题其实是代理、证书或 22 端口限制。
配置 HTTPS 代理:
git config --global http.proxy http://127.0.0.1:7890
git config --global https.proxy http://127.0.0.1:7890
git config --global --get http.proxy
git config --global --unset http.proxy
git config --global --unset https.proxy前两行是设置代理,第三行是查看代理,后两行是取消代理。执行 --get 能看到代理地址,就说明配置已经写入。失败时先确认代理服务本身是否可用,再看公司是否要求安装根证书。
生成 SSH key:
ssh-keygen -t ed25519 -C "zhangsan@example.com"
ls ~/.ssh
cat ~/.ssh/id_ed25519.pub测试远程连通:
ssh -T git@example.com访问成功时,平台通常会返回一段欢迎信息,提示你已经通过 SSH 认证,但不会给你 shell 登录权限。如果看到 Permission denied (publickey),一般就是公钥没有配置到代码平台,或者你当前使用的不是这把 key。
Windows PowerShell 下路径通常在:
Get-ChildItem $env:USERPROFILE\.ssh
Get-Content $env:USERPROFILE\.ssh\id_ed25519.pubSSH 失败先看三件事:公钥是否已配置到代码平台,远程地址是否是 SSH 格式,当前网络是否允许访问 22 端口。有些企业会把 SSH 代理到 443 端口,这时要按企业平台提供的 SSH 配置写 ~/.ssh/config。
最小工作闭环
一个新成员刚加入项目,不要一上来就在 main 上改代码。最小闭环应该是先把仓库拉下来,再从主线切出自己的任务分支,改完以后先在本地看清楚变更,再同步主线,最后推到远端发起评审。
git clone git@example.com:team/demo.git
cd demo
git switch -c feature/login-check
# 修改代码
git status --short
git diff
git add .
git diff --cached
git commit -m "新增登录参数校验"
git fetch origin
git rebase origin/main
git push -u origin feature/login-check这串命令解决的是一个完整开发动作:
git clone把远端仓库复制到本地,执行成功后目录里应该出现.git和项目文件。git switch -c从当前分支切出新分支,执行后用git branch --show-current应该看到feature/login-check。git status --short用来快速看哪些文件变了,M是修改,A是新增,??是未跟踪文件。git diff看工作区还没放进暂存区的内容,防止把调试日志、临时配置一起提交。git diff --cached看下一次提交将包含什么,这一步比直接git add . && git commit稳得多。git fetch只更新远端信息,不会动你的工作区;git rebase origin/main是把个人分支放到最新主线后面,提前暴露冲突。git push -u第一次推送分支并建立跟踪关系,后面在这个分支上可以直接git push。
如果 Git 版本低于 2.23,没有 switch,用旧命令:
git checkout -b feature/login-check这里要注意几个习惯:
- 改代码前先从正确分支拉新分支。
- 提交前用
status和diff确认自己到底改了什么。 - 推送前同步主线,尽早暴露冲突。
- 不直接推主分支,走 PR 或 MR。
如果 git rebase origin/main 失败,不要硬推。先看 git status,把冲突文件处理完,跑最小测试,再 git rebase --continue。如果越处理越乱,就 git rebase --abort 回到 rebase 前的状态。
工作区、暂存区和提交
Git 日常一定要分清三个区域。这个不是为了背概念,而是为了知道“我现在改了什么”“下一次提交会带上什么”“哪些内容已经进入历史”。
- 工作区:你正在编辑的文件。
- 暂存区:下一次提交准备包含的内容。
- 本地仓库:已经提交的历史记录。
常用命令这样用:
git status
git status --short
git diff
git diff --cached
git add README.md
git add src/
git add -p
git commit -m "修复用户状态判断"
git log --oneline --decorate --graph -20git status 适合先看全局,git status --short 适合每天高频使用。git diff 看还没暂存的内容,git diff --cached 看准备提交的内容。这里要养成一个习惯:提交前不看 diff --cached,就不要急着敲 commit。
git add -p 适合一次文件里有多块修改,但你只想提交其中一部分。比如一个文件里既修了 bug,又顺手改了格式,这时可以用 git add -p 把真正的 bug 修复单独提交。团队协作里,提交越聚焦,代码审查和回滚越容易。
提交前建议固定检查:
git status --short
git diff
git diff --cached如果 git diff 还有内容,说明工作区里有未暂存修改。如果 git diff --cached 里出现配置文件、密钥、构建产物、日志文件,就先停下来处理。生产团队里,很多事故不是因为 Git 命令难,而是因为一个 .env、一个临时 SQL、一个本地配置被顺手提交了。
.gitignore 不等于安全
.gitignore 解决的是“哪些本地文件不应该进入版本库”。常见配置可以这样写:
target/
build/
dist/
out/
.idea/
*.iml
.vscode/
*.log
*.tmp
.env
.env.local
application-local.yml注意:.gitignore 只对未被 Git 跟踪的文件生效。如果文件已经提交过,后来再加 .gitignore 不会自动停止跟踪。这个坑很常见,很多人以为加了忽略规则,文件就不会再出现在提交里,其实不是。
停止跟踪但保留本地文件:
git rm --cached application-local.yml
git commit -m "移除本地环境配置跟踪"执行后用 git status --short 看,应该出现删除跟踪关系的记录,但本地文件还在。这里的目的不是删除你机器上的配置,而是让 Git 不再管它。
如果密钥、密码、token 已经提交到远程仓库,不要只删文件。正确动作是立刻更换泄露凭据,再评估是否需要重写历史和通知相关人员。历史清理是高风险操作,必须由仓库管理员统一处理。
clone 的生产约束
新同事拉代码、CI 节点拉代码、发布机拉代码,看起来都是 git clone,但要求不一样。先看最普通的克隆:
git clone git@example.com:team/demo.git执行成功后,进入目录执行:
cd demo
git remote -v
git branch --show-current
git log --oneline -5git remote -v 应该看到 origin 地址,git branch --show-current 应该看到默认分支,git log 应该能看到最近提交。这里能验证三件事:仓库拉下来了,远端地址没错,本地历史可用。
指定目录:
git clone git@example.com:team/demo.git demo-service指定分支,适合只处理某个发布分支:
git clone -b release/1.4.0 git@example.com:team/demo.git浅克隆,适合临时拉代码提速:
git clone --depth 1 git@example.com:team/demo.git这里要注意:--depth 1 只拿最近一层历史,速度快,但很多依赖历史的命令会受影响,比如 git describe、跨 tag diff、生成完整变更日志。临时构建可以用,正式发布基线要谨慎。
部分克隆,适合很大的仓库:
git clone --filter=blob:none git@example.com:team/large-repo.git只检出部分目录,适合单体大仓里只开发一个服务:
git clone --filter=blob:none --sparse git@example.com:team/mono-repo.git
cd mono-repo
git sparse-checkout set service-a common-lib执行后用下面的命令检查:
git sparse-checkout list
git status --shortgit sparse-checkout list 应该显示当前检出的目录。这里的常见坑是以为本地只有这些文件,远端就只有这些文件。不是这样,仓库历史仍然在远端,当前工作区只是选择性检出。
生产约束:
- 构建发布尽量使用完整历史或至少能拿到 tag,否则版本号、变更日志和回滚定位会受影响。
--depth 1适合临时构建提速,但不适合需要git describe、跨 tag diff、历史追溯的发布任务。- partial clone 需要远程仓库按需提供缺失对象,离线环境慎用。
- 服务器部署不建议直接
git pull到生产目录后裸跑,至少要固定 commit 或 tag,并留下构建产物和回滚方案。线上真正回滚时,能回滚制品就不要临时在服务器上改 Git 历史。
branch、checkout 和 switch
分支解决的是“每个人的修改先隔离起来”。开发新功能、修复 bug、准备发布、线上热修,都不要直接在同一条线上乱改。
先查看分支:
git branch
git branch -a
git branch -vvgit branch 看本地分支,当前分支前面会有 *。git branch -a 会把远程分支也列出来,git branch -vv 可以看到本地分支跟踪的是哪个远程分支,以及领先或落后几个提交。
创建并切换分支:
git switch -c feature/order-export执行后用下面命令验证:
git branch --show-current应该看到 feature/order-export。如果还在 main,说明分支没有切成功,先不要改代码。
旧写法:
git checkout -b feature/order-export切换已有分支:
git switch main
git switch -git switch - 表示切回上一个分支,排障时很好用。这里要注意,切换分支前最好先 git status --short,如果有未提交修改,Git 可能会阻止切换,或者把修改带到新分支上。
删除本地分支:
git branch -d feature/order-export
git branch -D feature/order-export-d 是安全删除,Git 会检查这个分支是否已经合并。-D 是强制删除,一般只在确认分支不再需要、或者已经有远程备份时使用。不要为了清爽随手 -D,很多误删分支都是这么来的。
删除远程分支:
git push origin --delete feature/order-export删除远程分支前,先确认 MR 已关闭或已合并,发布分支和热修复分支尤其要谨慎。远程分支是团队共享入口,不是个人本地缓存。
建立远程跟踪:
git push -u origin feature/order-export
git branch --set-upstream-to=origin/feature/order-export feature/order-export第一次推送新分支一般用 git push -u,后面就可以直接 git push。如果你看到提示 no upstream branch,通常就是忘了建立跟踪关系。
分支命名建议:
feature/order-export
bugfix/login-timeout
hotfix/1.4.1-login-500
release/1.4.0
test/payment-regression分支名要表达用途,不要用 test1、new、mybranch。分支是团队协作入口,名字越含糊,后续清理和排障越痛苦。生产团队里,热修复分支最好带版本号和故障特征,例如 hotfix/1.4.1-login-500,这样发布记录里一眼就能看出来它处理的是哪次事故。
fetch、pull 和 push
fetch 只拉取远程引用,不修改当前工作分支。排查分支关系时,先 fetch 比直接 pull 稳:
git fetch origin
git fetch --prune origingit fetch origin 会更新远端引用。git fetch --prune origin 会顺便清理本地已经失效的远程分支引用。执行后如果有人删除了远程分支,你本地的 origin/xxx 才会消失。
看远程和本地差异:
git log --oneline --decorate --graph --all -30
git log --oneline HEAD..origin/main
git log --oneline origin/main..HEAD第二条 HEAD..origin/main 表示远端比你多了哪些提交,第三条 origin/main..HEAD 表示你本地比远端多了哪些提交。这里看清楚以后,再决定 merge、rebase 还是 push。
pull 是拉取并集成。不要把 git pull 当成无脑同步按钮。团队要明确默认策略。
只允许快进:
git pull --ff-only--ff-only 的意思是只允许快进。如果本地和远端分叉,它会直接失败,不会自动生成合并提交。公共分支上推荐优先用这个,因为失败比悄悄合出一个奇怪历史更好排查。
本地个人分支基于远程主线变基:
git fetch origin
git rebase origin/main这两行适合个人功能分支。执行后用 git log --oneline --graph --decorate -20 看,自己的提交应该排在最新 origin/main 后面。
明确使用 merge:
git pull --no-rebase推荐策略:
main、release/*、hotfix/*这类公共分支,不在本地随意 rebase。- 个人
feature/*分支,合并前可以 rebase 到目标分支最新提交。 - 需要严格线性历史的团队,可以要求个人分支 rebase 后再发起 MR。
- 需要审计真实合并路径的团队,可以使用
merge --no-ff保留合并节点。
推送分支:
git push
git push -u origin feature/order-export第一次推送用 -u,后面普通 git push 就够了。推送成功后,代码平台上应该能看到这个分支,后续就可以创建 PR 或 MR。
被拒绝时常见提示是 non-fast-forward。不要第一反应就 --force。先执行:
git fetch origin
git log --oneline --graph --decorate --all -30这一步是看远程是不是被别人更新了。如果图上看到远端分支在你前面,先把别人的提交合进来或 rebase 过来,再推送。
如果确实是自己个人分支 rebase 后需要覆盖远程,优先使用:
git push --force-with-lease--force-with-lease 会检查远程分支是否被别人更新过,比裸 --force 更安全。但它仍然是重写远程历史,公共分支禁止使用。
merge 和 rebase 怎么选
merge 和 rebase 不要按喜好选,要按场景选。merge 的特点是保留分支汇合记录,适合公共分支集成、发布分支合并、需要审计合并行为的场景。
git switch main
git merge --no-ff feature/order-export执行后用下面命令看历史:
git log --oneline --graph --decorate -20如果看到一个合并节点,说明这次 merge --no-ff 把功能分支的合入动作保留下来了。发布分支、热修复分支一般需要这种可审计记录。
rebase 的特点是把一串提交重放到另一个基线之上,让历史更线性,适合个人分支在合并前同步主线。
git switch feature/order-export
git fetch origin
git rebase origin/main执行成功后,你的个人提交会排在最新主线后面。这里要注意,rebase 会改写提交 ID,所以已经推送并被多人使用的分支,不要随便 rebase 后强推。
核心规则:
个人分支可以 rebase,公共分支优先 merge。
已推送并被多人使用的分支,不要 rebase 后强推。如果 rebase 冲突,先看状态:
git status
# 修改冲突文件
git add path/to/file
git rebase --continue修完一个冲突提交以后,git rebase --continue 可能还会继续遇到下一个冲突,这是正常的。因为 rebase 是一笔一笔重放提交,不是一次性解决所有历史。
放弃本次 rebase:
git rebase --abort如果 merge 冲突,流程类似:
git status
# 修改冲突文件
git add path/to/file
git merge --continue放弃本次 merge:
git merge --abort冲突解决手册
冲突出现时,终端一般会直接告诉你哪个文件冲了。常见现象如下:
CONFLICT (content): Merge conflict in src/UserService.java
Automatic merge failed; fix conflicts and then commit the result.git status --short 可能看到:
UU src/UserService.javaUU 表示两边都改了这个文件,Git 不知道该怎么合。打开文件会看到三段冲突区域。实际文件中的标记分别是连续 7 个小于号加当前分支名、连续 7 个等号、连续 7 个大于号加来源分支名。为了避免示例被仓库检查误判为真实冲突,这里用可读占位符表示:
[当前分支开始] HEAD
当前分支内容
[分隔线]
被合并分支内容
[来源分支结束] feature/order-export处理步骤:
- 先确认自己在哪个分支:
git branch --show-current。 - 看冲突文件:
git status。 - 打开文件,人工合并业务逻辑。
- 编译或测试,确认合并后的代码可运行。
git add标记已解决。git merge --continue、git rebase --continue或git cherry-pick --continue。
实际处理时可以按这个顺序敲:
git status
git diff
# 修复冲突后
git add src/UserService.java
git status
git merge --continuegit diff 会显示冲突区域和你当前编辑后的内容。修完以后再执行 git status,如果这个文件不再显示 UU,说明 Git 已经认可你把冲突处理完了。
遇到复杂冲突时,不要只靠文本选择。先问三个问题:
- 两边改的是同一业务规则,还是不同功能碰到同一文件。
- 是否有配置、数据库字段、接口返回结构需要同步调整。
- 合并后是否要补单测、接口测试或回归用例。
选择当前分支或对方分支内容的命令可以应急使用:
git restore --ours path/to/file
git restore --theirs path/to/file
git add path/to/file注意:在 merge 和 rebase 过程中,ours、theirs 的语义容易让人误判。关键文件不要盲选,必须看 diff 和业务语义。比如权限判断、金额计算、订单状态流转这类代码,宁愿慢一点找业务负责人确认,也不要为了让 Git 状态变干净就选一边覆盖。
冲突未解决时想撤销:
git merge --abort
git rebase --abort
git cherry-pick --abort执行 abort 后再 git status,工作区应该回到冲突前的状态。如果还有文件残留,先别继续合并,确认是不是你冲突过程中手动创建的临时文件。
stash 临时保存现场
stash 适合临时切换任务。比如你正在改订单导出,线上突然来了登录 500,需要马上切 hotfix,但当前代码还没到可以提交的程度。这时不要把半成品硬提交到公共分支,可以先把现场临时收起来。
保存当前修改:
git stash push -m "wip: order export page"执行后再看:
git status --short
git stash list工作区应该变干净,git stash list 里能看到刚才那条 wip 记录。
包含未跟踪文件:
git stash push -u -m "wip: include new files"如果新建文件还没有 git add,普通 stash 不一定会带走它们,带 -u 才会包含未跟踪文件。这里要注意,stash 不是备份系统,重要代码不要长期只放在 stash 里。
查看:
git stash list
git stash show -p stash@{0}git stash show -p 会把 stash 里的补丁展示出来,恢复前先看一眼,避免拿错现场。
恢复但保留 stash:
git stash apply stash@{0}恢复并删除 stash:
git stash pop stash@{0}apply 恢复后 stash 记录还在,适合不确定能不能顺利恢复的情况。pop 恢复成功后会删除 stash,适合确认当前分支就是要接回这段修改。
删除:
git stash drop stash@{0}生产建议:
stash是个人临时工具,不是交付方式。- 长时间保存的重要工作不要只放 stash,应该提交到个人分支。
stash pop也可能冲突,冲突处理和 merge 类似,修完以后同样要git add。- 交接工作时不要说“代码在我 stash 里”,要推到远程分支。
cherry-pick 补丁搬运
cherry-pick 用于把某个提交搬到当前分支,常见于热修复、补丁回灌、跨版本修复。比如一个 bug 已经在 main 修好了,但生产还跑在 release/1.4.0,这时就可能要把那个修复提交搬到发布分支。
先确保工作区干净:
git status --short这里必须是干净的。如果还有本地修改,先提交、stash 或放弃修改。否则 cherry-pick 冲突时,你很难分清哪些是原来的半成品,哪些是搬运过来的补丁。
搬运一个提交:
git cherry-pick 2f4c8ab执行成功后会在当前分支生成一个新提交,内容来自 2f4c8ab,但提交 ID 会变。用下面命令确认:
git log --oneline -5
git show --stat HEAD搬运并在提交信息里保留来源:
git cherry-pick -x 2f4c8ab生产补丁建议加 -x,提交信息里会记录来源提交,后面追溯“这个补丁从哪搬来的”更方便。
冲突后继续:
git status
# 修复冲突
git add path/to/file
git cherry-pick --continue放弃:
git cherry-pick --abort生产建议:
- 从
main修复后 cherry-pick 到release/*,比只修 release 更安全。 - 热修复从生产基线分支或 tag 创建,修完后必须补回主线。
- 跨版本 cherry-pick 后要重新测试,因为上下文可能已经变了。能编译不代表业务语义一定对。
- 多个提交组成一个完整修复时,不要只 cherry-pick 其中一个。
tag 和发布基线
发布一定要有基线。最简单可靠的基线就是 tag。没有 tag 的发布,后面排障经常会变成“当时到底发的是哪份代码”的口水仗。
查看 tag:
git tag
git tag -l "v1.4.*"如果 git tag -l "v1.4.*" 能看到历史发布版本,说明团队至少有版本基线可查。没有 tag 的老项目,建议从下一次发布开始补,不要试图把所有历史版本凭记忆补齐。
创建 annotated tag:
git tag -a v1.4.0 -m "release: v1.4.0"推荐使用 annotated tag,因为它有 tag 信息、创建者和时间,比轻量 tag 更适合发布审计。
给指定提交打 tag:
git tag -a v1.4.0 2f4c8ab -m "release: v1.4.0"查看 tag:
git show v1.4.0
git rev-parse v1.4.0git show 应该能看到 tag 信息和对应提交,git rev-parse 会输出对象 ID。发布前把这个提交号写进发布记录,后面回滚、比对、追责都靠它。
推送 tag:
git push origin v1.4.0推送所有 tag:
git push origin --tags一般更推荐推送指定 tag,而不是无脑 --tags。如果本地残留了测试 tag,--tags 会一起推上去。
删除本地 tag:
git tag -d v1.4.0删除远程 tag:
git push origin --delete v1.4.0远程 tag 一旦被发布系统引用,删除或移动都要走团队确认。不要为了“改个版本号”私自删远程 tag,这比删一个普通分支影响更大。
生产约束:
- 发布 tag 原则上不可移动。打错 tag 要走团队确认流程。
- tag 命名建议统一,例如
v1.4.0、v1.4.1、v1.5.0-rc.1。 - 构建制品要记录 tag、commit id、构建时间、构建环境。
- 生产回滚时优先回滚到上一个通过验证的 tag 或制品。
- 高安全要求团队可以使用签名 tag,并在发布前验证签名。
签名 tag 示例:
git tag -s v1.4.0 -m "release: v1.4.0"
git verify-tag v1.4.0reset、restore 和 revert
这三个命令名字相近,但用途不同。这里先给一句经验:本地没推送的错误,用 restore 或 reset 整理;已经进公共分支的错误,用 revert 留痕回滚。
restore 用来恢复文件,不移动分支:
git restore src/UserService.java
git restore --staged src/UserService.java
git restore --source=HEAD~1 -- src/UserService.java第一行丢弃工作区里这个文件的修改;第二行把文件从暂存区拿出来但保留工作区修改;第三行从某个历史版本恢复这个文件。执行前先 git diff,否则很容易把自己刚写的代码恢复没了。
reset 会移动当前分支指针,适合本地提交修正:
git reset --soft HEAD~1
git reset --mixed HEAD~1
git reset --hard HEAD~1区别:
--soft 只回退提交,保留暂存区和工作区
--mixed 回退提交和暂存区,保留工作区,默认行为
--hard 回退提交、暂存区和工作区,本地修改会丢这里要特别小心 reset --hard。执行前至少看两眼:
git status --short
git log --oneline -5如果工作区还有重要修改,先不要 hard reset。很多“代码突然没了”的现场,最后都能追到一次没看状态的 reset --hard。
revert 会新增一个反向提交,适合公共分支回滚:
git revert 2f4c8ab
git push origin main执行后历史里会多一个“反向提交”,原提交还在,但效果被撤销。这个方式适合公共分支,因为团队成员正常 pull 就能拿到回滚结果,不需要大家一起处理重写历史。
回滚 merge commit 需要指定主线父提交:
git revert -m 1 <merge_commit_id>这里的 -m 1 不是固定魔法值,含义是选择哪个父提交作为主线。真正操作前建议先在临时分支演练:
git switch -c test/revert-merge
git revert -m 1 <merge_commit_id>生产规则:
- 未推送的个人提交,可以用
reset整理。 - 已推送到公共分支的提交,优先用
revert。 reset --hard前先确认git status和git log --oneline -5。- 回滚 merge commit 前要看清父提交,必要时在临时分支演练。
误操作后先看 reflog:
git reflog
git switch -c rescue/restore 2f4c8abreflog 经常能救回本地误 reset、误 checkout、误 rebase 后的提交。但它不是永久备份,远程协作还是要靠及时推送分支和 tag。
推荐团队分支模型
团队不要照搬模型名字,先看发布节奏和质量门禁。分支模型没有绝对高级,能稳定发布、能快速回滚、能让修复不丢,才算适合。
小团队和高频发布
小团队、微服务、SaaS 项目,如果测试和发布自动化比较成熟,可以简单一点:
main
feature/*
hotfix/*
tag开发一个功能时按这个流程:
git switch main
git pull --ff-only
git switch -c feature/order-export
# 开发、提交、推送、MR
git push -u origin feature/order-export执行后去代码平台看,应该能看到 feature/order-export 分支,然后创建 MR。这里不要直接把 feature 推到 main,哪怕团队只有两三个人,也要留评审入口。
合并到 main 后由流水线部署测试或生产,发布时打 tag:
git switch main
git pull --ff-only
git tag -a v1.4.0 -m "release: v1.4.0"
git push origin v1.4.0执行后用下面命令确认 tag 已经在远端:
git ls-remote --tags origin v1.4.0能看到一行 tag 记录,说明发布基线已经推上去了。
适合:SaaS、小型微服务、自动化测试较完善、可以小步快跑的团队。
风险:主线必须一直可部署,测试和代码审查不能松。
中大型团队和阶段发布
中大型团队、固定版本窗口、测试周期比较长,就需要多一条集成分支和发布分支:
main
develop
feature/*
release/*
hotfix/*
tag开发阶段:
git switch develop
git pull --ff-only
git switch -c feature/order-export准备发布时,从 develop 拉出发布分支:
git switch develop
git pull --ff-only
git switch -c release/1.4.0
git push -u origin release/1.4.0发布分支只做发布修复,不再塞新功能。这里要注意,如果发布分支已经进入测试阶段,新需求继续往里塞,最后一定会变成“测试永远测不完”。
测试通过后,把发布分支合入 main 并打 tag:
git switch main
git pull --ff-only
git merge --no-ff release/1.4.0
git tag -a v1.4.0 -m "release: v1.4.0"
git push origin main
git push origin v1.4.0
git switch develop
git pull --ff-only
git merge --no-ff release/1.4.0
git push origin develop最后再把发布分支合回 develop,目的是把发布期间修的 bug 回灌到开发线。很多团队线上修复丢失,就是这一步漏了。
适合:多团队协作、版本窗口明确、测试周期较长、需要并行维护多个版本的项目。
风险:分支多,合并和回灌必须严格执行,否则修复会丢。
热修复流程
线上 v1.4.0 出问题,不要先在 main 上乱改。先从生产基线创建 hotfix,这样你修的是“线上正在跑的那份代码”:
git fetch origin --tags
git switch -c hotfix/1.4.1-login-500 v1.4.0
# 修复、提交、测试
git commit -m "修复登录接口空指针"
git push -u origin hotfix/1.4.1-login-500这里的分支名带上 1.4.1 和故障现象,后面看发布记录会很清楚。修完以后先在 hotfix 分支跑最小验证,比如编译、单测、关键接口回归。
验证通过后合并到 main 并打新 tag:
git switch main
git pull --ff-only
git merge --no-ff hotfix/1.4.1-login-500
git tag -a v1.4.1 -m "release: v1.4.1"
git push origin main
git push origin v1.4.1访问发布系统或制品仓库时,应该能看到新的 v1.4.1 构建入口。Git 这里只是把基线准备好,真正上线还要看你的部署系统是否已经使用这个 tag 或对应 commit 构建。
再补回开发分支:
git switch develop
git pull --ff-only
git merge --no-ff hotfix/1.4.1-login-500
git push origin develop如果没有 develop,就确认修复已经在当前主线里。热修复最常见事故是只修了生产版本,下一次正常发布又把问题带回来。
发布和回滚策略
Git 回滚要和部署回滚分开看。线上已经出故障时,第一目标是让服务恢复,不是先把 Git 历史整理得漂亮。
优先回滚制品
如果系统通过镜像、jar、静态包、部署包发布,线上故障优先考虑回滚到上一份已验证制品,而不是先改 Git 历史。原因很简单:制品是已经构建好的结果,回滚路径短;Git 改完还要重新构建、测试、发布,现场时间往往不允许。
回滚前确认:
git describe --tags --always
git rev-parse HEAD
git show --stat --oneline HEAD这三条命令用来确认当前代码基线。git describe --tags --always 看当前提交离哪个 tag 最近,git rev-parse HEAD 拿完整提交号,git show --stat 看这次提交改了哪些文件。
发布记录至少保存:
应用名称
环境
tag
commit id
构建号
构建时间
发布人
验证结果
回滚入口用 revert 修复公共历史
如果错误提交已经进入 main,不要在公共分支上 reset --hard 后强推。一般用 revert:
git switch main
git pull --ff-only
git revert <bad_commit_id>
git push origin main执行后会生成一个新的回滚提交。推送成功后,要重新触发构建或发布,让生产环境真正跑到回滚后的代码。
如果错误来自一个合并提交:
git revert -m 1 <merge_commit_id>
git push origin main回滚后要做两件事:
- 打一个修复 tag 或重新触发发布,让生产环境真正使用回滚后的代码。
- 明确原功能是否后续重做,避免下一次合并又把同样代码带回来。
本地误提交回退
最后一次提交信息写错,而且还没推送,可以改:
git commit --amend -m "修复订单导出空状态"最后一次提交内容需要拆开,而且还没推送,可以退回到工作区重新分批提交:
git reset --mixed HEAD~1
git add -p
git commit -m "调整订单导出查询条件"
git add -p
git commit -m "补充订单导出单测"已经推到公共分支后,不要用 amend 加强推。公共历史一旦被别人拉走,重写历史就会让所有协作者一起处理冲突。
中国大陆、内网和离线环境
公网受限
中国大陆和企业内网里,Git 问题经常不是命令写错,而是网络路径不稳定。常见问题:
- Git 官网、GitHub、国外包源访问慢或不可达。
- SSH 22 端口被限制。
- HTTPS 需要企业代理或证书。
- 开发机能访问,服务器和 CI 节点不能访问。
一般建议这样做:
- Git 安装包进入企业软件仓库,并记录版本和校验值。
- 代码托管使用企业 GitLab、Gitea、Gerrit 或云厂商代码仓库。
- 外部开源仓库通过内网镜像同步,不让生产构建临时访问外网。
- 代理配置纳入环境说明,不写进仓库。
- SSH 和 HTTPS 都准备一套排障命令。
查看远程地址:
git remote -v如果看到的是外网地址,而服务器或 CI 节点没有外网权限,就要切到内网地址。
切换远程地址:
git remote set-url origin git@example.com:team/demo.git执行后再 git remote -v,应该看到新的内网地址。这里不要把代理账号、token、临时密码写进仓库配置文件,代理配置放在机器或 CI 密钥配置里。
离线传输完整仓库
用 git bundle 可以在没有 Git 服务直连的环境里传输提交历史。它比 zip 包更适合离线协作,因为 bundle 里有 Git 提交历史和引用,离线侧可以继续 log、branch、merge。
联网侧创建完整 bundle:
git clone --mirror git@example.com:team/demo.git demo.git
cd demo.git
git bundle create demo-full.bundle --all
sha256sum demo-full.bundle > demo-full.bundle.sha256这里 --mirror 会把远端仓库按镜像方式拉下来,适合做离线分发源。sha256sum 是为了传输前后校验,离线介质拷贝过程中出错时能及时发现。
离线侧校验并克隆:
sha256sum -c demo-full.bundle.sha256
git bundle verify demo-full.bundle
git clone demo-full.bundle demo
cd demo
git log --oneline --decorate --graph -10sha256sum -c 应该显示 OK,git bundle verify 应该提示 bundle 可用。克隆后能看到最近提交,说明这份离线仓库已经可以正常使用。
增量同步可以用 tag 记录上次同步点:
git tag -f last-offline-sync main
git bundle create demo-incr.bundle last-offline-sync..main离线侧拉取:
git bundle verify demo-incr.bundle
git pull demo-incr.bundle main如果 git bundle verify 提示缺少前置对象,说明离线侧没有增量包需要的历史基础。这时不要硬拉,重新做完整 bundle,或者确认上一次同步点是否一致。
生产约束:
- bundle 只包含可达提交和引用,不包含工作区、暂存区、本地配置、hooks、未提交文件。
- 传输前后都要做校验。
- 增量 bundle 需要接收方已有前置提交,否则 verify 会失败。
- 离线环境也要保留 tag 和提交号,不能只传 zip 包。否则出了问题只能靠文件时间猜版本。
只交付源码快照
如果不需要 Git 历史,只需要某个版本源码包,可以用 git archive:
git archive --format=tar.gz --prefix=demo/ -o demo-v1.4.0.tar.gz v1.4.0
sha256sum demo-v1.4.0.tar.gz > demo-v1.4.0.tar.gz.sha256解压后应该只有源码文件,没有 .git 目录。git archive 适合发布源码快照,不适合团队继续协作开发。因为它没有 .git 历史,不能继续 pull、merge、rebase。
多人协作规范
分支保护
多人协作里,分支保护是底线。建议保护这些分支:
main
develop
release/*
hotfix/*保护规则至少包含:
- 禁止直接 push。
- 禁止 force push。
- 合并前必须通过代码审查。
- 合并前必须通过构建和测试。
- tag 发布需要负责人确认。
如果平台支持 CODEOWNERS、必需状态检查、签名提交、线性历史,可以按团队成熟度逐步开启。
这里要注意,分支保护不是为了卡人,而是为了防止误推、强推、绕过测试这类低级事故。越是生产主线,越不能依赖“大家自觉”。
提交前检查
提交前固定执行:
git status --short
git diff
git diff --cached这三条命令是提交前的刹车。git status --short 看文件范围,git diff 看还没暂存的内容,git diff --cached 看马上要提交的内容。
后端项目至少本地编译一次:
mvn test
# 或
gradle test前端项目至少执行:
npm test
npm run build如果项目测试很慢,也要有最小检查命令。不能把明显编译失败的代码推给别人。
提交信息
提交信息要说明意图,不只说动作。后面排查线上问题时,大家看的往往不是你当时的聊天记录,而是 Git 历史。
不推荐:
update
fix
修改代码
临时提交推荐:
新增订单导出参数校验
修复登录超时后重复跳转
调整用户状态字段兼容历史数据如果团队有任务系统,可以统一格式:
task#1234 新增订单导出参数校验
bug#5678 修复登录超时后重复跳转提交粒度建议:
- 一个提交只解决一个清晰问题。
- 格式化、重命名、业务修改分开提交。
- 大范围迁移先单独说明和评审。
- 不把调试日志、无关配置、IDE 文件混入业务提交。
代码评审前自查
发起 MR 前自查:
git fetch origin
git rebase origin/main
git status --short
git log --oneline origin/main..HEAD
git diff --stat origin/main...HEADgit log origin/main..HEAD 应该只看到本次任务相关提交。git diff --stat 应该只出现本次任务相关文件。如果这里冒出一堆格式化、临时配置、无关重命名,先拆提交或清理分支。
确认:
- 分支基于正确目标分支。
- 提交列表干净,没有临时提交。
- 变更文件符合任务范围。
- 本地构建或测试已通过。
- 冲突已经解决,不把冲突标记提交进去。
检查冲突标记:
git grep -n "<<<<<<<\\|=======\\|>>>>>>>"如果确实需要这些字符出现在文档或测试数据里,要人工确认。
常见故障排查
Permission denied publickey
现象:
Permission denied (publickey).
fatal: Could not read from remote repository.排查:
git remote -v
ssh -T git@example.com
ls ~/.ssh原因通常是公钥没配置、远程地址写错、SSH 端口被拦、使用了错误 key。
如果 ssh -T 失败,但 git remote -v 是 HTTPS 地址,说明你排错方向错了。先确认当前仓库到底用 SSH 还是 HTTPS。
Authentication failed
HTTPS 认证失败时,先确认是否需要 token 而不是密码:
git remote -v
git config --global --get credential.helperWindows 可能缓存了旧凭据,需要到凭据管理器清理。Linux CI 节点不要把 token 写进仓库,可以用环境变量或平台凭据管理。
push 被拒绝
现象:
! [rejected] main -> main (non-fast-forward)处理:
git fetch origin
git log --oneline --graph --decorate --all -30先看图,不要急着 force。被拒绝通常说明远端有你本地没有的提交,或者你本地重写过历史。
个人分支:
git rebase origin/main
git push --force-with-lease公共分支:
git pull --ff-only
# 如果失败,说明历史分叉,需要负责人判断 merge、revert 或人工修复本地修改阻止切换分支
现象:
Your local changes to the following files would be overwritten by checkout选择一:提交:
git add .
git commit -m "临时保存当前任务"如果这段代码已经有清晰意义,优先提交到个人分支。
选择二:stash:
git stash push -u -m "wip: before hotfix"如果只是临时切走处理问题,stash 更合适。
选择三:确认不要了再丢弃:
git restore path/to/file这一步会丢弃文件修改,执行前先 git diff path/to/file 看清楚。
detached HEAD
现象:
HEAD detached at v1.4.0如果只是查看 tag,没问题。若在 detached HEAD 上做了提交,先创建分支保住:
git switch -c fix/from-detached创建分支后再 git log --oneline -5,确认刚才的提交还在新分支上。
dubious ownership
现象:
detected dubious ownership in repository先确认仓库来源和目录权限。如果是可信仓库,再添加安全目录:
git config --global --add safe.directory /path/to/repo不要对未知来源仓库随便加全局信任。
大文件误提交
先看提交里有哪些大文件:
git ls-files -s
git log --stat --oneline如果还没推送:
git reset --mixed HEAD~1
git rm --cached path/to/big-file
echo "path/to/big-file" >> .gitignore
git add .gitignore
git commit -m "移除误提交大文件"这里要注意:示例里 echo 只是演示把文件加入忽略规则,正式项目最好手动编辑 .gitignore,确认规则不会误伤其它文件。
如果已经推送公共分支,先通知团队。重写历史会影响所有协作者,不能私自操作。
常用命令速查
初始化和配置:
git init
git config --global user.name "zhangsan"
git config --global user.email "zhangsan@example.com"
git config --global init.defaultBranch main
git config --global --list拉取和远程:
git clone git@example.com:team/demo.git
git remote -v
git remote add origin git@example.com:team/demo.git
git remote set-url origin git@example.com:team/demo.git
git fetch --prune origin提交:
git status --short
git diff
git add .
git add -p
git diff --cached
git commit -m "提交说明"
git commit --amend -m "新的提交说明"分支:
git branch -a
git branch -vv
git switch -c feature/demo
git switch main
git push -u origin feature/demo
git branch -d feature/demo
git push origin --delete feature/demo同步和合并:
git pull --ff-only
git rebase origin/main
git merge --no-ff feature/demo
git merge --abort
git rebase --aborttag:
git tag
git tag -a v1.4.0 -m "release: v1.4.0"
git show v1.4.0
git push origin v1.4.0回滚:
git restore path/to/file
git restore --staged path/to/file
git reset --soft HEAD~1
git reset --mixed HEAD~1
git reset --hard HEAD~1
git revert <commit_id>
git reflog临时保存和补丁搬运:
git stash push -u -m "wip: message"
git stash list
git stash apply stash@{0}
git stash pop stash@{0}
git cherry-pick -x <commit_id>排查:
git log --oneline --decorate --graph --all -30
git show <commit_id>
git diff origin/main...HEAD
git grep -n "keyword"
git fsck落地工程深水区
Git 在生产交付里的深水区,不是某个命令多复杂,而是“代码状态”能不能成为团队共同认可的发布事实。没有这个事实,回滚、审计、复盘都会失真。
第一是发布基线。上线记录里必须有 commit id、tag、构建号、镜像 tag 或制品 checksum。只写“发布最新版”没有意义。出问题时,先回滚已验证制品,再决定是否用 Git revert 修复公共历史。不要在公共分支上用 reset --hard 改历史,除非团队明确进入事故处理流程。
第二是分支保护。main/master、release、hotfix 这些公共分支必须限制直接 push。至少要求代码评审、CI 通过、线性历史或受控 merge 策略。否则 Git 会从协作工具变成事故放大器。
第三是凭证和仓库权限。Git token、SSH key、部署密钥要分用途管理。个人 key 不要放到 CI;CI key 不要有全组织写权限;只读拉代码的服务器不应该拥有推送权限。权限变更时要能追溯是谁、何时、为了哪个仓库授权。
第四是内网和离线交付。离线环境不能只发 zip 包,至少要保留 commit id、tag、git bundle 或源码归档校验和。只发源码快照会丢失历史、tag 和变更范围,后面无法证明生产运行的是哪一版。
第五是大文件和敏感信息。.gitignore 不能保护已经提交过的密钥、证书和大文件。提交前要有 secret scan 和大文件检查;误提交后要立即吊销密钥,不能只从 Git 历史里删除。清理历史属于高风险动作,要先备份仓库并通知所有协作者重新同步。
第六是团队节奏。发布分支、热修分支、回合主线、tag 命名、提交信息格式要固定下来。否则每次发布都要重新讨论“从哪个分支出包、修复合到哪里、tag 谁来打”,真正故障发生时就会拖慢止血。
发布前检查清单
发布前:
- 当前分支正确:
git branch --show-current。 - 工作区干净:
git status --short无未提交变更。 - 目标分支已同步:
git pull --ff-only。 - 提交范围正确:
git log --oneline <last_tag>..HEAD。 - 变更文件合理:
git diff --stat <last_tag>...HEAD。 - 构建和测试通过。
- tag 名称符合规范。
- 发布记录包含 commit id、tag、构建号和回滚入口。
发布后:
- 确认生产运行版本:
git rev-parse HEAD或制品元信息。 - 确认 tag 已推送:
git ls-remote --tags origin v1.4.0。 - 验证核心接口、日志、指标和异常告警。
- 如果发布分支有修复,确认已合并回主线。
- 清理已合并 feature 分支。
故障时:
- 先止血,优先回滚到上一份已验证制品或 tag。
- 记录故障版本、回滚版本、操作人和验证结果。
- Git 层面优先
revert公共提交,不私自重写公共历史。 - 热修复后必须补回主线,避免下次发布复发。
官方文档入口
- Git 安装入口:https://git-scm.com/install/
- Git for Windows:https://git-scm.com/install/windows
- Git 官方参考:https://git-scm.com/docs
- Pro Git Book:https://git-scm.com/book/en/v2
- 分支与
switch:https://git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell pull:https://git-scm.com/docs/git-pulltag:https://git-scm.com/book/en/v2/Git-Basics-Taggingstash:https://git-scm.com/book/en/v2/Git-Tools-Stashing-and-Cleaningcherry-pick:https://git-scm.com/docs/git-cherry-pickbundle:https://git-scm.com/docs/git-bundlearchive:https://git-scm.com/docs/git-archive
