Skip to content

第 43 课:Git 与 GitHub 入门

🎯 核心实操目标

本课目标:用规范的版本控制(version control)取代"毕业论文_终稿_打死不改绝对终稿3.docx"这类靠文件名堆叠的手工管理。本课你将掌握 Git 的核心概念(仓库 / 暂存区 / 提交 / 分支)与基础操作(init / add / commit / push),并用 GitHub(或国内替代 Gitee)把论文与代码托管为带完整时间戳、可回溯、可回退、可协作的版本库。

本课位于工具链模块的起点:后续的 Markdown 排版、python-docx 自动化、LaTeX、Jupyter 与 AI 编码代理,产出的都是纯文本(plain text)文件——而纯文本正是 Git 最擅长管理的对象。先把版本控制打好底,后面每一课的成果才有一个安全、可追溯的存放方式。

📋 课前准备(5 分钟自检)

账号

  • [ ] GitHub 账号github.com/signup(免费)
  • [ ] 如墙问题导致 GitHub 注册困难 → 用 Gitee(码云)作为国内替代:gitee.com

工具/环境

  • [ ] Git 命令行git-scm.com/downloads(Windows 安装时勾选”Git Bash Here”)
  • [ ] GitHub Desktop(可选 GUI 客户端,零基础推荐):desktop.github.com
  • [ ] VS Code(推荐 IDE,内置 Git 集成)

配置(首次安装后必做)

bash
git config --global user.name "你的名字"
git config --global user.email "你的邮箱"
git config --global core.quotepath false  # 避免中文文件名乱码

应急通道

  • 命令行恐惧 → 全程使用 GitHub Desktop 图形界面,效果一样
  • SSH key 配置失败 → 用 HTTPS + Personal Access Token 推送
  • 网络问题 → 用 Gitee 替代,或配置 GitHub 镜像代理

场景导入:靠文件名管理版本,迟早会出事

你写到了论文的第五版,发给导师。导师回复:"还是觉得你周一发我的第三版那段论证更有深度,在那个基础上改吧。" 你看着桌面上一堆为了"怕搞混"而重命名的《论文_副本》《论文_旧版_别看》《论文_终稿2》,却想不起来:第三版到第五版之间,自己究竟删掉了哪几条核心论据、改动了哪些段落。

这种困境的根源,是用文件名来记录版本。它有三个无法回避的缺陷:

  1. 不可追溯:文件名只告诉你"这是第几版",记不下"这一版相对上一版改了什么、为什么改"。
  2. 不可回退:你"觉得"第三版更好,却无法把当前稿精确还原到第三版的状态,更无法只取回第三版的某一段。
  3. 易丢失、难协作:副本散落在桌面、U 盘、微信文件里,硬盘故障或勒索软件一次就可能全部失去;多人合作时更会反复覆盖彼此的修改。

版本控制(version control)就是为系统性地解决这三件事而生的工程方法:它为文件的每一次有意义的修改留下一份带时间戳、带说明、可随时回退的快照,并把这些快照串成一条完整、可审计的历史。本课要做的,就是把这套工程界成熟的做法,用到论文与科研代码的日常管理上。


原理:版本控制为什么对科研格外重要

普通的"保存"只保留文件的最新状态,覆盖掉一切历史。版本控制保留的是完整的修改轨迹——它解决的恰好是科研工作流里四个反复出现的真实需求:

  1. 可追溯(traceability):每一次提交都附带一句作者写的说明(如"补方法段,删除 H3 假设")和精确时间戳。三个月后回看,你能清楚知道某段论证是何时、因何加入或删除的。论文写作是一个长期演进的过程,可追溯让这个过程有据可查,而不是只剩一个无从解释的最终稿。
  2. 可回退(revert / restore):导师说"还是第三版好"时,你不必凭记忆手工还原,而能把整个仓库或单个文件精确回到历史上的任意一个提交状态。改坏了、删错了、思路走偏了,都能安全退回——这从根本上消除了"不敢大改"的心理负担。
  3. 可复现(reproducibility):科研的代码与数据分析常被要求"能被他人重跑"。把分析脚本纳入版本控制,并让每一次提交对应一个明确的状态,审稿人或合作者就能取到与你论文结果完全对应的那一版代码,而不是一个来历不明的脚本。这是开放科学对"可复现"的基本要求。
  4. 可协作、防丢失:把仓库推送到 GitHub / Gitee 后,本地与云端互为备份,硬盘损坏不再等于成果归零;多人合作时,每个人的修改都带署名、可追踪、可合并,而不是靠互发文件、互相覆盖。

📐 一句话理解:Git 记的是"差异与历史",不是"一堆副本"

手工版本管理是不断复制整份文件(副本越堆越多、越来越乱);Git 记录的是每次修改相对上一版的差异(diff),并把它们组织成一条有序的历史。所以你的工作目录里永远只有一个文件,而它的全部过往都安全地保存在仓库(一个隐藏的 .git 目录)里,可随时调取任意一版。这就是下图要表达的核心区别。

📘 关键术语(首次出现,先对齐定义)
  • 版本控制(version control):系统化地记录文件随时间的修改,并支持随时查看、比较、回退到任意历史版本的方法。Git 是目前最主流的版本控制工具。
  • 仓库(repository / repo):被 Git 管理的一个项目目录。git init 后,目录里会多出一个隐藏的 .git 子目录,它保存了该项目的全部提交历史与版本数据;删掉 .git 就等于丢掉历史,只剩当前文件。
  • 提交(commit):把当前改动永久记录为一份带说明、带时间戳、带唯一标识的快照。每次 git commit 生成一个提交;一连串提交就构成版本历史。"提交"既是动词(这个动作)也是名词(生成的那份快照)。
  • 暂存区(staging area,又称 index):提交前的"待提交清单"。git add 把改动放进暂存区,git commit 只把暂存区里的内容记入历史。这一中间层让你能精确挑选"这次提交哪些改动",而非每次都全量提交。
  • 哈希(hash / commit ID):每个提交由一串 SHA-1 值唯一标识,日常用其前 7 位短哈希(如 3f8a1c2)来指代某次提交。它就是回退、比较时定位"哪一版"的地址。
  • 版本历史(history / log):所有提交按时间先后串成的链条,用 git log 查看。它就是本课开篇承诺的"可追溯轨迹"。
  • 回退(revert / checkout 还原):把仓库或某个文件恢复到历史上某次提交的状态。注意 git revertgit checkout <hash> -- <文件> 行为不同(下文有专门对照)。
  • 纯文本(plain text):仅由字符构成、可逐行比较差异的文件(如 .md/.tex/.py/.csv)。Git 对纯文本的差异追踪最精确——这也是后续各课都以纯文本为产出的原因(边界见文末【边界与局限】)。
  • 远程仓库(remote)/ 推送(push):托管在 GitHub、Gitee 等服务器上的仓库副本称为远程仓库(默认别名 origin);git push 把本地提交上传到远程,实现备份与协作。

一份文件,一条完整的提交历史

工作目录里始终只保留一个名为"论文_main"的文件;它背后的每一次提交(commit),都是这一时刻的一份完整快照:

传统作坊模式初稿_v1.docx终稿_打死不改.docx乱做一团 无法对比代码级 Git 时间快照流 (只存在一个文件)Commit A"写完引言"Commit B"删除了H3假设"NOW: 回滚瞬间复原到A

🚀 拆解实战:用图形客户端 GitHub Desktop 上手(无需命令行)

📋 零代码入门路径:如果对终端命令有畏难情绪,可以先用图形客户端完成全部核心操作,效果与命令行一致。GitHub Desktop 把"提交、查看历史、回退、推送"都做成了按钮——理解了它的工作流,再去看下一节的命令行,会发现按钮背后就是那几行命令。

步骤一:安装图形客户端

从官网下载并安装 GitHub Desktop。借助它,你无需记忆 git pull / push / commit 等终端命令,相应操作都对应界面上的按钮。

步骤二:建仓库 → 修改 → 提交(commit)

  1. 在软件中点击 Create a New Repository(新建仓库),把你的论文文件夹纳入版本控制,从此该目录的每一次改动都会被它追踪。
  2. 正常在 Word / Markdown 里写作、增删内容。
  3. 写完一段满意的内容后切回 GitHub Desktop,界面会清楚地标出差异:新增的内容显示为 绿色 +,删除的内容显示为 红色 −,让你在提交前就能逐行复核这次到底改了什么。
  4. 在左下角的提交信息框里,写一句清晰、具体的提交说明(如"完成问卷反向题部分的说明段"),然后点击 Commit to main,把这一刻的状态永久记入历史。

步骤三:查看历史与回退(revert)

若三天后导师认为之前的版本更好,无需手工还原:在 History(历史)面板里找到三天前那次提交,右键选择 Revert this commit(撤销此次提交)。GitHub Desktop 会生成一次反向提交,把那次改动整体抵消,使文件内容恢复到该提交之前的状态——且这一回退动作本身也作为一条新记录留在历史里,全程可追溯、可再撤销。

说明Revert this commit 撤销的是某一次提交的全部改动。如果只想取回某个文件的旧版本(而不动其它文件),命令行提供了更精细的做法,见下文 git checkout <hash> -- <文件>


⌨️ 命令行最小回路:从零到云端(可复制 + 真实回显)

GitHub Desktop 的按钮背后就是这几行命令。下面这套"从空文件夹到云端有历史"的最小回路,照着敲一遍,就能理解 init / add / commit / push 各自做了什么,以及它们如何串成一条完整历史。所有命令都可直接复制;命令下方贴的是终端真实回显的样子(commit hash 为 7 位短哈希,你本机生成的会与示例不同)。

第 1 步:建仓库,造第一份正文

bash
mkdir paper && cd paper      # 新建论文文件夹并进入
git init                     # 把当前文件夹变成一个 Git 仓库

回显(Git 2.30+ 默认主分支名为 main):

text
Initialized empty Git repository in /Users/you/paper/.git/

此时新建一份 paper.md(就是你的论文正文,先写引言):

bash
# paper.md 内容示例(焦虑量表反向计分研究,对应 Case A)
# 引言
本研究探讨 Anxiety_4_R 反向计分对量表内部一致性的影响。

第 2 步:看状态 → 暂存 → 提交

bash
git status                       # 看看 Git 现在“眼里”有什么

回显——paper.md未被追踪(Untracked)的红色文件:

text
On branch main

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
	paper.md

nothing added to commit but untracked files present (use "git add" to track)

把它放进暂存区(staging area),再提交记入历史:

bash
git add .                        # 把改动放进暂存区(. 表示当前目录所有改动)
git commit -m "写完引言"          # 盖章:这一刻的快照被永久记录

commit 的真实回显(3f8a1c2 是本次生成的短哈希,你的会不同):

text
[main (root-commit) 3f8a1c2] 写完引言
 1 file changed, 3 insertions(+)
 create mode 100644 paper.md

第 3 步:用 log 查看你的时间轴

再改一次正文(比如补上方法段、删掉一条假设),git add . + git commit -m "补方法段,删除 H3 假设" 之后,看历史:

bash
git log --oneline                # 一行一个 commit,最上面是最新的

回显——每行 = 一次提交,左边是短哈希、右边是你写的提交说明:

text
9b2e7d4 (HEAD -> main) 补方法段,删除 H3 假设
3f8a1c2 写完引言

如果想看带时间戳的完整信息:

bash
git log --pretty=format:"%h  %ad  %s" --date=format:"%Y-%m-%d %H:%M"
text
9b2e7d4  2026-06-07 21:48  补方法段,删除 H3 假设
3f8a1c2  2026-06-07 20:15  写完引言

到这里,你已经拥有了一条带完整时间戳、可回溯的本地历史——这正是开篇所说"可追溯轨迹"的具体形态。

提交说明写好 vs 写砸:决定历史是否可读

commit 后面那句说明(-m 的内容)不是走过场。版本历史能不能在三个月后帮到你,几乎全取决于这些说明写得是否具体、可检索。同样一次提交,下面两种写法的差距,到回退时才会显现:

写砸 ❌写好 ✅为什么
git commit -m "改了点东西"git commit -m "补方法段,删除 H3 假设""改了点东西"在 git log 里等于没写;具体说明让你日后一眼定位该回到哪一版
git commit -m "update" / "1" / "."git commit -m "引言加入反向计分研究背景"占位式说明无法检索;按"做了什么"描述,历史才可被搜索、可被复盘
攒一周改动一次性 git commit -m "周末的修改"每完成一个逻辑完整的小改动就提交一次,说明对应该改动大颗粒提交无法精细回退(想退一处却牵连一片);小步提交才能精准回到任意中间状态
git commit -m "终于对了!!!气死我了"git commit -m "修正问卷信度计算口径"情绪宣泄不携带信息;提交说明是写给"未来的你和合作者"看的工作记录

💡 一句话判据

检验一条提交说明是否合格,问一句:三个月后只看这行字,你能不能想起这次到底改了什么、为什么改? 答得上来,它就配得上"可追溯历史";答不上来,等于给未来的自己埋了一个无法回退的盲点。


🧹 论文仓库 .gitignore 模板(填好可直接用)

把下面的内容存成仓库根目录的 .gitignore 文件,Git 就会自动无视这些文件,git status 里再也不会冒出一堆噪音。这是一份已经填好的真实模板,按论文场景注释:

点击展开:论文仓库 .gitignore 完整范例
gitignore
# ===== Word / Office 临时文件 =====
~$*.docx          # Word 打开文档时生成的锁文件(见下方说明)
~$*.doc
~$*.xlsx
*.tmp             # 各类临时文件

# ===== Python / Notebook 中间产物 =====
__pycache__/      # Python 字节码缓存目录,纯机器产物,无需进版本库
*.pyc
.ipynb_checkpoints/   # Jupyter 自动保存的检查点,会反复变动制造噪音

# ===== 大数据文件(不进 Git,单独备份)=====
/data/            # 原始数据目录:问卷 CSV、SPSS .sav 等大文件不入库
*.sav
*.zip

# ===== 系统杂物 =====
.DS_Store         # macOS 目录元数据
Thumbs.db         # Windows 缩略图缓存

为什么 Word 临时文件(~$*.docx)必须忽略? 当你用 Word 打开 论文.docx 时,同目录会瞬间生成一个名为 ~$论文.docx隐藏锁文件,用来记录“谁正在编辑、防止两人同时改”。它有两个麻烦:① 你一关闭 Word 它就消失,于是 git status 永远在“多出一个文件 / 又少了一个文件”之间反复横跳,制造无意义的提交噪音;② 它内含编辑者用户名等本地信息,不该被提交到云端。所以把 ~$*.docx 写进 .gitignore,让 Git 彻底当它不存在。

大文件为何也忽略? /data/ 里的问卷原始数据动辄几十 MB,Git 擅长追踪文本差异、不擅长存二进制大文件。原始数据应单独归档备份,版本库只追踪你的正文、代码与分析脚本。


⏪ 命令行取回旧版正文:log 找 hash → checkout 单文件还原

GitHub Desktop 的 Revert 是“整次提交全部推翻”。命令行更精细:只把某一个文件还原到历史上的某一版,其它文件原封不动。这正是“导师说第三版的引言更好,只要那一段”的标准场景。

对照演示——假设当前 paper.md 引言已被你改乱,想取回“写完引言”那一版的正文:

bash
# ① 先用 log 找到目标版本的短哈希
git log --oneline
text
9b2e7d4 (HEAD -> main) 补方法段,删除 H3 假设
3f8a1c2 写完引言          ← 就要这一版的 paper.md
bash
# ② 用 checkout <hash> -- <文件> 只取回这一个文件的旧版正文
git checkout 3f8a1c2 -- paper.md
操作影响范围适用场景
git checkout <hash> -- paper.mdpaper.md 还原到该提交的版本,其它文件不动,历史不被改写只想找回某一段旧正文
Revert this commit(Desktop)整次提交的所有改动反向抹掉,并生成一条新提交想整体撤销某次提交

执行后 paper.md 已是旧版内容,但它现在处于“已修改待提交”状态,确认满意后照常 git add . && git commit -m "引言回退到 3f8a1c2 版本" 即可把这次回退也记入历史。


☁️ 首次推送到云端:remote addpush,以及常见报错处理

本地有了历史,最后一步是推到 GitHub(或 Gitee)。先在网站上新建一个空仓库(不要勾选自动生成 README,否则首次推送会冲突),复制它给你的仓库地址,然后:

bash
git remote add origin https://github.com/你的用户名/paper.git   # 绑定云端地址,别名 origin
git branch -M main                                              # 确保本地主分支叫 main
git push -u origin main                                         # 首次推送,-u 记住关联,以后直接 git push

成功的真实回显大致如下:

text
Enumerating objects: 6, done.
Counting objects: 100% (6/6), done.
Writing objects: 100% (6/6), 412 bytes | 412.00 KiB/s, done.
Total 6 (delta 0), reused 0 (delta 0)
To https://github.com/你的用户名/paper.git
 * [new branch]      main -> main
branch 'main' set up to track 'origin/main'.

HTTPS / PAT 首次推送的常见报错与处理

如今 GitHub 的 HTTPS 推送不能再用账户密码,必须用 Personal Access Token(PAT)。下面是真实会遇到的报错原文与对策:

报错原文(节选)原因处理
remote: Support for password authentication was removed. fatal: Authentication failed for '...'还在用网页登录密码推送到 GitHub → Settings → Developer settings → Personal access tokens 生成一个 token,推送时弹出的“密码”框里粘贴 token而非密码
error: remote origin already exists.git remote add origin 重复执行了改用 git remote set-url origin <新地址> 覆盖,或先 git remote remove origin 再加
! [rejected] main -> main (fetch first)云端仓库非空(建仓时勾了 README),本地落后git pull origin main --allow-unrelated-histories 合并,再 git push
fatal: unable to access '...': Failed to connect ... port 443网络无法连通 GitHub改用 Gitee 仓库地址,或配置代理后重试(见课前“应急通道”)
Updates were rejected because the remote contains work that you do not have同上,远端有你本地没有的提交git pull --rebase origin main 后再推

PAT 一次配好、长期省心:在 token 弹窗里粘贴一次后,Windows 凭据管理器 / macOS 钥匙串会帮你记住,之后 git push 不再反复问密码。token 形如 ghp_xxxxxxxxxxxxxxxxxxxx请妥善保管、不要写进任何会被提交的文件(这也是上面 .gitignore 要忽略敏感文件的延伸理由)。


🔁 第二个完整示例:用 Git 管理一个可复现的分析仓库(Case C)

前面的例子管的是论文正文(paper.md)。Git 对科研更大的价值,体现在管理分析代码 + 结果上——因为这正是审稿人要求"可复现"时你要交出去的东西。下面用 Case C(LLM 评估:300 篇摘要 × 3 个模型,配对比较质量评分 Quality_GPT5 / Quality_Claude47 / Quality_Gemini25,1–5 分、3 名标注者,基准模型为 Claude 4.7) 演示一个典型的"分析仓库"如何用 Git 维护其演进历史。整套命令与前面同源,可直接复制。

场景:你写了一个评分一致性分析脚本 analyze_ratings.py,跑出一张结果表 results/icc_table.csv。审稿人要求"补一个标注者一致性指标(ICC)"。下面演示如何把这次修改记成一条清晰、可回退的历史。

第 1 步:建仓库,纳入脚本,先排除大数据与中间产物

bash
mkdir llm-eval && cd llm-eval         # 新建分析仓库并进入
git init                              # 初始化为 Git 仓库

新建 .gitignore先把原始评分大数据与缓存挡在版本库之外(理由见上一节"大文件为何也忽略"):

gitignore
# Case C 分析仓库:只追踪脚本与结果,不追踪原始大数据与缓存
/data/raw_ratings.csv     # 300×3 原始评分(大文件,单独归档备份)
__pycache__/              # Python 字节码缓存
*.log                     # 运行日志

把脚本纳入版本控制并提交首版:

bash
git add analyze_ratings.py .gitignore   # 只暂存脚本与忽略规则
git commit -m "初版评分分析脚本:计算三模型质量均值与配对差异"

第 2 步:每完成一个分析步骤,提交一次(让历史对应"做了什么")

补上审稿人要求的 ICC 计算后,把"代码改动 + 新结果"作为一次逻辑完整的提交记入历史:

bash
git add analyze_ratings.py results/icc_table.csv   # 脚本与新产出的结果一起提交
git commit -m "新增标注者一致性 ICC(2,k) 计算,输出 results/icc_table.csv"

查看这条"代码即历史"的演进:

bash
git log --oneline
text
b7c4e90 (HEAD -> main) 新增标注者一致性 ICC(2,k) 计算,输出 results/icc_table.csv
a1d9f63 初版评分分析脚本:计算三模型质量均值与配对差异

第 3 步:审稿意见被推翻时,安全回退到上一版脚本

如果后来发现 ICC 的口径选错了、想退回"加 ICC 之前"那版脚本重做,用短哈希只还原脚本这一个文件,结果文件和其它内容不受影响:

bash
git checkout a1d9f63 -- analyze_ratings.py   # 只把脚本还原到首版,其它文件不动

此时脚本已回到首版内容、处于"待提交"状态,确认无误后照常 git add . && git commit -m "ICC 口径重做,脚本回退到 a1d9f63 版本" 即可把这次调整也记入历史。

🔁 迁移要点

对比"论文正文"与"分析仓库"两个例子,命令一字未变init / add / commit / log / checkout),变的只是被管理的对象:从 paper.md 换成 analyze_ratings.py + 结果表。要点有三:① 脚本与结果进库、原始大数据用 .gitignore 挡在库外;② 每个分析步骤一次提交,提交说明写清"算了什么";③ 审稿口径反复时,用单文件 checkout 安全回退。把对象换成你学科的分析脚本(Case A 的信效度计算、Case B 的回归代码),这套流程同样适用——这正是"可复现仓库"的日常维护方式。


常见误区与纠正

学员初用 Git 时,问题高度集中在几处,下表对号入座即可:

常见误区症状纠正方法
改完不提交,攒一大批再 commit一次提交混入十几处无关改动,想回退一处却牵连一片每完成一个逻辑完整的小改动就 git add + git commit 一次,提交粒度小才好精细回退
提交说明写 "update" / "1" / "改了下"git log 全是无信息的占位句,历史等于没记按"做了什么"写具体说明(见上文"写好 vs 写砸"对照),让历史可检索
把大数据 / 二进制文件直接入库仓库迅速膨胀、push 极慢,git diff 对二进制也看不出差异.gitignore 排除 /data/.sav.zip 等;原始数据单独归档备份
把 token / 密码 / 密钥写进文件并提交敏感信息进入历史,即使删除也仍留在历史记录里、可被检索敏感信息一律 .gitignore 忽略或用环境变量;切勿提交,token 形如 ghp_... 绝不入库
git add 后改了文件又忘记重新 add提交的是上次 add 时的旧内容,新改动没进这次提交记住 commit 只记暂存区内容;改动后要重新 git addcommit,或用 git status 核对
首次推送前在 GitHub 勾了自动 README远端非空导致 ! [rejected] ... (fetch first)建空仓库(不勾 README),或按上文报错表先 git pull --allow-unrelated-histories 再推
以为 GitHub 等于"自动备份盘"改了不提交、提交了不 push,云端其实没有最新版备份只在你提交并推送之后才生效;养成"改完即提交、阶段性即推送"的习惯

出错 / 报错怎么办:命令行排查的通用思路

命令行报错不必慌——Git 的报错信息通常已写明原因和建议动作。按下面顺序排查,多数问题能自助解决:

  1. git status:它是 Git 的"仪表盘"。绝大多数"不知道现在是什么状态"的困惑,跑一次 git status 就清楚了——它会告诉你当前在哪个分支、哪些文件已暂存 / 未暂存 / 未追踪,以及下一步可用的命令。
  2. 读完整报错,尤其括号里的提示:Git 的报错常直接给出建议命令(如 (use "git add <file>..." to ...)(fetch first))。把报错原文(尤其第一行 fatal: / error: / rejected)对照上文的报错表,或原样复制去检索,往往一步定位。
  3. 推送类报错先分清"认证"还是"落后":含 Authentication failed / password authentication was removed认证问题(用 PAT,见上文);含 rejected / fetch first / remote contains work本地落后于远端,先 pull 合并再 push
  4. 回退误操作前先确认范围:想撤销时分清三种动作——git checkout <hash> -- <文件>(只还原单个文件)、git revert <hash>(生成反向提交、抵消某次提交、历史保留)、git reset(移动分支指针、会改写历史,新手慎用)。拿不准时优先用前两个不改写历史的方式。
  5. 实在卡住,把报错原文交给 AI:把完整命令 + 完整报错贴给 AI 助手,让它解释含义并给出修复命令——但执行任何"会改写历史 / 删文件"的命令前,先用 git status 看清当前状态,理解每一步再动手。

⚠️ 一条安全底线

凡是带 --forcereset --hardclean -fd 的命令都可能不可逆地丢弃改动或历史。在自己尚未完全理解其后果前,不要照搬网上或 AI 给的此类命令;先 git status 确认状态、必要时先 git commit 留一份快照,再操作。


边界与局限:Git 适合什么、不适合什么

Git 强大,但不是万能。把下面几条边界记牢,能避免大量"用错工具"的麻烦:

边界 / 失效场景为什么会这样你应该怎么做
擅长纯文本,不擅长大二进制文件Git 按行比较差异来高效存储;.docx/.xlsx/.sav/图片/视频是二进制,改一点就要存一整份新副本,仓库迅速膨胀且 git diff 看不出改了什么文本类(.md/.tex/.py/.csv)尽量纳入 Git;大二进制与原始数据用 .gitignore 排除、单独归档;确需为大文件做版本管理时了解 Git LFS(大文件存储)
能看 Word 文件"变没变",但看不清"改了哪句".docx 是压缩二进制,Git 只能判断它整体变化、无法逐句对比需要逐句追踪修改时,写作改用 Markdown / LaTeX 纯文本(正是后续课程的方向);用 Word 时靠"修订模式"补足
版本控制 ≠ 自动备份Git 记录的是你主动提交的快照;没提交的改动、没推送的本地提交,云端都没有改完即 commit,阶段性即 push;重要成果再叠加一份独立的异地 / 网盘备份,不把鸡蛋放一个篮子
管得了"文件版本",管不了"运行环境"Git 只追踪文件内容,不记录你的 Python 版本、库依赖、系统环境真正的可复现还需配套:用 requirements.txt / environment.yml 锁定依赖,必要时配合容器(container,如 Docker)固定整套运行环境
公开仓库会暴露你提交的一切推到公开 GitHub 仓库的内容(含历史里曾出现过的敏感信息)任何人可见,且历史难以彻底抹除敏感数据 / 密钥绝不提交(.gitignore 把关);涉私涉密项目用私有仓库;一旦误提交密钥,立即作废该密钥
解决冲突、回退历史有学习成本多人改同一处会产生合并冲突(merge conflict),需要人工判断保留哪一版;高级回退命令理解不当可能丢改动本课只覆盖单人基础流程;冲突解决、分支协作属进阶内容,遇到时再针对性学习,先掌握"提交—推送—回退"的安全闭环

💡 一句话定位

Git 是纯文本的时间机器协作底座,不是网盘、不是 Word 的修订模式、也不能单独保证"换台电脑就能重跑"。把它用在它擅长的地方(追踪文本、记录历史、托管协作),其余需求用配套工具(异地备份、依赖锁定、容器)补齐,才是完整的科研可复现方案。


📦 本课交付物

按本节实操任务完成并提交以下内容,提交 AI 初审,按 Module_Rubrics.md 对应维度评分:

  • [ ] 本节实操产出:本节任务区块要求的具体文件 / 文本 / 截图
  • [ ] AI 协作日志:至少 1 段完整的"任务描述 → AI 输出 → 人工修正"对话记录
  • [ ] 四维质检记录:用 Course_QA_Checklists.md(事实/逻辑/格式/引用)核查本节 AI 输出的笔记
  • [ ] 沉淀模板:将本课关键 Prompt / 流程 / 检查清单加入你的个人工具箱

🏁 本章小结

把本课凝练成可据以复习的几条要点:

  1. 要解决的问题:靠文件名("终稿_v3")管理版本,必然走向不可追溯、不可回退、易丢失。版本控制(version control)为每一次有意义的修改留下带时间戳、带说明、可回退的快照,从根本上解决这三件事。
  2. 为什么科研需要它:可追溯(每次提交可解释)、可回退(精确还原到任意历史版本或单个文件)、可复现(让审稿人取到与论文结果对应的那版代码)、可协作防丢失(云端备份 + 署名可追踪)。
  3. 核心概念:仓库(repository,即被管理的目录 + 隐藏的 .git 历史)、提交(commit,一份永久快照)、暂存区(staging area,addcommit 之间的待提交清单)、哈希(短哈希定位某次提交)、远程仓库与推送(pushorigin 实现备份协作)。
  4. 基础操作闭环init(建仓)→ 改文件 → add(暂存)→ commit(记入历史,写好说明)→ log(查看历史)→ checkout <hash> -- <文件>revert(回退)→ remote add + push(推送上云)。图形客户端 GitHub Desktop 的按钮与这套命令一一对应。
  5. 关键习惯:小步提交 + 写具体的提交说明("补方法段,删除 H3 假设"而非"update");用 .gitignore 把大数据、临时文件、敏感信息挡在版本库外;改完即提交、阶段性即推送。
  6. 边界要清楚:Git 擅长纯文本、不擅长大二进制;它不是自动备份盘、也不单独保证运行环境可复现;冲突解决与高级回退属进阶。把它用在擅长之处,其余用配套工具(异地备份、依赖锁定、容器)补齐。

自测清单(可保留逐项打勾)

  • [ ] 我不再靠"复制 + 重命名 Word 文档"管理论文版本,而是用 commit 把每次修改记入可回退的历史。
  • [ ] 我能说清仓库 / 提交 / 暂存区三个概念,并知道 commit 只记录暂存区里的内容。
  • [ ] 我能独立跑通 init → add → commit → log 的本地闭环,并写出具体、可检索的提交说明。
  • [ ] 我会用 git checkout <hash> -- <文件> 只取回某个文件的旧版本,并能说出它与 Revert this commit 的区别。
  • [ ] 我能把本地仓库 push 到 GitHub / Gitee,且遇到认证(PAT)或"远端非空"报错时知道如何对照处理。
  • [ ] 我用 .gitignore 排除了大数据、临时文件与敏感信息,且清楚 Git 不擅长管大二进制文件、不等于自动备份。

✍️ 思考与练习

下列练习用于把本节概念用起来(区别于"本课交付物"里的任务),建议写在你的本地笔记中。

练习 1(提交说明辨析)。 同学 A 一周只提交一次,说明写"周末的修改";同学 B 每完成一处改动就提交一次,说明写清"做了什么"(如"引言加入反向计分研究背景")。三个月后导师要求"退回加方法段之前那一版"。请说明谁能更快、更精确地完成回退,为什么;并指出 A 的两个具体问题。

好答案要点:B 更快更精确——小颗粒提交 + 具体说明,使他能在 git log一眼定位目标版本、且回退时不牵连无关改动;A 的问题:① 一次提交混入一周内多处无关改动,无法只退"方法段"而不影响其它;② 说明"周末的修改"无信息、不可检索,git log 里等于没记。能点出"提交粒度"与"说明可检索性"两点即达标。

练习 2(回退方式选择,紧扣 Case C)。 在 Case C 的分析仓库里,你最近一次提交"新增 ICC 计算"同时改了 analyze_ratings.pyresults/icc_table.csv。现在你只想把脚本退回到上一版重做,但要保留刚生成的结果表。下列哪种做法合适,为什么另外两种不合适?(a) git checkout <上一版hash> -- analyze_ratings.py;(b) git revert <最近一次提交>;(c) git reset --hard <上一版hash>

好答案要点:选 (a)——它只把单个文件 analyze_ratings.py 还原到指定版本,其它文件(含结果表)原封不动,且不改写历史。(b) 会把"那次提交的全部改动"整体抵消,连结果表的新增也一并撤销,不符合"保留结果"的要求;(c) reset --hard 会把整个工作区强制回退、丢弃未提交改动且改写分支历史,既误删结果表又有不可逆风险,新手应避免。能讲清"单文件 vs 整次提交 vs 整库、是否改写历史"的区别即达标。

练习 3(边界识别)。 某同学把 50 张实验照片、一个 800MB 的 raw_ratings.csv 和三个 .docx 草稿全部 git add 后提交,还顺手把含数据库密码的 config.py 一起提交,并推到了公开 GitHub 仓库。请指出这里至少三个问题,并给出正确做法。

好答案要点:① 大二进制 / 大数据入库——照片与 800MB CSV 让仓库膨胀、diff 看不出改动,应用 .gitignore 排除、原始数据单独归档(必要时了解 Git LFS);② .docx 逐句不可比——Word 是二进制,Git 只知"变没变"看不清"改哪句",需逐句追踪应改用 Markdown/LaTeX;③ 密钥进了公开仓库历史——config.py 里的密码任何人可见且历史难彻底抹除,应 .gitignore 忽略、改用环境变量,且立即作废该密码、改用私有仓库。能点出"Git 不擅长大二进制、公开仓库暴露一切"两条边界即达标。

练习 4(可复现的边界)。 你把分析脚本完整提交并推送到了 GitHub,自认为"已经可复现了"。半年后合作者克隆仓库却跑不起来——报错缺少某个库、且结果与你论文里的数略有出入。请用本课【边界与局限】解释为什么"代码进了 Git"不等于"可复现",并说出两条补救措施。

好答案要点:Git 只追踪文件内容,不记录运行环境(Python 版本、库依赖、系统),所以代码入库不能保证他人环境下能跑、能复现同一结果。补救:① 用 requirements.txt / environment.yml 锁定库与版本并一并提交;② 必要时用容器(container,如 Docker)固定整套运行环境;(可补充:把"对应论文结果的那次提交"打标记/记录其哈希,确保取到的是正确版本)。能点出"Git 管文件不管环境"这条边界即达标。

助力学者在 AI 时代极速产出高质量学术成果 · 55 课时双轨制 · plan v3.3