[原文链接:Link] 转载请注明原作者
🍻Git 后悔药
- 💌 一手教材地址:
- 官方永久最新doc发布页: https://git-scm.com/docs/
- $ git switch 教学: https://git-scm.com/docs/git-switch
- $ git restore 教学: https://git-scm.com/docs/git-restore
- $ git reset 教学: https://git-scm.com/docs/git-reset
- $ git revert 教学: https://git-scm.com/docs/git-revert
🍬基础药方:分区看待,对症下药
♻️ 在工作区进行 Ctrl + Z
-
⚓情况:想把一个 modified 文件变成 unmodified 文件 (就是上次 commit 后的干净的文件)
-
方式:
-
(旧)
git checkout -- <file> ...
(Git 2.23.0 版本前 - 2019-8月前) -
(新)
git restore <file> ...
(Git 2.23.0 版本后 - 2019-8月后)(以上基础信息基本只在 $ git commit 前决定是否需要使用)
-
♻️ 在暂存区进行 Ctrl + Z
-
⚓情况:想把一个 staged (已暂存) 文件变回 unstaged 文件,也就是变回仅 modified 但未暂存的文件
-
(旧)
git reset HEAD <file> ...
(Git 2.23.0 版本前 - 2019-8月前) -
(新)
git restore --staged <file> ...
(Git 2.23.0 版本后 - 2019-8月后)(以上基础信息基本只在 $ git commit 前决定是否需要使用)
-
♻️ 在版本库进行 Ctrl + Z
-
目的:回滚某个 commit
-
首先,并不是所有情况都需要回滚commit,
因为正常代码改错了的话,重改完 add 再重新 commit 就好了
-
所以,如下情况才需要回滚commit:
-
(⚓情况1) commit message 写错了,日志被污染
- 解决方案:
git commit --amend
(重新修改上一次的 commit message) (amend v. 修正)
- 解决方案:
-
(⚓情况2) commit 前忘记检查 status, 落下了几个 modified but unstaged 文件忘了 commit
-
解决方案:
-
git add <当初落下的未暂存的那些modified文件>
-
git commit --amend
(重新修改上一次的 commit message,并补上落下的文件)
-
关于 git commit --amend:
其中 –amend 本质是另开一个分叉,把上一个 commit 全部内容进行修正(在新分叉上),
旧的那个分叉就舍弃掉了,只是会留在 git reflog 的记录里,但 git log 再也看不到它了。
此外,$ git commit --amend 等价于 $ git reset --soft HEAD~ (见下节内容)
此外!!
如果你的 commit 已经 push 到了远程仓库,那么使用 --amend 修改 commit 后,
git push 时一定要使用 --force-with-lease 或 -f 参数。否则就会报错。
下节内容同理,一旦回溯,push 则需加 -f 参数。
-
-
(☠️情况3) commit 了严重错误的内容,或不小心 commit 进去了一堆垃圾文件。
- 解决方案:
- ☠️ 超出 $ git commit --amend 能力范围,需要其他指令来完成 (引出下一节内容)
- 解决方案:
-
-
🍬高级药方:$ git reset 的三组药方
-
学完对于三个分区的操作回滚(撤销),你会发现自己对 commit 的回滚管理好像还不能做到尽善尽美
-
这时就需要另外一套解决方案来发挥发挥了,那就是 reset 。
-
其本质是: 对 HEAD 指针及其 branch 位置的更改(主要目的),及其他区域信息的更改(次要,由参数决定)。
git-reset - Reset current HEAD to the specified state
故 reset 并不是撤销, 而是让 HEAD, branch 位置重设
-
另一解读: 由上部分中
$ git commit --amend
引出,reset 通过开分叉,扔