提交 · Git 与 GitHub
怎么保存工作的各个版本?
课程目录为什么需要它
「最终版.doc、最终版2.doc、真的最终版.doc」就是手工做版本管理。Git 把这件事做得很规范:每个保存的版本(一次提交)都有说明、作者和时间,而且随时能回去。每个软件团队都在用它,你的 GitHub 主页也是由它构成的。
直觉理解
想象三个地方:
- 工作区:你正在编辑的文件。
- 暂存区:一个托盘,放下一张快照要包含的修改(
git add)。 - 历史:快照本身(
git commit)。
git status 告诉你每个地方有什么。git log 列出所有快照,最新的在前。
托盘让你能挑选:你改了三个文件,但只有两个是一回事,就只把这两个放进去,配一句清楚的说明提交。
定义
提交 Commit
A snapshot of the staged files with a message. It gets an id (a hash like 1abf82a) and points to the commit before it.暂存文件的一张快照,带一句说明。它有一个编号(类似 1abf82a 的哈希值),并指向它前面的那个提交。
仓库 Repository
A folder Git tracks, with its whole history stored in a hidden .git folder. `git init` turns a folder into one.被 Git 管理的文件夹,全部历史存在隐藏的 .git 文件夹里。`git init` 把一个文件夹变成仓库。
示例
第一次提交
在互动课里运行开始管理这个文件夹,暂存两个文件,保存第一张快照。
git init
git status
git add app.py README.md
git commit -m "first version"
git status逐步执行
- L1这个文件夹现在是仓库了。
- L2两个文件都是未跟踪的:Git 看得到,但没有在保存它们。
- L3把两个都放上托盘。
- L4-m 写说明。快照保存好了。
- L5没有要提交的了:工作区是干净的。
挑选要提交的内容
在互动课里运行两处修改,两次提交,各有各的说明。
echo "print('welcome')" >> app.py
echo "Run with python app.py" >> README.md
git add README.md
git commit -m "explain how to run"
git status
git commit -am "add welcome message"
git log --oneline逐步执行
- L3只有 README 放上了托盘。
- L5app.py 仍然是已修改、未提交。
- L6-a 会把所有改过的已跟踪文件一起暂存,再提交。
- L7三次提交,最新的在前。
常见错误
说明写成「更新」
半年后,「更新」什么也说明不了。写清楚改了什么、为什么:「修复购物车为空时的总价」。
一次巨大的提交
把修 bug、新功能、格式调整混在一次提交里,以后就没法只撤销其中一个。每件事单独提交。
小测验
1. 你改了一个文件,没有 `git add` 就运行了 `git commit -m "fix"`。会怎样?
查看答案
答案:B
commit 保存的是托盘上的东西。先 git add,或者对已跟踪的文件用 commit -a。
2. 最后一条命令打印什么?
git init
git add app.py
git commit -m "add app"
git status查看答案
答案:A
只加了 app.py,所以 README.md 仍然未跟踪。
动手练习
3 道练习,分三层:先预测程序的输出,再按新需求改程序,最后从零写一个。代码在浏览器里运行,提交马上判题。
- 预测输出暂存了什么?
执行完这些命令后,哪一句是对的?
- 改需求没东西可提交?
这里想做第一次提交,但失败了。修好它,让两个文件都被提交,工作区干净。
- 从零写两次干净的提交
建一个仓库。先只提交 README.md,说明写
add readme;再提交 app.py,说明写add app。
本课术语
| 术语 | 中文 | 英文定义 |
|---|---|---|
| Version control | 版本控制 | Keeping every saved version of files so you can compare and go back. |
| Commit | 提交 | One saved snapshot in Git's history, with a message. |
| Staging area | 暂存区 | The changes chosen for the next commit. |