Git 零基础入门:从第一次提交到协作
Git 零基础入门:从第一次提交到同学协作
课堂目标:能解释修改放在哪里,能独立提交一次修改,能通过分支和 Pull Request 与同学协作。
学习方式:先看演示,再自己操作,最后用自己的话解释结果。无需编程基础,今天只编辑 Markdown 文本。
01 · 课程安排与课前准备
| 时间 | 板块 | 你要完成的事 |
|---|---|---|
| 0–15 分钟 | Git 为什么有用 | 区分 Git 与 GitHub,认识仓库 |
| 15–30 分钟 | 环境与练习项目 | 检查 Git,配置提交身份,建立仓库 |
| 30–65 分钟 | 工作区、暂存区、提交 | 做两次提交,解释两个 diff |
| 65–85 分钟 | 分支与历史 | 建分支、切换、观察文件变化 |
| 85–95 分钟 | 休息 | 保留终端与编辑器 |
| 95–130 分钟 | 远程与 PR | 推送分支,审核并合并一次 PR |
| 130–155 分钟 | 冲突与撤销 | 复现冲突,人工解决,辨认撤销范围 |
| 155–175 分钟 | 独立任务 | 完成班级介绍贡献流程 |
| 175–180 分钟 | 回顾 | 回答检查题,使用速查表 |
课前由讲授者准备:Git、文本编辑器(如 VS Code)、平台账号;一个名为 git-classroom 的练习远程仓库,默认分支为 main,已有 README.md。提前邀请同学为协作者并检查推送权限。首次认证可能花时间,宜在课前完成。
课堂使用命令行帮助理解状态;Windows 推荐 Git Bash,macOS 可使用终端。下文的文件内容用编辑器填写并保存,命令在终端执行。包含 <...> 的命令是模板,运行前替换整个占位符,不能直接照抄。示例姓名是虚构的;练习不填写个人敏感信息。
讲授提示:每次输入命令之前,先问“你预计它会改变什么?”执行之后再用
git status验证。
02 · Git 解决什么问题?
如果班级介绍文件叫“最终版”“最终版2”“最终版修复”,很难知道谁改过什么、哪次修改可以保留。Git 为项目保存版本历史,帮助比较变化、查找原因和整合多人修改。
| 名称 | 是什么 | 今天的用途 |
|---|---|---|
| Git | 在电脑上运行的分布式版本控制工具 | 记录提交、管理分支、合并修改 |
| GitHub / GitLab / Gitea | 托管 Git 仓库并提供协作的平台 | 共享提交、创建 PR、审核 |
| Repository / Repo | Git 管理的项目仓库 | 保存文件历史与相关信息 |
.git |
通常位于项目根目录的 Git 元数据目录 | 交给 Git 管理,不手动编辑 |
Git 可以离线提交;远程同步需要能连接远程仓库。 常规 clone 会获得项目历史;浅克隆等特殊方式可能只下载部分历史。
Git 适合文本、代码和 Markdown;也能跟踪图片等二进制文件,但不能像文本那样逐行比较。它不替代所有备份方案。
课堂提问:断网时可以 commit 吗?同学是否能立即看到你的 commit?
可以在本地 commit。同学需通过远程同步或其他传递方式获取它;本地提交不会自动上传。
03 · 第一次配置与本地仓库
检查与配置
git --version
能看到版本号,表示 Git 可以调用。下文使用 switch 和 restore,需要 Git 2.23 或更新版本。
git config --global user.name "你的显示名称"
git config --global user.email "你的提交邮箱"
git config --global --get user.name
git config --global --get user.email
前两条中的内容要改为自己的信息。它们写入提交作者信息,不等于登录 GitHub。公开仓库的提交邮箱可能公开;可使用平台提供的隐私邮箱。--global 对当前系统用户生效;在单个仓库内不带它,可以设置该项目的身份。
本地练习:不依赖网络
在专门的练习目录执行,避免在其他项目内建立嵌套仓库:
mkdir git-local-practice
cd git-local-practice
git init -b main
用编辑器创建 README.md,填入并保存:
# 班级介绍
我们正在学习 Git。
git status
git add README.md
git diff --staged
git commit -m "Add classroom introduction"
git log --oneline
预期:新文件从 Untracked files 进入 Changes to be committed,commit 后工作区干净。这里没有远程仓库,也无需 push。
已有远程项目用 git clone <仓库地址>;新的本地项目用 git init。 clone 后一般不需要再 init。
04 · 核心:工作区、暂存区、本地与远程
| 位置 | 存放什么 | 哪个操作改变它 |
|---|---|---|
| Working Tree 工作区 | 你当前看到和编辑的文件 | 编辑并保存文件 |
| Staging Area 暂存区 | 下一次提交准备采用的文件内容 | git add |
| Local Repository 本地仓库 | 已记录的提交历史 | git commit |
| Remote Repository 远程仓库 | 对方仓库保存的提交与分支 | git push 等同步操作 |
重点:保存文件不等于提交;暂存不等于提交;提交不等于上传。
git add记录执行当时的内容,不会持续跟随你的编辑。
演示一:修改 → 检查 → 暂存 → 提交
在 git-local-practice 中,把 README 的最后一句改为:
我们正在学习 Git,并练习团队协作。
git status
git diff
示意 diff(实际还会有文件路径和行号):
-我们正在学习 Git。
+我们正在学习 Git,并练习团队协作。
- 表示删除的行,+ 表示增加的行;一次替换通常表现为一删一增。然后执行:
git add README.md
git diff
git diff --staged
git commit -m "Describe classroom collaboration practice"
git status
为什么第二次 git diff 没有输出? 修改已暂存,工作区与暂存区一致;用 git diff --staged 才能看下一次提交会包含什么。没有输出不代表没有修改。
| 命令 | 比较对象 | 回答的问题 |
|---|---|---|
git diff |
工作区与暂存区 | 还有哪些已跟踪文件的修改没暂存? |
git diff --staged |
暂存区与当前提交 | 下一次提交准备记录哪些变化? |
git status |
状态摘要 | 新文件、暂存、未暂存分别有哪些? |
普通 git diff 不显示未跟踪新文件的内容。先在编辑器检查,暂存后再用 git diff --staged 检查。
演示二:暂存以后又编辑了
-
README 新增一行
活动:周五读书会。,保存。 -
执行
git add README.md。 -
把这行改成
活动:周六读书会。,再次保存。 -
执行下面三条命令,先观察,不提交。
git status
git diff
git diff --staged
同一个文件可以同时出现于已暂存和未暂存修改中。
周五。暂存区仍是第二步记录的内容。要提交周六,需再次 git add README.md,检查 git diff --staged 后再 commit:
git add README.md
git diff --staged
git commit -m "Add Saturday reading activity"
提交信息与历史
提交记录项目快照,并带有作者、时间、父提交等信息。提交说明由人填写;Git 不会自动知道修改原因。提交哈希用于识别提交,通常可用足够长且无歧义的前缀。
| 模糊说明 | 更便于理解的说明 |
|---|---|
update |
Add Saturday reading activity |
fix |
Fix spelling in classroom introduction |
123 |
Add contribution instructions |
中文提交说明也可以。一次提交尽量围绕一个目的,避免把无关修改放在一起。
git log --oneline
git log --oneline --graph --all
git show HEAD
若进入分页显示,按 q 退出。HEAD 在普通分支工作中指向当前分支,当前分支指向它的最新提交。
05 · 分支:把自己的修改单独推进
分支是指向提交的可移动引用,不是必须复制一份整个项目目录。创建分支后,在这个分支上的新提交不会自动加入 main。
git branch
git switch -c feature/activity
在 README 末尾加上并保存:
负责人:Alice。
git add README.md
git commit -m "Add reading activity coordinator"
git switch main
打开 README,负责人这一行应当消失。然后:
git switch feature/activity
这一行应当回来。切换分支会更新工作区文件,提交仍保存在历史中。
重点:未提交的修改不一定被分支隔离;它们可能跟着切换,也可能使切换被拒绝。课堂中先提交,再切换;遇到拒绝先看
git status。
本地合并演示
git switch main
git merge feature/activity
git log --oneline --graph --all
merge 把指定分支整合进当前分支。这里 main 没有额外提交,通常发生 fast-forward:main 直接前移,不创建新的合并提交。两边各有新提交时,正常 merge 可能创建含两个父提交的合并提交。
检查点:执行 git merge feature/activity 前,为什么要确认当前在 main?
因为合并更新的是当前分支。分支方向弄反,得到的结果就不符合目标。
06 · 远程仓库:clone、push、fetch、pull
从这里开始,切换到课堂远程项目。保留本地练习目录,进入它的父目录:
cd ..
git clone <课堂仓库的HTTPS地址>
cd git-classroom
git remote -v
git status
仓库地址从平台复制,项目文件夹名称以实际 clone 结果为准。HTTPS 与 SSH 都可用;本课采用课前配置好的认证方式。不要把访问令牌写进讲义或提交文件。
origin 是 clone 通常创建的远程名称,不是平台名,也不要求远程必须叫它。远程地址与操作权限是两件事:能 clone 不代表能 push。
| 命令 | 做什么 | 工作区会怎样 |
|---|---|---|
git push |
发送本地提交并请求更新远程分支 | 不提交未提交文件 |
git fetch origin |
获取远程对象与远程跟踪引用 | 不直接修改当前工作区 |
git pull --ff-only |
获取远程更新,只允许快进整合 | 可快进则更新,否则拒绝 |
课堂统一使用显式 --ff-only,避免历史分叉时无意进行其他整合。普通 pull 的整合方式受参数与配置影响,不应简单理解为“覆盖本地”。
git switch main
git pull --ff-only origin main
git switch -c feature/alice-intro
创建 alice.md,填写:
# Alice
- 兴趣:摄影、阅读。
- 本次目标:学会通过 PR 提交修改。
git status
git add alice.md
git diff --staged
git commit -m "Add Alice introduction"
git push -u origin feature/alice-intro
-u 设置上游跟踪关系;以后在此分支通常可直接 git push。push 成功只表示远程有了这个分支,main 尚未因此合并。 每位同学使用不同文件名和分支名。
若无推送权限,请讲授者核对协作者权限。本课不引入 Fork;Fork 是平台层面的仓库复制,与本地 branch 不同。
07 · Pull Request:让同学看过再合并
PR 是平台提供的合并提议,不是 Git 命令;GitLab 常称 Merge Request。git pull 与 Pull Request 不是同一个操作。
创建与审核
在平台打开课堂仓库,进入创建 PR 的页面。不同平台按钮名称可能不同,重点核对:
| 字段 | 本例应选择 |
|---|---|
| Base / Target(目标分支) | main |
| Compare / Source(来源分支) | feature/alice-intro |
| 标题 | Add Alice introduction |
| 描述 | 做了什么、如何检查、需要同学关注什么 |
可以填写这样的描述:
新增 Alice 的介绍文件,包含兴趣与本次学习目标。
已预览 Markdown,并确认此次提交只包含 alice.md。
请检查文字是否清楚,以及是否需要补充介绍字段。
审核者先看 Files changed / Diff:有没有无关文件?有没有敏感信息?内容是否符合任务?如仓库有 CI,也应检查结果。CI 不替代人工审核。
处理一条审核意见
同学建议增加“想练习的命令”。在原分支修改 alice.md 并保存:
- 想练习的命令:git status、git diff。
git add alice.md
git diff --staged
git commit -m "Add commands to practice"
git push
同一来源分支的新提交会更新原 PR,无需再创建一个 PR。 审核通过后,由有权限的人在平台合并。本课无需展开不同合并策略。
合并后的本地同步
git switch main
git pull --ff-only origin main
检查 main 中是否出现 alice.md。平台上的合并不会自动更新你电脑中的 main。
讲授提示:请同学口述“本地 feature → 远程 feature → PR → 远程 main → 本地 main”的五个位置,检查是否把上传与合并混淆。
08 · 冲突:两个合理修改需要人来决定
冲突常见于双方修改同一段内容;同一文件的不同位置往往可以自动合并。删除与修改等情况也可能产生冲突。Git 能处理文本差异,但不能替团队决定最终含义。
可复现演示:回到本地练习目录
以下从 git-classroom 进入 git-local-practice,不推送,不影响课堂远程仓库。在开始前执行 git status,确保工作区干净。
cd ../git-local-practice
git switch main
用编辑器新建 meeting.txt,只写一行 时间待定,保存:
git add meeting.txt
git commit -m "Add meeting time placeholder"
git switch -c demo/alice
把该行改为 会议时间:周五 18:00,保存:
git add meeting.txt
git commit -m "Propose Friday meeting"
git switch main
git switch -c demo/bob
把同一行改为 会议时间:周六 10:00,保存:
git add meeting.txt
git commit -m "Propose Saturday meeting"
git merge demo/alice
git status
这里在 demo/bob 合并 demo/alice,会产生同一行的冲突。文件内容通常类似:
<<<<<<< HEAD
会议时间:周六 10:00
=======
会议时间:周五 18:00
>>>>>>> demo/alice
在这次普通 merge 中,HEAD 一侧来自当前 demo/bob,另一侧来自正在合并的 demo/alice。不要凭“Current / Incoming”字样盲选;先核对双方意图。
解决并完成
假设双方商定 会议时间:周六 14:00,用这行替换整个冲突块,删除所有冲突标记,保存:
git diff
git add meeting.txt
git diff --staged
git commit -m "Resolve meeting time conflict"
git status
git add 告诉 Git 该文件已解决;Git 不会替你验证约定是否正确。检查最终文本后再提交。
如果尚未解决、决定取消这次合并,可以在 merge 进行中执行:
git merge --abort
该命令不能在完成合并后当作撤销命令使用。合并前有未提交修改时,abort 不一定能完整恢复;因此演示从干净工作区开始。
09 · 撤销与忽略:先判断修改处在哪个阶段
三个情形,不要用同一条命令处理
| 情形 | 可用操作 | 影响 |
|---|---|---|
| 加入暂存区,但暂时不想提交 | git restore --staged README.md |
取消暂存,保留工作区内容;本课已有提交 |
| 已跟踪文件的未暂存修改确定不要 | git restore README.md |
用暂存区内容恢复工作区,丢弃该文件未暂存修改 |
| 已提交并共享,想撤销某次效果 | 下一阶段学习 git revert <提交ID> |
新增反向提交,可能出现冲突 |
注意:
git restore README.md默认以暂存区为来源,不保证回到最近一次 commit。执行前先看两个 diff,确认要保留的内容。它不负责删除未跟踪新文件。
小练习:在本地练习仓库的新文件 scratch.md 写一句话,暂存,再用 git restore --staged scratch.md 取消暂存。确认文件仍在;不要与真实项目中的笔记混用。
本课不执行 reset --hard、clean -fd 或 push --force。前两者可能丢弃内容,强制推送可能改写共享分支历史。
.gitignore 示例
在项目根目录创建 .gitignore:
# 本机配置与凭据
.env
.env.*
!.env.example
# 依赖、构建产物与日志
node_modules/
dist/
*.log
这些是常见项目示例,不代表每个项目都必须采用同样规则。.env.example 应只放字段说明与虚构占位值。
.gitignore 主要作用于尚未跟踪的文件,不会让已跟踪文件自动停止跟踪。 若普通文件已经被跟踪,需要另行处理;若凭据已经进入历史,仅删除文件或增加忽略规则不够。先撤销或更换泄露凭据,再与维护者处理历史及副本。
提交 .gitignore 本身,让团队共享忽略规则。课堂可新建 practice.log,运行 git status,观察它不会作为新文件出现。
10 · 常见问题:先看状态,再找原因
| 提示或现象 | 常见原因 | 先做什么 |
|---|---|---|
not a git repository |
终端不在项目目录 | 核对当前目录,进入 clone 的文件夹 |
Author identity unknown |
提交身份未配置 | 检查 user.name 与 user.email |
nothing to commit |
无暂存修改,或编辑未保存 | 保存文件,检查 status 与两个 diff |
| 新文件没有出现在 diff | 文件尚未跟踪 | 在编辑器检查,add 后看 staged diff |
no upstream branch |
分支尚未设置上游 | 首次用 git push -u origin <分支名> |
non-fast-forward / push rejected |
远程分支已有本地缺少的提交等 | status、fetch,核对历史;不要直接 force |
| pull --ff-only 拒绝 | 本地与远程不能快进整合 | 停下来与讲授者检查两边历史 |
| 切分支被拒绝 | 未提交修改可能被覆盖 | 看 status,先保存并处理修改 |
| 认证失败 / 权限不足 | 凭据、仓库地址或权限问题 | 核对地址、账号、协作者权限 |
| 平台没有显示最新内容 | 未 push、查看错分支等 | 核对当前分支、remote 与提交历史 |
求助时提供:正在做什么、刚执行的命令、完整报错、git status。隐藏令牌、密码和其他不应分享的信息。
11 · 独立实战:为班级介绍贡献一页
回到 git-classroom 目录。给自己 20 分钟,先隐藏参考流程:
-
检查状态,在干净工作区切到 main 并同步最新提交。
-
创建自己的分支,如
feature/bob-intro。 -
新建
bob.md,包括标题、兴趣、学习目标三部分。 -
检查文件内容,只暂存这次任务所需文件。
-
查看暂存差异,写清楚提交说明并 commit。
-
推送分支,创建目标为 main 的 PR。
-
与同学互相审查;根据意见修改一次并推送。
-
合并后更新本地 main,验证文件存在。
验收标准:提交包含正确文件;PR 方向正确;能解释 add / commit / push 的差别;能说明如何根据审核意见更新原 PR。
进入课堂项目后执行(使用自己尚未用过的分支名):
git status
git switch main
git pull --ff-only origin main
git switch -c feature/bob-intro
在编辑器创建并保存 bob.md,然后:
git status
git add bob.md
git diff --staged
git commit -m "Add Bob introduction"
git push -u origin feature/bob-intro
创建 PR、审核与合并在平台上完成。后续审核修改仍在原分支提交;合并后切回 main 再 pull。
12 · 五分钟复盘与命令速查
尝试用自己的话回答:
-
Git 与 GitHub 各做什么?
-
为什么 add 后再编辑,需要重新 add?
-
为什么 commit 后同学还看不到修改?
-
push 分支后,main 为什么没有变化?
-
同一个文件被两人修改,一定冲突吗?
-
如何取消暂存并保留修改?
-
为什么
.gitignore不能删除已经提交的秘密? -
不确定 Git 当前状态,先执行哪条命令?
-
Git 管理版本;平台托管仓库与协作。
-
add 记录当时的文件内容,后续编辑不会自动进入暂存区。
-
commit 在本地,还需同步。
-
推送的是自己的分支,还需合并。
-
不一定,Git 常能自动合并互不重叠的修改。
-
git restore --staged <文件>,本课仓库已有提交。 -
忽略规则不会清除过去的提交,也不自动停止跟踪已有文件。
-
git status,随后视需要看两个 diff。
| 目的 | 命令 |
|---|---|
| 获取已有项目 | git clone <地址> |
| 看状态 | git status |
| 看未暂存差异 | git diff |
| 看待提交差异 | git diff --staged |
| 暂存指定文件 | git add <文件> |
| 取消暂存 | git restore --staged <文件> |
| 提交 | git commit -m "说明" |
| 看简洁历史 | git log --oneline |
| 创建并切换分支 | git switch -c <新分支> |
| 切换分支 | git switch <已有分支> |
| 看远程地址 | git remote -v |
| 首次推送当前分支 | git push -u origin <分支> |
| 后续推送 | git push |
| 获取远程信息 | git fetch origin |
| 在 main 上快进同步 | git pull --ff-only origin main |
| 合并进当前分支 | git merge <来源分支> |
日常顺序:检查状态 → 同步 main → 建分支 → 编辑 → 检查 diff → add → 检查 staged diff → commit → push → PR → review → merge → 更新本地 main。
今天最需要记住:知道修改现在在哪里,知道下一条命令会改变什么。遇到不明状态,先看
git status。
附录 · 讲授者的课前核对与下一阶段
-
课前在自己的电脑走完远程认证、clone、推送和 PR 流程。
-
两个练习目录用途不同:本地目录演示状态与冲突,远程目录练习协作。
-
演示命令逐段执行,不要一次粘贴整页。每次 add 与 commit 之间都停下来检查。
-
同学卡住时先让其解释 status,不直接代为输入所有命令。
-
如果网络暂时不可用,先完成本地练习;远程协作部分须恢复连接后实操。
-
下一阶段再学习 revert、stash、reflog、rebase、cherry-pick、标签与 CI;无需今天记住全部命令。
评论
还没有评论,来说两句吧。