查看与撤销修改 · Git 与 GitHub
怎么看改了什么,又怎么撤销错误?
课程目录为什么需要它
历史记录的意义就在于能回去。Git 针对不同情况有不同的撤销命令,选对很重要:有的在共享的历史上也安全,有的会改写历史。分得清它们,别人才敢把仓库交给你。
直觉理解
先看:git diff 逐行显示未暂存的修改(+ 是加的,- 是删的);git diff --staged 显示托盘上的内容。
然后按错误在哪里选撤销方式:
| 错误在…… | 命令 |
|---|---|
| 文件里,还没暂存 | git restore 文件 |
| 托盘上 | git restore --staged 文件 |
| 最后一次提交里,还没推送 | git commit --amend |
| 别人已经拿到的提交里 | git revert 提交 |
revert 不抹掉任何东西:它新增一个反向的提交。所以它在共享的历史上是安全的。
定义
差异 Diff
The line-by-line difference between two versions. Lines starting with + were added, lines with - removed.两个版本之间逐行的差别。以 + 开头的行是新增的,以 - 开头的是删除的。
HEAD
The commit you are on now. `HEAD~1` is the one before it.你当前所在的提交。`HEAD~1` 是它前面那一个。
示例
撤销之前先看
在互动课里运行文件里有一处修改:先看看,再丢掉。
echo "print('debug!!!')" >> app.py
git diff
git restore app.py
git status逐步执行
- L2+ 开头的那行就是你刚加的。
+print('debug!!!') - L3restore 把文件恢复成最后一次提交时的样子。
- L4又干净了。
撤销一次提交
在互动课里运行最后一次提交加了一行,把东西弄坏了。revert 新增一个提交,把它去掉。
git log --oneline
git revert HEAD
git log --oneline
cat app.py逐步执行
- L2新增一个提交:Revert "add total"。
- L3历史变长了;什么都没抹掉。
- L4文件又只剩一行了。
print('shop')
常见错误
在共享的历史上 reset --hard
git reset --hard HEAD~1 会把最后一次提交从你的分支上删掉。如果队友已经拉取了它,你们的历史就对不上了。已推送的提交用 revert。
restore 会丢掉修改
git restore 文件 会永久丢掉这个文件里未提交的修改。先看一眼 git diff。
小测验
1. 你提交了一个错别字,而且已经推送了,队友也拉取了。怎么撤销?
查看答案
答案:B
revert 新增一个提交,谁的历史都不会被改写。
2. 最后一条命令打印什么?
echo "print('oops')" >> app.py
git add app.py
git restore --staged app.py
git status查看答案
答案:A
--staged 只是把它从托盘上拿下来。修改还在文件里。
动手练习
3 道练习,分三层:先预测程序的输出,再按新需求改程序,最后从零写一个。代码在浏览器里运行,提交马上判题。
- 预测输出文件里是什么?
准确写出最后一条命令打印的内容。
- 改需求安全地撤销
最后一次提交(
add total)已经推送出去了。这条命令会抹掉它,会弄乱队友的历史。改用安全的方式撤销,让历史保留所有提交。 - 从零写提交前收拾干净
有人留下了两个问题:
config.txt被误放上了托盘,app.py里多了一行调试代码要去掉。把config.txt从托盘上拿下来(文件保留),丢掉app.py里的修改,什么都不要提交。
本课术语
| 术语 | 中文 | 英文定义 |
|---|---|---|
| Diff | 差异 | The line-by-line changes between two versions. |
| HEAD | HEAD | The commit you are currently on. |
| Revert | 反转提交 | A new commit that undoes an earlier one. |