Git 简明教程

Git - Fix Mistakes

人非圣贤,孰能无过。因此,每个 VCS 都提供了在一定范围内修复错误的功能。Git 提供了一个功能,我们可以使用该功能撤销对本地存储库所做的修改。

假设用户错误地对他的本地存储库进行了一些更改,然后想要撤销这些更改。在这种情况下, revert 操作将发挥重要作用。

Revert Uncommitted Changes

让我们假设 Jerry 错误地修改了他本地存储库中的一个文件。但是,他想要撤销他的修改。为了处理这种情况,我们可以使用 git checkout 命令。我们可以使用这个命令来还原文件的内容。

[jerry@CentOS src]$ pwd
/home/jerry/jerry_repo/project/src

[jerry@CentOS src]$ git status -s
M string_operations.c

[jerry@CentOS src]$ git checkout string_operations.c

[jerry@CentOS src]$ git status –s

此外,我们可以使用 git checkout 命令从本地存储库中获取已删除的文件。让我们假设 Tom 从本地存储库中删除了一个文件,并且我们想要恢复这个文件。我们可以使用相同的命令来实现这一点。

[tom@CentOS src]$ pwd
/home/tom/top_repo/project/src

[tom@CentOS src]$ ls -1
Makefile
string_operations.c

[tom@CentOS src]$ rm string_operations.c

[tom@CentOS src]$ ls -1
Makefile

[tom@CentOS src]$ git status -s
D string_operations.c

Git 在文件名之前显示了字母 D 。这表示该文件已从本地存储库中删除。

[tom@CentOS src]$ git checkout string_operations.c

[tom@CentOS src]$ ls -1
Makefile
string_operations.c

[tom@CentOS src]$ git status -s

Note − 我们可以在提交前执行所有这些操作。

Remove Changes from Staging Area

我们已经看到当我们执行一个添加操作时,文件从本地仓库移动到暂存区域。如果一个用户意外地修改了一个文件并将其添加到暂存区域中,他可以使用 git checkout 命令撤销他的修改。

在 Git 中,有一个 HEAD 指针始终指向最新的提交。如果你想要撤销一个来自暂存区域的修改,你可以使用 git checkout 命令,使用 checkout 命令的时候,你必须提供一个额外的参数,即 HEAD 指针。额外的提交指针参数指示 git checkout 命令重置工作树并移除暂存修改。

假设 Tom 从他的本地仓库中修改了一个文件。如果我们查看这个文件的状态,它将会显示文件已经修改但是尚未添加到暂存区域中。

tom@CentOS src]$ pwd
/home/tom/top_repo/project/src
# Unmodified file

[tom@CentOS src]$ git status -s

# Modify file and view it’s status.
[tom@CentOS src]$ git status -s
M string_operations.c

[tom@CentOS src]$ git add string_operations.c

Git status 显示文件出现在暂存区域中,现在使用 git checkout 命令撤销它并查看撤销的文件的状态。

[tom@CentOS src]$ git checkout HEAD -- string_operations.c

[tom@CentOS src]$ git status -s

Move HEAD Pointer with Git Reset

完成了一些修改之后,你可能决定移除这些修改。Git reset 命令用于重置或撤销修改。我们可以执行三种不同类型的重置操作。

下图展示了 Git reset 命令的图片表示。

before git reset
after git reset

Soft

每个分支都有一个 HEAD 指针,指向最新的提交。如果我们使用带有 --soft 选项的 Git reset 命令,后面跟着提交 ID,那么它仅仅会在不销毁任何东西的情况下重置 HEAD 指针。

.git/refs/heads/master 文件储存了 HEAD 指针的提交 ID。我们可以使用 git log -1 命令验证它。

[jerry@CentOS project]$ cat .git/refs/heads/master
577647211ed44fe2ae479427a0668a4f12ed71a1

现在,查看最新的提交 ID,它将会与上面的提交 ID 相匹配。

[jerry@CentOS project]$ git log -2

上述命令将产生以下结果。

commit 577647211ed44fe2ae479427a0668a4f12ed71a1
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 10:21:20 2013 +0530

Removed executable binary


commit 29af9d45947dc044e33d69b9141d8d2dad37cc62
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 10:16:25 2013 +0530

Added compiled binary

让我们重置 HEAD 指针。

[jerry@CentOS project]$ git reset --soft HEAD~

现在,我们简单地将 HEAD 指针回退一个位置。让我们检查 .git/refs/heads/master file 的内容。

[jerry@CentOS project]$ cat .git/refs/heads/master
29af9d45947dc044e33d69b9141d8d2dad37cc62

文件中的提交 ID 已经改变,现在通过查看提交信息来验证它。

jerry@CentOS project]$ git log -2

上述命令将产生以下结果。

commit 29af9d45947dc044e33d69b9141d8d2dad37cc62
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 10:16:25 2013 +0530

Added compiled binary


commit 94f7b26005f856f1a1b733ad438e97a0cd509c1a
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 10:08:01 2013 +0530

Added Makefile and renamed strings.c to string_operations.c

mixed

Git reset 带有 --mixed 选项会撤销那些尚未提交的来自暂存区域的修改。它仅仅会撤销来自暂存区域的修改。对文件工作副本所做的实际修改不会受到影响。默认的 Git reset 等同于 git reset — mixed。

hard

如果你对 Git reset 命令使用 --hard 选项,它将会清空暂存区域;它将会将 HEAD 指针重置为特定提交 ID 的最新提交,也会删除本地文件修改。

让我们检查提交 ID。

[jerry@CentOS src]$ pwd
/home/jerry/jerry_repo/project/src

[jerry@CentOS src]$ git log -1

上述命令将产生以下结果。

commit 577647211ed44fe2ae479427a0668a4f12ed71a1
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 10:21:20 2013 +0530

Removed executable binary

Jerry 通过在文件开头添加单行注释来修改了文件。

[jerry@CentOS src]$ head -2 string_operations.c
/* This line be removed by git reset operation */
#include <stdio.h>

他使用 git status 命令验证了它。

[jerry@CentOS src]$ git status -s
M string_operations.c

Jerry 将修改的文件添加到暂存区域,并使用 git status 命令验证了它。

[jerry@CentOS src]$ git add string_operations.c
[jerry@CentOS src]$ git status

上述命令将产生以下结果。

# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
#
modified: string_operations.c
#

Git 状态显示文件出现在暂存区域中。现在,使用重置命令——硬选项重置 HEAD。

[jerry@CentOS src]$ git reset --hard 577647211ed44fe2ae479427a0668a4f12ed71a1

HEAD is now at 5776472 Removed executable binary

Git 重置命令成功,它将从暂存区撤消文件并删除对该文件进行的所有本地更改。

[jerry@CentOS src]$ git status -s

Git 状态显示文件已从暂存区域撤消。

[jerry@CentOS src]$ head -2 string_operations.c
#include <stdio.h>

head 命令还显示了重置操作也移除了本地更改。