-
1. 起步
-
2. Git 基础
-
3. Git 分支
-
4. 服务器上的 Git
- 4.1 协议
- 4.2 在服务器上部署 Git
- 4.3 生成 SSH 公钥
- 4.4 架设服务器
- 4.5 Git Daemon
- 4.6 Smart HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 第三方托管服务
- 4.10 小结
-
5. 分布式 Git
-
A1. 附录 A: Git 在其他环境
- A1.1 图形界面
- A1.2 Visual Studio 中的 Git
- A1.3 Visual Studio Code 中的 Git
- A1.4 IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine 中的 Git
- A1.5 Sublime Text 中的 Git
- A1.6 Bash 中的 Git
- A1.7 Zsh 中的 Git
- A1.8 PowerShell 中的 Git
- A1.9 小结
-
A2. 附录 B: 在应用程序中嵌入 Git
-
A3. 附录 C: Git 命令
2.4 Git 基础 - 撤销操作
撤销操作
在任何阶段,你都可能想要撤销某些操作。在这里,我们将回顾一些用于撤销已做修改的基本工具。请务必小心,因为有些撤销操作是不可逆的。这是 Git 中少数几个如果操作不当可能会丢失数据的地方。
一种常见的撤销场景是:提交得太早,可能忘了添加某些文件,或者提交信息写错了。如果你想重做这次提交,可以进行遗漏的修改,暂存它们,然后使用 --amend 选项进行再次提交:
$ git commit --amend
此命令会将暂存区中的内容提交。如果你自上次提交后没有做任何修改(例如,在上一次提交后立即运行此命令),那么快照将完全保持不变,你唯一能改变的就是提交信息。
同样会启动提交信息编辑器,但其中已经包含了上一次提交的信息。你可以像往常一样编辑该信息,但这会覆盖掉上一次的提交。
例如,如果你执行了提交,然后意识到忘记暂存某个你想添加到本次提交中的文件,你可以执行以下操作:
$ git commit -m 'Initial commit'
$ git add forgotten_file
$ git commit --amend
最终你只会得到一次提交 —— 第二次提交会替换掉第一次提交的结果。
|
注意
|
理解这一点很重要:当你修改(amend)上一次提交时,并不是在“修复”它,而是将其完全 替换 为一个新的、经过改进的提交,旧的提交会被移除。实际上,就像之前的提交从未发生过一样,它不会出现在你的仓库历史中。 修改提交的显而易见的好处是,可以对上一次提交进行微小的改进,而不会在仓库历史中留下类似“哎呀,忘了添加一个文件”或“糟糕,修改上一次提交的拼写错误”这样的提交信息。 |
|
注意
|
只能修改那些尚在本地且未推送出去的提交。修改已经推送过的提交并强制推送该分支,会给你的协作开发者带来问题。关于当你这样做时会发生什么,以及如果你身处接收端该如何恢复,请阅读 变基的风险。 |
取消暂存已暂存的文件
接下来的两节将演示如何处理暂存区和工作目录中的变更。好消息是,用来确定这两个区域状态的命令,也会提醒你如何撤销对它们的修改。例如,假设你修改了两个文件,想把它们作为两次独立的修改分别提交,但你不小心输入了 git add *,结果把两个文件都暂存了。该如何撤销其中一个文件的暂存呢?git status 命令会提醒你:
$ git add *
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
renamed: README.md -> README
modified: CONTRIBUTING.md
在“Changes to be committed”(要提交的变更)文本下方,它提示可以使用 git reset HEAD <file>… 来取消暂存。那么,我们按照这个建议来取消 CONTRIBUTING.md 文件的暂存:
$ git reset HEAD CONTRIBUTING.md
Unstaged changes after reset:
M CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
renamed: README.md -> README
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: CONTRIBUTING.md
该命令看起来有点奇怪,但确实有效。现在 CONTRIBUTING.md 文件处于已修改但未暂存的状态。
|
注意
|
诚然, |
目前,关于 git reset 命令,你只需要知道这个“魔法指令”即可。我们将在 重置揭秘 中深入探讨 reset 的原理,以及如何通过它掌握真正高级的技巧。
撤销对文件的修改
如果你意识到不想保留对 CONTRIBUTING.md 文件的修改该怎么办?如何轻松地取消修改 —— 即将其还原为上一次提交(或刚克隆时,或者无论你通过什么方式将其放入工作目录时)的样子?幸运的是,git status 也告诉了你如何做。在上一个示例的输出中,未暂存区域看起来是这样的:
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: CONTRIBUTING.md
它非常明确地告诉你如何丢弃所做的修改。让我们按照它的指示操作:
$ git checkout -- CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
renamed: README.md -> README
可以看到,修改已经被还原了。
|
重要提示
|
理解 |
如果你想保留所做的修改但又需要暂时将其搁置,我们将在 Git 分支 一章中介绍储藏(stashing)和分支(branching);通常那些方法是更好的选择。
请记住,Git 中任何 已提交 的东西几乎总是可以恢复的。即使是已删除分支上的提交,或者被 --amend 提交覆盖的提交,都是可以恢复的(参见 数据恢复)。然而,任何未提交而丢失的内容,很可能就永远找不回来了。
使用 git restore 撤销操作
Git 2.23.0 版本引入了一个新命令:git restore。它基本上是 git reset(我们刚刚介绍过)的替代方案。从 Git 2.23.0 版本开始,对于许多撤销操作,Git 将使用 git restore 而不是 git reset。
让我们重走一遍之前的步骤,这次改用 git restore 而不是 git reset 来撤销操作。
使用 git restore 取消暂存文件
接下来的两节将演示如何使用 git restore 处理暂存区和工作目录中的变更。好消息是,用来确定这两个区域状态的命令,也会提醒你如何撤销对它们的修改。例如,假设你修改了两个文件,想把它们作为两次独立的修改分别提交,但你不小心输入了 git add *,结果把两个文件都暂存了。该如何撤销其中一个文件的暂存呢?git status 命令会提醒你:
$ git add *
$ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: CONTRIBUTING.md
renamed: README.md -> README
在“Changes to be committed”文本下方,它提示可以使用 git restore --staged <file>… 来取消暂存。那么,我们按照这个建议来取消 CONTRIBUTING.md 文件的暂存:
$ git restore --staged CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
renamed: README.md -> README
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: CONTRIBUTING.md
现在 CONTRIBUTING.md 文件处于已修改但未暂存的状态。
使用 git restore 撤销对文件的修改
如果你意识到不想保留对 CONTRIBUTING.md 文件的修改该怎么办?如何轻松地取消修改 —— 即将其还原为上一次提交(或刚克隆时,或者无论你通过什么方式将其放入工作目录时)的样子?幸运的是,git status 也告诉了你如何做。在上一个示例的输出中,未暂存区域看起来是这样的:
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: CONTRIBUTING.md
它非常明确地告诉你如何丢弃所做的修改。让我们按照它的指示操作:
$ git restore CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
renamed: README.md -> README
|
重要提示
|
理解 |