Git 操作笔记

Git 操作笔记

  • [Git 完整操作笔记](#Git 完整操作笔记)
    • [一、Git Commit(提交)](#一、Git Commit(提交))
    • [二、Git Branch(分支)](#二、Git Branch(分支))
    • [三、Git Merge(合并)](#三、Git Merge(合并))
    • [四、Git Rebase(变基)](#四、Git Rebase(变基))
    • [五、HEAD 与分离 HEAD](#五、HEAD 与分离 HEAD)
    • 六、相对引用
    • 七、撤销变更
      • [7.1 git reset(本地撤销,改写历史)](#7.1 git reset(本地撤销,改写历史))
      • [7.2 git revert(安全撤销,可推送)](#7.2 git revert(安全撤销,可推送))
    • 八、Cherry-pick(精确复制提交)
    • [九、交互式 Rebase(-i)](#九、交互式 Rebase(-i))
    • 十、提交修改技巧
      • [技巧 #1:用 rebase -i + amend 修改历史提交](#1:用 rebase -i + amend 修改历史提交)
      • [技巧 #2:用 cherry-pick + amend(更简洁,避免冲突)](#2:用 cherry-pick + amend(更简洁,避免冲突))
    • [十一、Git Tag(标签)](#十一、Git Tag(标签))
    • [十二、Git Describe(描述位置)](#十二、Git Describe(描述位置))
    • [十三、多分支 Rebase(进阶)](#十三、多分支 Rebase(进阶))
    • [十四、选择 parent 提交(^2)](#十四、选择 parent 提交(^2))
    • 十五、远程仓库基础
      • [15.1 git clone](#15.1 git clone)
      • [15.2 git fetch(下载,不修改本地)](#15.2 git fetch(下载,不修改本地))
      • [15.3 模拟团队协作(fakeTeamwork)](#15.3 模拟团队协作(fakeTeamwork))
      • [15.4 git pull(拉取并合并)](#15.4 git pull(拉取并合并))
      • [15.5 git push(推送)](#15.5 git push(推送))
    • 十六、偏离的工作(推送冲突的处理)
    • [十七、远程服务器拒绝(main 被保护)](#十七、远程服务器拒绝(main 被保护))
    • 十八、合并多个特性分支后推送
    • 十九、远程跟踪分支
    • [二十、Push / Fetch 的参数详解](#二十、Push / Fetch 的参数详解)
      • [20.1 git push 的 `<place>` 参数](#20.1 git push 的 <place> 参数)
      • [20.2 `<source>:<destination>` 格式(来源和目标不同名)](#20.2 <source>:<destination> 格式(来源和目标不同名))
      • [20.3 git fetch 的参数](#20.3 git fetch 的参数)
      • [20.4 空 source 的特殊用法](#20.4 空 source 的特殊用法)
    • [二十一、git pull 的参数](#二十一、git pull 的参数)
    • 二十二、快速参考速查表

Git 完整操作笔记

📌 本笔记来源于 learngitbranching.js.org 交互式教程内容整理


一、Git Commit(提交)

Git 提交记录保存的是目录下所有已跟踪文件的快照 ,但不会盲目复制整个目录,而是只打包与上次的差异 ,因此非常轻量。每个提交记录都有 parent 节点,维护完整历史。

bash 复制代码
git commit

演示过程 :初始有 C0、C1 两个提交,执行 git commit 后生成 C2,C2 的 parent 是 C1。

例题:连续提交两次

bash 复制代码
git commit
git commit

二、Git Branch(分支)

分支只是一个指向某个提交记录的轻量指针,创建多少都不会有存储开销。

bash 复制代码
git branch <name>            # 创建分支
git checkout <name>          # 切换分支(切换后 * 号移动到新分支)
git checkout -b <name>       # 创建并切换(常用简写)

演示过程

bash 复制代码
git branch newImage          # 创建 newImage,指向当前 C1
git commit                   # ⚠️ 此时仍在 main 上,newImage 不动!
git checkout newImage        # 切换到 newImage
git commit                   # 现在提交在 newImage 上

例题:创建名为 bugFix 的分支并切换过去

bash 复制代码
git branch bugFix
git checkout bugFix
# 或者一步到位:
git checkout -b bugFix

⚠️ Git 2.23 起,git switchgit checkout 的新替代命令,功能更清晰。


三、Git Merge(合并)

合并两个分支会产生一个特殊的合并提交记录 ,它有两个 parent 节点,包含了两条分支及其所有祖先的内容。

bash 复制代码
git merge <branch>

演示过程

bash 复制代码
# main 和 bugFix 各有一个独有提交
git checkout bugFix
git merge main               # 因为 main 继承自 bugFix,Git 直接 fast-forward(移动指针,无新提交)

四、Git Rebase(变基)

Rebase 将一系列提交记录"复制"后,在另一个地方逐个放下,产生更线性的提交历史

bash 复制代码
git rebase <target-branch>

演示过程

bash 复制代码
git rebase main              # 将 bugFix 的工作复制并移到 main 顶端(产生 C3' 副本,原 C3 仍存在但半透明)
git checkout main
git rebase bugFix            # 因为 bugFix 继承自 main,只是 fast-forward 移动指针

rebase 与 merge 对比

rebase merge
提交历史 线性、整洁 保留真实并行历史
历史是否被修改 改写 不会改写
适用场景 追求干净提交树 需要保留完整历史

五、HEAD 与分离 HEAD

HEAD当前所在提交记录的符号名称 ,通常指向分支名(如 main)。

分离 HEAD:让 HEAD 直接指向某个提交哈希,而非分支名。

bash 复制代码
# 原来:HEAD → main → C1
git checkout C1
# 现在:HEAD → C1(分离状态)

查看 HEAD 指向:

bash 复制代码
cat .git/HEAD
git symbolic-ref HEAD        # HEAD 指向分支名时使用

六、相对引用

从已知位置出发,通过操作符在提交树中移动:

操作符 含义
^ 向上移动 1 个提交(parent)
^^ 向上移动 2 个提交
~<num> 向上移动多个提交
^<num> 合并提交时选择第几个 parent

演示

bash 复制代码
git checkout main^           # 切换到 main 的 parent
git checkout HEAD~4          # 从 HEAD 向上移动 4 步
git checkout HEAD~^2~2       # 链式操作:向上1步 → 选第2个parent → 再向上2步
bash 复制代码
git checkout HEAD~4          # 从 HEAD 向上移动 4 步

强制移动分支

bash 复制代码
git branch -f main HEAD~3    # 强制将 main 指向 HEAD 的第 3 级 parent

⚠️ 真实 Git 中,不能对当前所在分支执行 git branch -f


七、撤销变更

7.1 git reset(本地撤销,改写历史)

将分支引用向后移动至更早的提交,就好像那个提交从未发生过。

bash 复制代码
git reset HEAD~1             # main 回退到 C1,C2 的变更回到未暂存状态

⚠️ git reset 只适合本地分支,不能用于已推送到远程的共享分支

7.2 git revert(安全撤销,可推送)

创建一个新的提交记录 来抵消目标提交的变更,不改写历史。

bash 复制代码
git revert HEAD              # 产生新提交 C2',其内容刚好撤销 C2 的变更

八、Cherry-pick(精确复制提交)

指定提交记录复制到当前 HEAD 下方,需要知道提交的哈希值(或别名)。

bash 复制代码
git cherry-pick <C1> <C2> ...

演示 :将 side 分支上的 C2、C4 复制到 main 上

bash 复制代码
# 当前在 main 上
git cherry-pick C2 C4        # C2、C4 被依次复制到 main 顶端

例题:对三个分支分别进行不同的 cherry-pick 操作

  • one 需要重新排序并删除 C5
  • two 仅需重排顺序
  • three 只需要一次提交
bash 复制代码
git checkout one
git cherry-pick C4 C3 C2
git checkout two
git cherry-pick C5 C4 C3 C2
git branch -f three C2

九、交互式 Rebase(-i)

当不清楚哪些提交的哈希值时,用交互式变基审查并整理即将变基的提交列表。

bash 复制代码
git rebase -i HEAD~4

交互界面中可以:

  • 调整提交顺序(拖动)
  • 删除/跳过某个提交(关闭 pick)
  • 在真实 Git 中还支持 squash(合并)、edit、reword 等

例题:对最近 4 个提交(C2 C3 C4 C5)进行交互式变基,删除 C2,顺序改为 C5 → C4 → C3

bash 复制代码
git rebase -i HEAD~4
# 在编辑界面:删除 C2,调整顺序为 C5、C4、C3

十、提交修改技巧

技巧 #1:用 rebase -i + amend 修改历史提交

场景 :你在 newImage 分支提交了一次,又基于它创建了 caption 分支再提交一次,现在需要修改 newImage 中的那次提交。

步骤

bash 复制代码
git rebase -i HEAD~2         # 将 C2 调到最前(顺序改为:C3, C2 → 变成 C2 在前)
git commit --amend           # 修改现在最新的提交(即原来的 C2)
git rebase -i HEAD~2         # 恢复原来的顺序(C2'', C3')
# 然后更新 main 指向最新

技巧 #2:用 cherry-pick + amend(更简洁,避免冲突)

bash 复制代码
git checkout main
git cherry-pick C2           # 摘取需要修改的提交
git commit --amend           # 修改它
git cherry-pick C3           # 再摘取后续提交

十一、Git Tag(标签)

标签是永久指向某个提交的锚点,不会随新提交移动,常用于标记版本发布。

bash 复制代码
git tag v1 C1                # 在 C1 上创建标签 v1
git tag v1                   # 不指定提交时,默认在 HEAD 处

例题:

bash 复制代码
git tag v0 C1
git tag v1 C2
git checkout C2

十二、Git Describe(描述位置)

帮助找到离某个提交最近的标签,在提交树中定位当前位置。

bash 复制代码
git describe <ref>

输出格式<tag>-<numCommits>-g<hash>

  • tag:最近的标签名
  • numCommits:与该标签相差几个提交
  • hash:当前提交哈希的前几位
  • 若 ref 上就有标签,则只输出标签名

示例 (先执行 git tag v2 C3):

bash 复制代码
git describe main   # 输出:v1-2-gC2
git describe side   # 输出:v2-1-gC4

十三、多分支 Rebase(进阶)

场景 :有 bugfix、side、another 多个分支,需按顺序全部 rebase 到 main 上,使提交历史有序。

bash 复制代码
git rebase main bugfix       # 将 bugfix rebase 到 main
git rebase bugfix side       # 将 side rebase 到 bugfix
git rebase side another      # 将 another rebase 到 side
git rebase another main      # 将 main fast-forward 到 another

十四、选择 parent 提交(^2)

合并提交有两个 parent,^ 后加数字可以选择走哪条路径。

bash 复制代码
git checkout main^           # 默认选第一个 parent(正上方)
git checkout main^2          # 选第二个 parent(另一条分支)
bash 复制代码
git checkout HEAD~^2~2       # 链式:向上1步 → 选第2个parent → 再向上2步

例题:

bash 复制代码
git branch bugWork main^^2^

十五、远程仓库基础

远程仓库是你仓库在另一台计算机上的拷贝,具备备份和协作两大核心作用。

15.1 git clone

bash 复制代码
git clone                    # 在本地创建远程仓库的完整拷贝

克隆后,本地会多出一个远程分支 (如 o/mainorigin/main),命名规范为 <remote>/<branch>

远程分支的特性:

  • 切换到远程分支时自动进入分离 HEAD 状态(不能直接提交)
  • 反映远程仓库上次通信时的状态

演示 :切换到远程分支后提交

bash 复制代码
git checkout o/main          # 进入分离 HEAD 状态
git commit                   # o/main 不会更新!因为它只反映远程状态

例题:

bash 复制代码
git commit
git checkout o/main
git commit

15.2 git fetch(下载,不修改本地)

从远程仓库下载本地缺失的提交记录,并更新远程分支指针(如 o/main),但不修改本地工作分支

bash 复制代码
git fetch                    # 下载所有远程更新

⚠️ git fetch 只是单纯下载,不会更新你的 main 分支,也不会修改磁盘文件。


15.3 模拟团队协作(fakeTeamwork)

教程内置命令,用于模拟队友向远程仓库推送提交:

bash 复制代码
git fakeTeamwork             # 在远程 main 上新增一个提交
bash 复制代码
git fakeTeamwork foo 3       # 在远程 foo 分支上新增 3 个提交

例题:完整的克隆 → 模拟远程变更 → 本地提交 → 拉取流程

bash 复制代码
git clone
git fakeTeamwork 2
git commit
git pull

15.4 git pull(拉取并合并)

git pull = git fetch + git merge 的缩写。

bash 复制代码
# 等价写法:
git fetch
git merge o/main
# ↓ 等同于
git pull

# 等价写法(rebase 版):
git fetch
git rebase o/main
# ↓ 等同于
git pull --rebase

15.5 git push(推送)

将本地提交上传到远程仓库:

bash 复制代码
git push                     # 推送当前分支

执行后 :远程仓库接收新提交,远程分支(o/main)也同步更新。


十六、偏离的工作(推送冲突的处理)

场景 :你在周一克隆了仓库,开发到周五,但同事这期间也推送了新提交。此时你的提交基于旧版本,git push 会被拒绝。

bash 复制代码
git push    # ❌ 在这里执行git push会导致失败!你的 C3 基于旧的 C1,远程已更新到 C2,现象是什么都没有变

解决方案一:rebase(保持线性历史)

bash 复制代码
git fetch
git rebase o/main
git push
# 简写:
git pull --rebase
git push

解决方案二:merge

bash 复制代码
git fetch
git merge o/main
git push
# 简写:
git pull
git push

例题:完整的克隆 → 模拟冲突 → 用 rebase 解决后推送

bash 复制代码
git clone
git fakeTeamwork
git commit
git pull --rebase
git push

十七、远程服务器拒绝(main 被保护)

场景:团队项目中 main 分支被锁定,必须通过 Pull Request 合并,不允许直接 push。

错误信息

复制代码
! [远程服务器拒绝] main -> main
(TF402455: 不允许推送这个分支;你必须使用 pull request 来更新这个分支。)

解决办法:将 main 重置为远程状态,将本地工作移到特性分支后推送:

bash 复制代码
git branch -f main o/main    # 将本地 main 重置为与远程一致
git checkout -b feature C2   # 从正确的提交创建特性分支
git push origin feature      # 推送特性分支,再去提 PR

十八、合并多个特性分支后推送

场景:有 side1、side2、side3 三个特性分支,需要按顺序合并到 main 并推送。

方案一:rebase(线性历史)

bash 复制代码
git fetch
git rebase o/main side1      # 将 side1 rebase 到 o/main 上
git rebase side1 side2       # 将 side2 rebase 到 side1 上
git rebase side2 side3       # 将 side3 rebase 到 side2 上
git rebase side3 main        # 将 main fast-forward 到 side3
git push

方案二:merge(保留历史)

bash 复制代码
git checkout main
git pull
git merge side1
git merge side2
git merge side3
git push

十九、远程跟踪分支

maino/main 的关联关系由分支的 remote tracking 属性决定,克隆时 Git 自动设置:

复制代码
local branch "main" set to track remote branch "o/main"

设置方法一:创建新分支并跟踪远程分支

bash 复制代码
# 演示:
git checkout -b foo o/main
git pull                         # 更新的是 foo,main 不动
bash 复制代码
# 演示:
git checkout -b foo o/main
git commit
git push                         # 推送到 origin/main(不是 foo!)

设置方法二git branch -u

bash 复制代码
git branch -u o/main foo        # 让 foo 跟踪 o/main
git branch -u o/main            # 当前在 foo 上时可省略 foo
# 演示:
git branch -u o/main foo
git commit
git push

例题:不切换到 main,直接将工作推送到远程 main

bash 复制代码
git checkout -b side o/main
git commit
git pull --rebase
git push

二十、Push / Fetch 的参数详解

20.1 git push 的 <place> 参数

bash 复制代码
git push origin main         # 推送本地 main 到远程 main
git push origin foo          # 推送本地 foo 到远程 foo

指定参数后,Git 会忽略当前所在分支,直接操作指定的分支。

bash 复制代码
git checkout C0
git push origin main         # 即使 HEAD 在 C0,main 仍会被推送 ✅
bash 复制代码
# 如果不指定参数会发生什么呢?
git checkout C0
git push                     # ❌ 失败!HEAD 没有跟踪任何分支

20.2 <source>:<destination> 格式(来源和目标不同名)

bash 复制代码
git push origin <source>:<destination>
# 示例:
git push origin foo^:main       # 将 foo^ 位置的提交推送到远程 main
git push origin main:newBranch  # 推送到远程不存在的分支(Git 自动创建)
bash 复制代码
git push origin main:newBranch  # 推送到远程不存在的分支(Git 自动创建)

例题:

bash 复制代码
git push origin main^:foo
git push origin foo:main

20.3 git fetch 的参数

git fetchgit push 参数概念相同,只是方向相反(下载而非上传):

bash 复制代码
git fetch origin foo         # 下载远程 foo,放到本地 o/foo(不影响本地 foo)
bash 复制代码
git fetch                    # 无参数:下载所有远程分支的更新
bash 复制代码
git fetch                    # 无参数:下载所有远程分支的更新

例题:

bash 复制代码
git fetch origin c3:foo
git fetch origin c6:main
git checkout foo
git merge main

20.4 空 source 的特殊用法

bash 复制代码
# push 空值到远程 → 删除远程分支
git push origin :foo         # 删除远程 foo 分支
bash 复制代码
# fetch 空值到本地 → 在本地创建新分支
git fetch origin :bar        # 在本地创建 bar 分支

例题:

bash 复制代码
git push origin :foo
git fetch origin :bar

二十一、git pull 的参数

git pull = git fetch + git merge,参数透传给 fetch,fetch 完成后自动 merge:

bash 复制代码
# 等价命令:
git pull origin foo          # ≡ git fetch origin foo; git merge o/foo
git pull origin bar:bugFix   # ≡ git fetch origin bar:bugFix; git merge bugFix
git pull origin main:foo     # 先在本地创建 foo 并拉取,再 merge 到当前分支

例题:

bash 复制代码
git pull origin c3:foo
git pull origin c2:side

二十二、快速参考速查表

本地操作

命令 说明
git commit 提交快照
git branch <name> 创建分支
git checkout -b <name> 创建并切换分支
git merge <branch> 合并分支(产生合并提交)
git rebase <branch> 变基(产生线性历史)
git rebase -i HEAD~<n> 交互式变基(整理提交)
git cherry-pick <C1> <C2> 精确摘取指定提交
git commit --amend 修改最近一次提交
git reset HEAD~1 回退提交(本地)
git revert HEAD 撤销提交(安全,可推送)
git tag <name> <ref> 创建标签
git describe <ref> 描述当前位置与最近标签的距离
git branch -f <name> <ref> 强制移动分支指针

相对引用

表达式 含义
HEAD^ 上一个提交
HEAD~3 向上 3 个提交
main^2 main 合并提交的第二个 parent
HEAD~^2~2 链式相对引用

远程操作

命令 说明
git clone 克隆远程仓库
git fetch 下载远程更新(不修改本地)
git pull fetch + merge
git pull --rebase fetch + rebase
git push 推送到远程
git push origin <src>:<dst> 指定来源和目标
git push origin :<branch> 删除远程分支
git fetch origin :<branch> 本地创建新分支
git branch -u o/main 设置当前分支的远程追踪
git checkout -b foo o/main 创建 foo 并跟踪 o/main
相关推荐
MageGojo1 小时前
Whois 域名查询 API 接入实战:用一个 GET 请求获取域名注册信息
java·git·github
数智工坊1 小时前
周志华《Machine Learning》学习笔记--第四章--决策树
笔记·学习·机器学习
黑猫警长丶1 小时前
Git 本地操作基础
git
百万小涵1 小时前
从零接入大模型:通义千问、Ollama 与 OpenAI SDK 入门(RAG与Agent实战学习笔记①)
笔记·学习
我命由我123451 小时前
BOM 极简理解
运维·经验分享·笔记·物联网·学习·运维开发·学习方法
xian_wwq1 小时前
【学习笔记】大模型应用安全落地实践
笔记·学习·ai安全
江华森1 小时前
Jenkins 从入门到精通 — 完整学习笔记
笔记·学习·jenkins
江华森1 小时前
Kafka 从入门到精通 — 完整学习笔记
笔记·学习·kafka
chushiyunen1 小时前
elasticsearch笔记
笔记·elasticsearch·jenkins