commit

1
2
3
git add . //把当前修改全部加入暂存区(也可指定文件)
git commit -m "msg" //提交并添加提交信息 msg(-m 是 message)
git commit --amend //修改上一条 commit(覆盖,不适用于已 push)

🌿 branch

1
2
3
4
5
6
git branch //查看现有分支
git branch feature/foo //创建分支 feature/foo
git checkout feature/foo //切换到 feature/foo 分支
git checkout -b feature/foo //创建 + 切换到 feature/foo
git branch -d feature/foo //删除分支(如果已 merge)
git branch -D feature/foo //强制删除分支(未 merge)

🔀 merge

1
2
3
4
git checkout main //切换到 main
git merge feature/foo //把 feature/foo 合并到 main
git merge --no-ff feature/foo //禁止 fast-forward 合并(保留 merge commit)
git merge --abort //冲突时放弃 merge

📍 rebase

1
2
3
4
5
git checkout feature/foo //切 feature 分支
git rebase main //让 feature/foo 基于 main 最新提交
git rebase --abort //中止 rebase(遇冲突)
git rebase --continue //解决冲突后继续
git rebase -i HEAD~5 //交互式 rebase(整理最近 5 次 commit)

🔁 同步远程(配合 rebase)

1
2
3
git pull //拉取并 merge(默认)
git pull --rebase //拉取并 rebase(更线性)
git push //推送到远程

rebase 注意点

1
2
git push --force //强制推送(改历史后要用,会覆盖远程)
git push --force-with-lease //更安全版本的强推

好的,继续用同样风格总结 + 命令 + 注释,简洁明了。


🧩 分离 HEAD(detached HEAD)

🔸现象解释:HEAD 不指向 branch,而直接指向某个 commit
🔸用途:临时查看老版本、测试、构建

1
2
git checkout <commit_id> //切到某个 commit(进入 detached HEAD)
git checkout main //离开 detached HEAD 回到 main

🎯 相对引用 ^

^ 表示:「父提交」

1
2
3
HEAD^ //HEAD 的父提交
HEAD^^ //HEAD 的父的父
HEAD^2 //对于 merge commit,用 ^N 表示第 N 个父

举例:

1
git checkout HEAD^ //回到上一个提交

🎯 相对引用 ~

~ 表示:「第 N 个父提交(只沿主线)」

1
2
3
HEAD~1 //等同 HEAD^
HEAD~2 //主线往上 2 次父提交
HEAD~5 //往上 5 个提交

区别点:

1
2
^ 表示父提交分支
~ 表示主线父提交

merge commit 时特别明显。


🔁 撤销变更(工作区、暂存区、历史)

1. 撤销工作区未 add 的改动

1
2
git checkout -- <file> //撤销指定文件改动(恢复到最近 commit)
git checkout -- . //全部撤销

2. 撤销已 add 但未 commit

1
2
git reset <file> //取消 add,回到工作区
git reset //取消所有 add

3. 撤销 commit(保留工作区)

1
2
3
git reset --soft HEAD^ //撤销上一条 commit,改动保留在暂存区
git reset --mixed HEAD^ //撤销 commit + 暂存,改动回工作区(默认)
git reset --hard HEAD^ //撤销 commit 并丢弃变更(危险!)

4. 已 push 的错误提交(用 revert)

1
git revert <commit> //生成新的反向提交,安全撤销

👉 revert 优点:不会改历史 → 适合多人协作


🧱 撤销 vs 回退 总结

操作 是否改历史 是否丢数据 是否适合多人
checkout – ⚠ 可能
reset ⚠ 看模式
revert

🍒 Git Cherry-pick

🔹 作用:把某个 commit 的改动“挑过来”应用到当前分支
🔹 用途:单独拣选某次提交到其他分支,不需要 merge 整条分支

1
2
3
4
5
git checkout main //切到目标分支
git cherry-pick <commit_id> //把指定 commit 的改动应用到当前分支
git cherry-pick <commit1> <commit2> //一次挑选多个 commit
git cherry-pick --continue //解决冲突后继续 cherry-pick
git cherry-pick --abort //放弃 cherry-pick

💡 特点

  • 会生成新的 commit(和原 commit 内容一样,但 commit id 不同)
  • 不会改变原分支历史
  • 常用于 hotfix / 补丁

🛠 交互式 rebase(interactive rebase)

🔹 作用:整理/修改分支历史(改 commit 顺序、合并、删除、修改提交信息)
🔹 命令

1
2
git checkout feature/foo //切到要整理的分支
git rebase -i HEAD~5 //整理最近 5 次提交(交互式)

🔹 交互界面常用操作

1
2
3
4
5
6
pick <commit_id>  //保留该 commit
reword <commit_id> //修改提交信息
edit <commit_id> //修改 commit 内容(停下来手动改)
squash <commit_id> //把该 commit 合并到前一个 commit(保留信息)
fixup <commit_id> //把该 commit 合并到前一个 commit(丢弃信息)
drop <commit_id> //删除该 commit

🔹 后续操作

1
2
3
git rebase --continue //解决冲突后继续
git rebase --abort //放弃 rebase
git push --force-with-lease //rebase 后推送远程分支(改历史需强推)

💡 特点

  • 历史线性化,更干净
  • 可以修改提交顺序、信息、合并多个 commit
  • 危险:不要对已 push 给别人的分支 rebase

🔁 Cherry-pick vs 交互式 rebase

对比点 cherry-pick interactive rebase
改变历史 不改原分支历史 改变当前分支历史
是否生成新 commit 是(新 commit id) 可修改或合并 commit
用途 拣选单个/少量 commit 整理整个分支历史
协作风险 高(慎用已 push 分支)

🏷 Git Tag

🔹 作用:给某个 commit 打上“标记”,通常用于发布版本或里程碑
🔹 特点:不会像分支一样移动,固定指向某个 commit

1
2
3
4
5
6
7
8
9
10
11
12
13
git tag //查看本地所有 tag
git tag -l "v1.*" //查看符合模式的 tag

git tag v1.0 //给当前 commit 打轻量 tag
git tag -a v1.0 -m "版本 1.0" //打带注释的 tag(推荐)
git tag -a v1.0 <commit_id> -m "版本 1.0" //给指定 commit 打 tag

git show v1.0 //查看 tag 对应的 commit 信息
git tag -d v1.0 //删除本地 tag

git push origin v1.0 //推送 tag 到远程
git push origin --tags //推送所有 tag
git fetch --tags //拉取远程 tag

💡 补充

  • 轻量 tag:仅仅是指向 commit 的指针
  • **带注释 tag (-a)**:是完整对象,可保存作者、时间、信息

🔍 Git Describe

🔹 作用:根据最近的 tag 来描述当前 commit 的信息,常用于生成版本号
🔹 特点:输出可读版本信息,比直接 commit id 更友好

1
2
3
4
git describe //显示距离最近 tag 的描述(默认最近可达 tag + 后续提交数量 + 简短 commit id)
git describe --tags //强制使用带注释 tag
git describe --abbrev=8 //设置 commit id 缩短长度(默认 7 位)
git describe --all //显示分支/远程引用描述

💡 例子

1
v1.0-3-g9fceb02

解释:

  • v1.0 → 最近的 tag
  • 3 → 从 tag 后到当前 commit 的提交数量
  • g9fceb02 → 当前 commit 的缩短 hash

用途

  • 自动生成版本号
  • CI/CD 构建时标记构建版本
  • 跟踪某个提交距离最近的发布版本

🔁 总结 Tag vs Describe

命令 作用 输出/特性 用途
git tag 标记 commit tag 名 发布版本、里程碑
git describe 基于最近 tag 描述 commit v1.0-3-gxxxx 生成版本号、追踪提交

🌀 1. Git Clone

🔹 作用:从远程仓库克隆一份完整本地仓库(包括 commit 历史、分支、tag)

1
2
git clone <repo_url> //克隆远程仓库到本地
git clone <repo_url> <folder_name> //克隆到指定文件夹

💡 特点

  • 会自动创建 origin 指向远程
  • 默认会切到远程默认分支(一般是 main/master)

📥 2. Git Fetch

🔹 作用:从远程拉取最新 commit / branch / tag 到本地,但不合并到当前分支

1
2
3
git fetch //拉取所有远程更新(仅更新本地远程引用)
git fetch origin //只拉取 origin 仓库
git fetch origin main //只拉取远程 main 分支

💡 特点

  • 安全,不改动当前工作区
  • 拉取后需要手动 merge 或 rebase

📦 3. Git Pull

🔹 作用:fetch + merge(默认)或者 fetch + rebase(可选)
🔹 命令

1
2
3
git pull //拉取远程更新并 merge 到当前分支
git pull --rebase //拉取远程更新并 rebase 到当前分支(线性历史)
git pull origin main //只拉取 origin 的 main 并合并

💡 特点

  • 快速同步远程到本地
  • 如果本地修改和远程冲突,会提示解决冲突

📤 4. Git Push

🔹 作用:把本地提交推送到远程分支

1
2
3
4
git push //推送当前分支到远程对应分支
git push origin main //推送 main 分支到 origin
git push --force //强制推送(改历史后用)
git push --force-with-lease //安全强制推送(仅当远程未更新时生效)

💡 注意点

  • 已 push commit 不建议随意 reset/rebase
  • 多人协作常规用 pull + push
  • CI/CD 自动化常依赖 push

偏离的提交历史(Diverged History)

🔹 现象:本地分支和远程分支都有新的 commit,彼此不在同一条直线上

1
git status //提示 “Your branch and 'origin/main' have diverged”

🔹 解决方式

  1. merge(保留历史)
1
git pull //默认 merge
  1. rebase(线性化历史)
1
git pull --rebase //把本地提交放到远程最新之后

💡 提示

  • merge 保留分叉历史,冲突后生成 merge commit
  • rebase 历史线性,但改写 commit,慎用已 push 分支

🔒 锁定的 Main(Locked Main)

🔹 概念:公司或开源仓库为了保护主分支,禁止直接 push
🔹 常见策略

  • 设置保护分支(Protected Branch)
  • 必须通过 Pull Request / Review 才能合并
  • 阻止 force push
1
git push origin main //如果 main 被锁定,会被拒绝

💡 开发流程建议

  • 个人开发 → 新建 feature 分支
  • 完成 → 提交 PR → 审核通过 → merge 到 main
  • 避免直接修改 main

🔁 总结工作流(锁定 Main + 避免偏离历史)

1
2
3
4
5
6
7
git clone <repo>           //克隆仓库
git checkout -b feature/foo //创建新功能分支
...开发+commit...
git fetch //拉取远程更新
git rebase origin/main //把本地分支放到 main 最新之后
git push origin feature/foo //推送 feature 分支
...发 PR 审核...

主分支 main 锁定,所有开发都通过 feature 分支 + PR 流程合并,避免冲突和偏离历史。


顺序按照learngitbranching的关卡总结,做一名仁慈的独裁者一定会很有趣…… 并未包含在内。

参考资料

https://learngitbranching.js.org/?locale=zh_CN