git checkout -b 一步创建并切换分支,如 git checkout -b feature/user-auth;可指定起点如 git checkout -b hotfix/login-error main;推荐用 git switch -c 替代,但 -b 仍完全可用。

git checkout -b 会悄悄覆盖已有分支名
很多人以为 git checkout -b 只在分支不存在时才创建,其实它只要本地没这个分支,就直接新建;但如果你本地删了分支、远程还有同名分支,再用 git checkout -b feature/login,它不会拉远程的,而是新建一个空的本地分支——这会导致后续 git push 直接推空历史,覆盖远程分支指针。
正确做法是优先用 git switch(Git 2.23+):
git switch feature/login
它会自动匹配远程同名分支(如 origin/feature/login)并建立跟踪;如果本地没有、远程有,就检出并设置 upstream;如果都不存在,才报错,避免误操作。
- 旧 Git 版本可用
git checkout --track origin/feature/login替代 - 别依赖
git branch -D后随手checkout -b—— 先git fetch确认远程状态 - CI/CD 脚本里禁止用
checkout -b创建“预期已存在”的分支
rebase vs merge:谁该负责清理提交历史
不是“用了 rebase 就更干净”,而是要看谁掌握合并权。主干(如 main 或 develop)的维护者应决定是否允许 rebase,普通开发者只管把功能分支做干净——哪怕用 git commit --amend 或 git rebase -i HEAD~3 把调试日志、临时注释、格式修复等提交压平。
关键分界点:
- 功能分支内部:鼓励交互式 rebase 整理逻辑粒度,比如把 “fix typo” 和 “add null check” 合进对应的功能提交
- 向
main合并时:如果项目约定用 merge,就git merge --no-ff feature/login,保留分支边界;如果约定用 rebase,则由 maintainer 执行git rebase main feature/login再 fast-forward 合入,而非让开发者自己 rebase 后 force-push - force-push 在共享分支(如
release/2.1)上是危险操作,除非团队明确授权且全员同步了重写后的 ref
git diff origin/main...HEAD 的三个点不是笔误
多分支并行时,常用 git diff 比较差异,但 origin/main..HEAD(两个点)和 origin/main...HEAD(三个点)语义完全不同:
-
origin/main..HEAD:显示从origin/main到HEAD的所有提交引入的变更(即当前分支独有的提交 diff) -
origin/main...HEAD:显示origin/main和HEAD的共同祖先(merge base)到HEAD的 diff —— 这才是“我这个分支真正改了什么”,排除掉上游已合并但本地还没 fetch 的干扰 - CI 流水线校验代码变更范围时,必须用三个点,否则可能漏判或误报(例如
main刚合入一个 PR,你的分支还没git fetch,两个点会把那个 PR 的改动也算进你的 diff)
feature 分支命名要带上下文,不是为了好看
像 feat-user-auth 看似规范,但多人并行时容易冲突或歧义。实际协作中,分支名是轻量级上下文载体,应该包含可定位的信息:
- 建议格式:
feat/<user>/<ticket-id>-short-desc</ticket-id></user>,例如feat/alex/JIRA-123-login-flow - 好处:PR 标题自动继承、Git hooks 可校验 ticket 存在、
git branch --format筛选方便(git branch | grep "JIRA-123")、避免git push --all误推测试分支 - 禁止用模糊词:
fix、update、temp—— 它们无法被检索、无法被归因、无法被审计 - 分支生命周期结束后,不要仅靠
git branch -d删除本地分支,顺手git push origin :feat/alex/JIRA-123-login-flow清理远端(冒号前空格不能少)
分支策略最易被忽略的其实是“谁来触发同步”——不是等 CI 报错才去 git fetch,而是在每次 git switch main 前,自动执行 git fetch origin main:main;不是靠人记着 rebase,而是用 hub pull-request --browse 类工具把分支状态可视化。机制比约定更可靠。


















