Git 使用基础教程

本教程将介绍以下内容:Git 的核心概念(工作区/暂存区/提交历史/Stash)、版本存档与回滚、分支合并与冲突处理、进阶工具(Rebase/Stash/Worktree),以及 GitHub 远程仓库的使用。

教程路线

基础篇:存档

  • 让 Git 管理项目(git init)
  • 核心模型:工作区、暂存区、提交历史
  • 存档流程:git add → git commit
  • 查看状态:git status、git log

基础篇:回滚与忽略

  • 回滚的 3 种场景(工作区、暂存区、提交历史)
  • 撤销操作:git restore、git reset、git revert
  • 忽略文件:.gitignore

进阶篇:分支与合并

  • 分支概念与操作(git branch、git switch)
  • 合并分支与冲突处理(git merge、快进合并、三方合并)
  • 进阶工具:Rebase、Stash、Worktree

工具篇:GitHub 远程仓库

  • GitHub 使用场景与作用
  • 配置 SSH Key(ssh-keygen)
  • 创建 GitHub 仓库、关联远程仓库(git remote add)
  • 推送代码(git push)、克隆代码(git clone)

第 0 章 基础概念:Git 与 GitHub

(1)Git 是什么?为什么我们要使用 Git?

Git 是一款安装在你电脑上的本地软件,它负责记录并备份代码的各个版本,能够高效管理你的项目。它解决的是项目更新过程中的版本管理问题,并支持我们回退错误的修改。如果你不想变成这样:-

屏幕截图 2026-11-03 150714
  • 屏幕截图 2026-11-03 150745
    请使用 Git。

更具体地说,Git 会在项目目录下维护一个本地仓库,把每一次提交的代码状态记录下来。你可以查看历史、比较差异、回退到某个版本,也可以在不同的分支上并行开发。它不依赖网络,本地就能完成版本管理。

(2)什么是 GitHub?与 Git 的关系是什么样的?

既然有了 Git,我们又为什么使用 GitHub?

GitHub 是一个远程网站,用于备份代码和 Git 记录。Git 只是将代码和版本记录备份存储在本地;如果我们的电脑遭遇不测,本地仓库也可能一起丢失,所以对代码进行多重备份是有必要的。GitHub 就担任这个角色。我们可以使用 Git 连接 GitHub 的远程仓库(你可以把 GitHub 理解为存储代码的云盘),代码便可以通过 Git 推送到 GitHub 的服务器中,实现本地一份、云端一份的双重备份。

当然,GitHub 的功能远不止备份,例如协作、共享开源等。不过本篇是 Git 的使用教程,所以这部分不多赘述。

一句话总结:我们用 Git 进行本地的代码版本管理,然后用 Git 连接 GitHub 进行远程的云端备份。

(3)Git 的基础知识:三个区域

那么 Git 是如何运作的?可以先记住三个区域。

假设我们有一个项目,项目所在的目录名为 todo-app,该目录下有两个文件,分别为 index.html 和 readme.md。

工作区是你当前正在编辑的文件所在的目录。你打开 todo-app,看到 index.html、readme.md,这些文件就处在工作区。

暂存区是介于工作区和提交历史之间的一个中间区域,用来存放你准备纳入下一次提交的改动。你用 git add 把工作区里的改动放入暂存区,但这时还没有真正生成提交。

提交历史是已经存档的版本库。你用 git commit 把暂存区里的内容正式存成一个 commit,从此这次改动就进入了提交历史。

一次正常的提交流动是这样的:

工作区 --git add--> 暂存区 --git commit--> 提交历史

为什么要有暂存区,不能直接 commit 吗?暂存区的意义在于,它可以让你一点一点挑出下一次要提交的内容。比如你重构了 todo-app 的代码,多出了 JS 和 CSS 文件,你可以先挑 index.html,再挑对应的 JS 和 CSS,确认无误后再统一提交。如果没有暂存区,你只能把当前所有改动一次性打包提交,很难精确控制一次 commit 到底包含什么。

再往前看一步:提交历史里的每一个 commit 并不是孤立的。分支本质上是一个指向某个 commit 的可移动指针,HEAD 通常指向当前分支,再由当前分支间接指向最新提交。后面讲分支、合并、Rebase 时,都会围绕这张“提交图”展开。另外,Git 除了工作区、暂存区、提交历史之外,还有一个用来临时存放未提交改动的地方,叫 Stash;它更像一个栈,后面会单独讲。

现在你只需要形成初步印象:工作区是正在修改的文件;暂存区存放准备提交的改动;提交历史是已经存档的 commit。git add 把改动放入暂存区,git commit 把暂存区内容写入提交历史。下面从第一次存档开始。

小结: Git 负责本地版本管理,GitHub 负责远程备份;工作区、暂存区、提交历史构成一次提交的基本路径,暂存区让你精确控制一次提交的内容;分支是指向 commit 的可移动指针,Stash 是临时保存未提交改动的栈。先建立这个模型,后面的命令都是围绕它展开的。


阅读前说明:几个容易误解的点

有几个表述如果直接照搬,容易在面试或团队协作中产生误解,先在这里说清楚。

  1. 分支不是“标签”,而是可移动指针。更准确地说:分支是指向某个 commit 的可移动指针;HEAD 通常指向当前分支,再由当前分支间接指向最新提交。把分支叫“贴在 commit 上的标签”是教学化表达,理解方向没问题,但严格表述应校正。
  2. git restore 默认不是“直接从上次提交恢复”。git restore <文件> 默认是从暂存区恢复工作区。只是在“改动还没 git add”的场景里,暂存区内容和 HEAD 一致,所以效果看起来像“恢复到上一次提交”。这个区别很重要。
  3. Stash 的“第四空间”是教学类比。Git 的核心模型常讲工作区、暂存区、提交历史;Stash 是 refs/stash 下保存的栈,用来临时存放未提交改动。把它叫“第四个区域”方便理解,但不要理解成和前三者完全并列的物理区域。
  4. .gitignore 只对未跟踪文件生效。已经被 git add 或 commit 跟踪的文件,写进 .gitignore 不会自动失效,需要 git rm --cached <文件> 取消跟踪后再提交。
  5. git stash 默认不包含未跟踪文件。如果需要连未跟踪文件一起收走,要用 git stash -u。
  6. git branch -d 只能删除已合并分支。未合并分支需要 -D 强制删除,但要谨慎。
  7. git push -f 不要在公共分支随意使用。强推可能覆盖别人的提交,公共分支回滚优先用 git revert。
  8. 快进合并的条件:当前分支没有分叉、且当前分支是目标分支的祖先时,Git 直接把指针前移,不产生新 commit。说“主分支没有新提交”是场景化表达,严格说是“可快进”。

第 1 章 第一次存档:工作区、暂存区、提交历史

你有一个简单的待办项目 todo-app,包含 index.html 和 readme.md,现在还没被 Git 管理。你想给它存档,以免改坏后无法恢复。

终端进入项目目录:

cd todo-app
git init

git init 会创建一个隐藏的 .git 文件夹,里面存放所有版本记录。此时还没有任何存档。

执行:

git status

你会看到 Untracked files(未跟踪的文件),说明 Git 发现了它们但还没开始管理。

把文件加入暂存区:

git add index.html
# 或
git add .
#用 . 来代表当前工作目录下所有文件

git add 只是把改动放入暂存区,并不生成提交。暂存区存在的意义是让你精确控制一次提交的内容:重构代码后多出了 JS 和 CSS 文件,你可以先挑 index.html,再挑对应的 JS 和 CSS,确认无误后再统一提交。

第一次提交前需要设置身份:

git config --global user.name "你的名字"
git config --global user.email "你的邮箱"

这不是登录账号,只是告诉 Git 提交记录里记谁的名字。这两行命令只需执行一次,以后在这台电脑上操作任何项目都不用再设置。如果没设置,Git 可能无法让你提交。

提交:

git commit -m "添加待办页面"

-m 后面是提交说明。一个项目可能有几十上百个 commit,写好说明方便以后查阅。必须加 -m 或进入编辑器。

查看历史:

git log --oneline

--oneline 让每个 commit 只占一行。按 Q 退出。

工作区在英文里有时叫 working tree,有时叫 working directory,都是工作区的意思。git status 里的 working tree clean 表示工作区没有未提交改动。

小结: git init 建仓库,git status 看状态,git add 把改动放入暂存区,git commit 生成提交,git log 查看历史;提交前要设置 user.name 和 user.email。记住 add 不等于 commit,暂存区是提交前的中间层。


第 2 章 回滚:改动在哪,就从哪回滚

你改了一下 todo-app 里的 index.html,把页面改成深色主题,但发现改坏了,想要回滚。回滚方法取决于你的改动现在处于哪个区域。

2.1 场景一:改动只在工作区

修改了文件但未 git add,git status 显示 Changes not staged for commit。

git restore .
# 或
git restore index.html

git restore 默认从暂存区恢复工作区。因为本场景还没 git add,暂存区与 HEAD 一致,所以效果就是让工作区文件恢复到上一次提交的状态。

工作区在英文里两种说法,有时叫 working tree,有时叫 working directory,都是工作区的意思。

注意:这会覆盖工作区未保存的改动,慎用。

2.2 场景二:改动已进暂存区

已经执行了 git add,git status 显示 Changes to be committed。

git restore --staged .
git restore .

第一步 git restore --staged . 把改动从暂存区撤回工作区。它仅修改 Git 暂存区记录,文件内容不变。此时 git status 变回 Changes not staged for commit。第二步 git restore . 再把改动从工作区撤销,彻底回滚。

2.3 场景三:改动已提交为 commit

已经 git commit,git log 能看到新提交。

方案 A:删除 commit(危险)

git reset --hard HEAD~1

HEAD 代表当前提交,HEAD~1 代表前一个提交。--hard 会把工作区、暂存区、提交历史全部重置。

--hard 干得很彻底,用的时候一定要小心。如果你的工作区还有没提交的改动,执行后它们也会一起消失。执行前最好先用 git status 看一眼。

其他模式:

git reset --mixed HEAD~1   # 默认模式,可简写 git reset HEAD~1
git reset --soft HEAD~1

git reset --mixed HEAD~1 是默认模式,回滚暂存区和提交历史,保留工作区。适合 commit 后发现小问题想改改再重新提交。git reset --soft HEAD~1 仅回滚提交历史,保留工作区和暂存区。适合你想把几个 commit 合并成一个时使用。

方案 B:追加回滚 commit

git revert HEAD

这会创建一个新的 commit 来抵消原来的改动,历史记录里仍然保留原来的 commit,以后后悔了还能找回来。非常适合公共分支。执行后会弹出 Vim 编辑器,里面是自动生成的回滚说明(以 # 开头的行是注释,会被忽略)。按冒号 :wq 保存退出即可。

工作区坏了用 restore;暂存区进错了先 restore --staged 再 restore;提交历史要删用 reset,公共分支要安全回滚用 revert。--hard 是危险命令,执行前先 git status。

小结: 工作区改动用 git restore;暂存区改动先 git restore --staged 再 git restore;已提交的改动用 git reset 删除提交(--hard 危险),公共分支用 git revert 追加反向提交。回滚前先确认改动在哪个区域。


第 3 章 忽略文件:.gitignore

你在 todo-app 里建了一个 notes.txt 记录个人学习笔记,你不想让 Git 跟踪它们。

创建 .gitignore 文件(在访达里新建,或者用 vim .gitignore),写入要忽略的文件名:

notes.txt

创建后 git status 里 notes.txt 就消失了。

注意:.gitignore 只对未跟踪文件生效。如果文件已经被 git add 或 commit 过,写进 .gitignore 是没用的,需要先用 git rm --cached <文件> 取消跟踪,再提交。

.gitignore 文件本身是需要提交到 Git 的,因为它是项目规则的一部分,换了电脑也需要这些规则。

小结: .gitignore 只对未跟踪文件生效;已跟踪文件要先 git rm --cached 取消跟踪;.gitignore 本身要提交,因为它是项目规则的一部分。


第 4 章 分支:平行开发与合并

4.1 为什么需要分支?

要给 todo-app 增加“截止时间”功能,需要拆成 3 个 commit(界面、保存逻辑、过期提醒)。如果直接在主分支上开发,中间状态主分支会有半成品,用户点到可能会报错。所以需要拉一个新分支专门开发,保证 master 分支随时处于稳定可用状态。

分支本质上是一个指向 commit 的可移动指针,HEAD 指向当前分支,通常间接指向该分支最新提交。不同分支可以各自向前提交,最后再合并。

把分支叫“标签”是教学化说法;严格说分支会随着新提交向前移动,而标签(tag)通常固定指向某个 commit。

4.2 创建并切换分支

git switch -c feature/due-date

-c 是 create 的缩写,相当于 git branch + git switch。老教程里可能会用 git checkout -b,效果一样,但 switch 是新拆出来的命令,更清晰。

分支名里可以带斜杠 /,比如 feature/due-date,这只是命名习惯,Git 并没有严格限制。

4.3 在新分支开发并提交

经历 3 次 git add + git commit。

4.4 切回主分支并合并

git switch master
git merge feature/due-date

为什么合并前要切回 master?因为合并是把别的分支合并到当前所在的分支,所以必须先站在目标分支上。

合并后发生了什么?如果是快进合并(Fast-forward),master 指针直接往前挪,不产生新 commit。如果是三方合并,Git 会自动生成一个新 commit。

合并后分支要删吗?如果分支已经没用了,可以用 git branch -d feature/due-date 删掉。git branch -d 只能删除已合并分支;未合并分支需要 -D 强制删除,慎用。

4.5 快进合并与三方合并

快进合并(Fast-forward):当当前分支没有分叉、且当前分支是目标分支的祖先时,Git 直接把指针前移,不产生新 commit。前面“主分支没有新提交”就是典型可快进情况。

三方合并(Merge Commit):两个分支都有新提交、发生分叉时,Git 新建一个 commit 把两边代码合并起来。

一个功能一个分支;合并前先切回目标分支;能快进就不产生新 commit,有分叉就产生合并 commit;删分支用 -d,未合并分支慎用 -D。

小结: 分支是指向 commit 的可移动指针;git switch -c 创建并切换分支;合并前先切回目标分支;能快进则快进,有分叉则三方合并;删分支用 -d,未合并分支慎用 -D。


第 5 章 合并冲突:Git 停下来让你做决定

你从 master 拉了两个新分支:feature/sort(排序)和 feature/complete-all(全部完成)。两个分支都在 todo-app 的“添加按钮”那一行下面插入了一个新按钮,于是合并时产生了冲突。Git 不知道到底该保留哪一个,也无法决定谁在前谁在后,于是停下来让你决定。

  1. 执行 git merge feature/complete-all,终端报错 CONFLICT,提示 Automatic merge failed。
  2. git status 查看,提示 Unmerged paths(未合并的路径),index.html 显示 both modified。
  3. 打开 index.html,找到冲突标记:
<<<<<<< HEAD
当前分支的代码
=======
要合并进来的分支的代码
>>>>>>> feature/complete-all
  1. 删除标记符号,保留你最终需要的代码(这里是两个按钮都保留)。
  2. 执行:
git add .
git commit

<<<<<<< HEAD 到 ======= 之间是当前分支(master)的代码;======= 到 >>>>>>> feature/complete-all 之间是要合并进来的分支的代码。

冲突发生得越晚,解起来越痛苦。一个功能做一两周,最后合并时冲突可能有一大堆。建议在开发过程中,时不时把分支变基到 master 上,让冲突早点暴露、早点解决。

如果不想解决了,可以用 git merge --abort 放弃本次合并,回到合并前的状态。

冲突不可怕:先看 git status,再找 <<<<<<<、=======、>>>>>>>,改成你要的代码,add 后 commit;不想合并就 merge --abort。

小结: 冲突时 Git 停下来让你决定;先看 git status 找到 Unmerged paths,编辑冲突标记,git add 后 git commit;不想合并用 git merge --abort。冲突越早解决越轻松。


第 6 章 Rebase:给分支重新换一个地基

你的 feature/complete-all 分支是从旧 master 拉出来的,期间 master 已经合入了别人的 feature/sort。如果你直接在 feature/complete-all 上开发完再合并,会有三方合并的冲突。更好的做法是先把分支变基到最新 master 上。

Rebase 是给分支重新换一个“地基”,把当前分支的提交挨个挪到目标分支的最新提交后面。它的本质是把当前分支的每个 commit 挨个挪到目标分支后面重新应用一遍。关键点是:会重写提交历史;冲突时执行 git rebase --continue 而非 git commit。

  1. 在 feature/complete-all 分支上执行:
git rebase master
  1. 遇到冲突,解决冲突(编辑文件,保留需要的代码)。
  2. 执行:
git add .
  1. 关键一步:执行
git rebase --continue

而不是 git commit。在这里用了 commit 会导致 rebase 流程混乱。

  1. 如果弹出编辑器让你修改 commit 说明,直接保存退出即可。

成功后会显示 successfully rebased。变基后,当前分支就接在了 master 最新的 commit 后面,此时再合并通常就是 Fast-forward,非常干净。

Rebase 是“挪提交、换地基、重写历史”;冲突解决后 add,然后 rebase --continue,不要 commit。

小结: Rebase 把当前分支的提交挪到目标分支最新提交后面,会重写历史;冲突解决后 git add 再 git rebase --continue,不要 git commit;变基后再合并通常就是快进,历史更干净。


第 7 章 Stash:临时保存未提交改动

你正在给 todo-app 写“清空已完成”功能,写了一半。突然用户反馈一个 bug 需要紧急修复。你执行 git switch master 时,Git 报错:

Your local changes would be overwritten by switch

为什么会报错?因为分支切换时,Git 需要改写工作区里的文件。如果你工作区里有未提交的改动,这些改动就会被目标分支的文件覆盖掉,导致你的半成品代码丢失。Git 不敢替你做决定,所以干脆停下来报错。

能不能把改动挪到别的地方放一放?可以。Git 除了工作区、暂存区、提交历史之外,还有一块专门用来临时保存未提交改动的地方,名字叫 Stash(储藏区)。之前它一直是空的,所以没提它。

执行 git stash 后,Git 会把工作区(以及暂存区)里所有还没提交的改动保存到 Stash 里。保存走之后,index.html 就回到了上一次提交时的样子。这个时候再去切分支,就不会覆盖掉任何东西了。

  1. 执行:
git stash

终端会提示 Saved working directory and index state WIP on ...。

WIP 是 Working Progress 的缩写,意思是“正在做的活”。在 Git 里,就是指那些还没有提交的改动。index 就是暂存区(Staging Area 的另一种叫法)。这说明 Stash 不仅会保存工作区的改动,也会保存暂存区的改动。

  1. 此时 git status 显示 working tree clean,工作区干净了。顺利切换到 master,拉取 hotfix 分支修 bug、合并、删除临时分支。

  2. 切回原来的分支,执行:

git stash pop

把半成品取回来。pop 是“弹出来”的意思。取回后,工作区又变回修改状态,你可以接着写。当前状态就跟收起来之前一模一样。

stash 适合临时打断一下的情况,先去干点别的,很快就回来。如果你要同时开发多个分支,频繁 stash 和 pop 会非常麻烦。这时候更好的方案是使用 Worktree(见下一章)。

需要补充几点:Stash 不是分支,它是一个栈(Stack),可以存多份,后进先出。取回命令 git stash pop 是弹出最新的一份。Stash 的“第四空间”是教学类比;Git 的核心模型常讲工作区、暂存区、提交历史,Stash 是 refs/stash 下保存的栈。git stash 默认不收未跟踪文件;需要时用 git stash -u。git stash list 可查看栈中保存了哪些记录。

小结: 切分支时工作区不干净会报错;git stash 临时保存未提交改动,修改完后git stash pop 取回;Stash 是栈,默认不含未跟踪文件;频繁切换分支时考虑 Worktree。


第 8 章 Worktree:一个仓库,多个工作目录

你正在给 todo-app 开发“导出”功能,写了一半。产品临时插入一个“统计”功能,并且下周就要上线。你不想频繁 stash 切换分支,想一边保留导出功能的半成品,一边去另一个目录开发统计功能。

  1. 执行:
git worktree add ../todo-app-stats -b feature/stat master

这行命令的意思是,在上一级目录创建一个 todo-app-stats 文件夹,基于 master 分支创建一个叫 feature/stat 的新分支,并把这个新目录关联到这个新分支。

  1. 进入新目录,正常开发、git add、git commit、git merge。

  2. 功能上线后,删除 worktree:

git worktree remove ../todo-app-stats

不要直接把这个新目录拖进废纸篓!否则 Git 记录会残留。必须用 git worktree remove 命令删除。

核心原理一句话:每一个 Worktree 都有自己独立的工作区和暂存区,但所有的 Worktree 共用同一份提交历史。在任何一个 Worktree 里提交,另一个 Worktree 里都能看到。这跟直接复制粘贴一份文件夹是完全不一样的。

git worktree list 可以查看当前有哪些工作树。加号 + 表示该分支正在另一个 Worktree 中打开。

小结: Worktree 让一个仓库有多个工作目录,各自有独立的工作区和暂存区,但共用提交历史;用 git worktree add 创建,git worktree remove 删除,不能直接删文件夹。


第 9 章 GitHub:把本地历史备份到远程

本地代码和 Git 记录有丢失风险(电脑坏了、误删文件夹),需要备份到云端 GitHub。

9.1 配置 SSH Key 与原理

  1. 生成密钥:
ssh-keygen -t ed25519 -C "你的邮箱"

一路回车(不设密码)。

  1. 查看公钥:
cat ~/.ssh/id_ed25519.pub

复制输出的内容。

  1. GitHub 页面:右上角头像 → Settings → SSH and GPG keys → New SSH key → 粘贴公钥 → Add SSH key。

  2. 测试连接:

ssh -T git@github.com

第一次会提示确认指纹,输入 yes。

私钥留在本地绝对不要给别人,公钥可以公开。GitHub 用公钥验证你的私钥签名,确认是你本人。就像你在文件上签了字,别人模仿不来。

9.2 创建远程仓库与推送

  1. GitHub 点击 New repository,命名(英文,例如 todo-app),不勾选初始化文件。
  2. 本地执行:
git remote add origin git@github.com:你的用户名/todo-app.git

这是给远程仓库起个别名叫 origin,以后不用写一长串地址。

  1. 推送:
git push -u origin master

-u 把本地 master 和远程 master 绑定,以后直接 git push 即可。如果本地主分支叫 master,远程默认可能是 main,推送时注意改一下命令里的分支名。

9.3 日常开发流程与经验

改代码 → git add . → git commit -m "说明" → git push。

git status 会提示 Your branch is ahead of 'origin/master' by 1 commit,说明本地领先远程,需要 push。

9.4 从 GitHub 恢复:git clone

删除本地文件夹模拟丢失,然后执行:

git clone git@github.com:你的用户名/todo-app.git todo-app

克隆会拉取完整的提交历史,git log 能看到所有记录。不仅是文件,连历史都在。

小结: SSH 公钥给 GitHub,私钥留本地;git remote add origin 关联远程仓库;git push -u 绑定分支;日常 add → commit → push;丢失后 git clone 可恢复完整历史。


第 10 章 命令速查表

命令 作用 常用参数 示例 注意事项
git --version 查看 Git 版本 – git --version 出现版本号即可用
git init 初始化 Git 仓库 – git init 会在当前目录创建 .git 文件夹
git status 查看当前仓库状态 – git status 常看 working tree clean 代表无改动
git add 把工作区改动放入暂存区 .(当前目录) git add . 被 .gitignore 忽略的未跟踪文件不会被加进去
git commit 把暂存区内容提交为 commit -m "说明" git commit -m "添加待办页面" 必须加 -m 或进入编辑器
git log 查看提交历史 --oneline git log --oneline 按 Q 退出
git restore 撤销工作区改动 <文件> / . git restore index.html 默认从暂存区恢复工作区;会覆盖工作区未保存的改动,慎用
git restore --staged 把改动从暂存区撤回工作区 <文件> / . git restore --staged . 仅修改 Git 暂存区记录,文件内容不变
git reset --hard 回滚工作区、暂存区、提交历史 HEAD~1 git reset --hard HEAD~1 危险!会彻底清除未提交改动和提交记录
git reset --mixed 回滚暂存区和提交历史,保留工作区 HEAD~1 git reset HEAD~1 默认模式(不加选项)
git reset --soft 仅回滚提交历史,保留工作区和暂存区 HEAD~1 git reset --soft HEAD~1 适合修改上次提交内容
git revert 创建一个抵消目标 commit 的新 commit HEAD git revert HEAD 安全,不删除历史
git branch 查看/创建分支 -d(删除) git branch feature/due-date / git branch -d feature 创建后不会自动切换;-d 只能删已合并分支
git switch 切换分支 -c(创建并切换) git switch -c feature/due-date 老写法是 git checkout -b
git merge 合并分支 – git merge feature/due-date 先切回目标分支(如 master)再合并
git rebase 变基 master git rebase master 冲突解决后用 git rebase --continue
git stash 把未提交改动存起来 – git stash 工作区会变干净;默认不含未跟踪文件
git stash pop 把存的改动取回工作区 – git stash pop 与 git stash 对应
git worktree 管理工作树 add, list, remove git worktree add ../todo-app-stats -b feature/stat master 删除时要用 git worktree remove
ssh-keygen 生成 SSH 密钥对 -t ed25519 -C "邮箱" ssh-keygen -t ed25519 -C "your@email.com" 公钥给 GitHub,私钥留本地
git remote add 关联远程仓库 origin <地址> git remote add origin git@github.com:xxx/todo-app.git origin 是默认名
git push 推送本地提交到远程 -u origin master git push -u origin master -u 绑定分支后,以后直接 git push
git clone 克隆远程仓库到本地 – git clone git@github.com:xxx/todo-app.git todo-app 后面可接自定义文件夹名

补充:git branch -D <分支> 可强制删除未合并分支,但会丢失该分支未合并提交,慎用;公共分支不要随意 git push -f。

小结: 速查表用于快速查阅命令和危险点;重点掌握 add、commit、status、log、restore、reset、revert、branch、switch、merge、rebase、stash、worktree、push、clone 的用途和注意事项。


第 11 章 易错点与坑

  • .gitignore 对已跟踪文件无效:必须先用 git rm --cached <文件> 取消跟踪,再提交。
  • git reset --hard 危险:会同时清空工作区、暂存区和提交历史,未提交的代码会彻底丢失。执行前最好 git status 确认。
  • 合并顺序:合并是把别的分支合并到当前分支,所以必须先切换到目标分支(如 master)再执行 git merge。
  • Rebase 冲突解决后:执行 git add . 后,应继续 git rebase --continue,而不是 git commit。
  • 删除 Worktree:不能直接拖进废纸篓,需用 git worktree remove,否则 Git 记录残留。
  • SSH 私钥保密:私钥留在本地绝对不要公开或发给别人,只把公钥(.pub 结尾)给 GitHub。
  • 不要随意 git push -f:在公共分支上强推会覆盖别人的代码,推荐用 git revert 来撤销远程提交。
  • git restore 默认源是暂存区:不要误以为它永远从 HEAD 恢复;在场景一未暂存时效果等同恢复到上次提交。
  • git stash 默认不含未跟踪文件:需要连未跟踪文件一起收走时用 git stash -u。
  • git branch -d 只删已合并分支:未合并分支要 -D,但会丢失未合并提交,慎用。

小结: 易错点集中在 .gitignore 对已跟踪文件无效、reset --hard 危险、合并顺序、Rebase 冲突后要 --continue、Worktree 删除方式、私钥保密、不要随意 push -f。


第 12 章 术语中英对照

Git 术语 英文 解释
工作区 Working Directory / Working Tree 当前编辑文件的目录
暂存区 Staging Area / Index 准备提交的改动存放区
提交历史 Commit History 所有已提交的版本记录
提交 Commit 一次版本存档
分支 Branch 指向 commit 的可移动指针,指向一条提交线
快进合并 Fast-forward 直接移动分支指针的合并,不产生新 commit
三方合并 Merge Commit 两个分支合并时生成的新 commit
变基 Rebase 重新定义分支的“地基”,重写历史
贮藏/储藏区 Stash 临时保存未提交改动的地方,是独立于工作区、暂存区、提交历史的“第四空间”教学类比
工作树 Worktree 同一仓库的多个工作目录,共用提交历史
远程仓库 Remote Repository 托管在 GitHub 等平台上的仓库
克隆 Clone 把远程仓库完整复制到本地
推送 Push 把本地提交上传到远程仓库

小结: 术语中英对照帮助阅读英文文档和报错信息;工作区、暂存区、提交历史、分支、快进合并、三方合并、变基、Stash、Worktree 是核心词汇。


第 13 章 经验总结

13.1 主分支与分支管理

master(或 main)是主分支,希望它随时处于稳定、可用的状态。不要把只做了一半、还不能正常工作的功能直接提交到主分支上。

一个功能一个分支。开发新功能时,先基于当前稳定的 master 拉出一个新分支,等功能全部开发完、测试通过后,再合并回 master。

分支命名建议:可以用 feature/ 开头表示新功能,用 hotfix/ 开头表示紧急修复。这只是团队习惯,不是硬性规定,但能让分支一目了然。分支名里可以带斜杠 /,比如 feature/due-date,这只是命名习惯,Git 并没有严格限制。

13.2 冲突与合并

冲突发生得越晚,解起来越痛苦。一个功能做一两周,最后合并时冲突可能有一大堆。在开发过程中,要时不时把自己的分支变基(Rebase)到最新的 master 上,让冲突早点暴露、早点解决,不要等到最后一刻。

合并前一定要先切回目标分支(比如 master),因为合并是把别的分支合并到当前所在的分支。如果不想解决冲突了,可以用 git merge --abort 放弃本次合并,回到合并前的状态。

13.3 回滚与安全

git reset --hard 非常彻底,用的时候一定要小心。它会同时清空工作区、暂存区和提交历史,如果你工作区还有没提交的改动,执行后它们也会一起消失。执行前最好先用 git status 看一眼。

公共分支的回滚优先用 git revert。因为它会创建一个新的 commit 来抵消原来的改动,历史记录仍然保留,以后后悔了还能找回来。

提交信息(-m)要写清楚。一个项目可能有几十上百个 commit,写好说明方便以后查阅。如果不想让 Git 跟踪某些文件,在 .gitignore 里加上它。但注意,.gitignore 只对未跟踪文件生效,已跟踪的文件需要先用 git rm --cached 取消跟踪。

13.4 Stash 与 Worktree 的选择

Stash 适合“临时打断”:先去干点别的,很快就回来。比如修个紧急 bug,切个分支。如果要同时开发多个分支,频繁 stash 和 pop 会非常麻烦。这时候更好的方案是使用 Worktree。

Worktree 的核心优势:一个仓库对应多个工作目录,每个 Worktree 有独立的工作区和暂存区,但所有的 Worktree 共用同一份提交历史。在任何一个 Worktree 里提交,另一个 Worktree 里都能看到。删除 Worktree 不能直接删文件夹,必须用 git worktree remove,否则 Git 记录会残留。

13.5 SSH 与 GitHub

私钥留在本地绝对不要给别人,公钥可以公开。GitHub 用公钥验证你的私钥签名,确认是你本人。

git push -u origin master 里的 -u 是把本地分支和远程分支绑定,以后直接 git push 即可,不用每次都写一长串。

日常开发流程要养成习惯:改代码 → git add . → git commit -m "说明" → git push。这样才能保证 GitHub 上一直有最新的备份。如果本地主分支叫 master,远程默认可能是 main,推送时注意改一下命令里的分支名。

小结: 主分支保持稳定,一个功能一个分支;冲突早暴露早解决;危险命令先 git status;公共分支回滚用 git revert;Stash 适合临时打断,Worktree 适合并行开发;私钥不离本地,日常 add → commit → push 形成习惯。


结语

一旦你理解了工作区、暂存区、提交历史、分支指针、Stash、Worktree 和远程仓库之间的关系,很多命令就不再需要死记硬背:add 是把改动放入暂存区,commit 是把暂存区内容写成提交,restore 是撤销,reset 是移动历史指针,revert 是追加一个反向提交,branch/switch/merge/rebase 是在提交图上移动和拼接分支,stash/worktree 是处理并行工作的两种工具,push/clone 则是把本地历史和远程备份连接起来。

最后记住几条原则:主分支保持稳定,一个功能一个分支,冲突早点暴露早点解决,危险命令先用 git status 看清现场,公共分支回滚优先 git revert,私钥永远留在本地。

发表评论