Git 和 GitHub:完整指南 - 第 2 章:Git 中的撤销操作
由 Mux 赞助的 DEV 全球展示挑战赛:展示你的项目!
在创建时间线/分支、 i.e设置项目历史记录时,您将获得一项重要的能力,可以回溯到过去。
通过回溯功能,您可以查看项目之前的状态,可以撤销这些状态的更改,甚至可以重置历史记录!
共同的主题是“撤销”,我们稍后会详细讨论这一点。现在我想讨论一下我们在第一章中简要提及的一个话题,那就是“头脑”。
HEAD是什么?
为了更清楚地理解HEAD,让我们再来看一个HEAD的例子。当我们使用命令的摘要语法记录项目历史记录时:
git log --oneline
现在我们可以看到提交历史的概要。如果您注意到第一个提交,会发现它关联着一个(HEAD -> master)指针。HEAD是一个指针,master是默认分支。分支本身记录了提交的时间线。默认情况下,HEAD指向最后一次提交,但如果您回溯到项目的其他先前状态,HEAD将指向相应的提交。More on this soon...
为了证明HEAD默认指向最后一次提交,我们可以运行以下命令:
git show HEAD
该命令的输出显示了最后一次提交及其相关信息。其中后半部分将在其他章节中讨论……
请注意,HEAD充当了提交的唯一标识符(ID)。这意味着,如果我们传入上次提交的奇怪字符串,git show我们将得到相同的输出。
我们可以使用HEAD代替 ID。有趣的是,我们可以用HEAD显示其他提交的信息。为了演示,我们先清空屏幕。运行命令,记录我们当前提交历史的摘要。要使用HEAD记录其他提交的详细信息,请使用以下命令:
git show HEAD~
波浪号 (~) 后面跟着一个数字,表示提交的索引。例如:
git show HEAD~1
我们提交了 1 次,但HEAD指向的是第二次提交。
历史记录中的提交索引是从零开始的,也就是说,你要从 0 开始计数。记住这一点!
关于HEAD就说这么多吧,我们将在整个旅程中使用它。
是时候撤销之前的事情了。
实际上,我提到了我们将要讨论的三个基本命令,它们可以让我们撤销操作。这些命令是:
- 查看
- 恢复
- 重置
查看
我们将从检出(checkout)命令开始。借助该命令,我们可以撤销对文件的修改,还可以回溯到项目的不同状态,并查看其原始版本。此外,它还允许我们在不同的分支之间切换。
unmodify不是一个词,但不知为何我觉得在这里用它很合适 🤔。
未修改
我们先来看看如何撤销对文件的修改。为此,我们需要先修改项目中的一些文件。这完全取决于您,但请记住保存您对文件所做的更改。
当我们检查文件状态时,发现文件已被修改。
假设由于某种原因我们不小心引入了一个错误,需要撤销对文件的修改。例如,我们创建了一个不应该创建的变量。我们可以使用以下命令来撤销对文件的修改:
git checkout
此命令后需跟要取消修改的文件。例如:
git checkout script.js
要同时取消修改多个文件,我们可以使用以下命令:
git checkout .
或者
git checkout *
它还git checkout可以执行回溯操作,查看项目之前的状态。与我们将要讨论的其他两个命令不同,`checkout`是最安全的。因为使用`checkout`无法更改或删除之前的提交。
要回溯到某个提交/快照,我们需要指定要回溯的提交/快照。我们已经知道,可以使用唯一标识符(ID) 或HEAD指针来指定提交。我们通过运行以下命令来执行回溯:
git checkout
此命令后需跟上要回滚到的提交 ID。例如:
git checkout 90077b6
你也可以像这样使用HEAD指针:
git checkout HEAD~2
您现在已将项目恢复到之前的状态。您会注意到,在此提交之后创建的所有文件都已被删除,并且对任何文件所做的更改都将恢复到您进行此提交时的状态。
太棒了!👍
我们回到了过去。但你可能会想,这真的会删除之前的所有工作吗?
特别是如果你运行命令查看提交历史记录的话:
git log --oneline
查看命令输出git checkout ___,你会发现它显示我们处于分离 HEAD状态。这意味着我们的HEAD不再指向上一个提交,而是指向当前提交的ID。这样我们就能回滚到项目之前的状态。
想要回到未来😏,我们只需要运行以下命令:
git checkout master
现在我们回来了!如果我们检查一下以确保所有提交都完好无损,我们会很高兴地看到它们都还在,更重要的是,HEAD指向了最后一个提交。
检出操作非常安全,因为它是只读的,您无法更改或编辑之前的提交。
让我们再次回到过去来证明这一点。
现在我们知道如何回溯到之前的某个提交,git checkout只需输入提交 ID 即可。回到之前的状态后,我们就可以按照正常流程修改文件,将它们放到暂存区,最后提交并添加提交信息。
当我们运行命令时,git log --oneline可以看到刚刚创建的提交,但如果我们回到当前分支(master 分支)并再次运行相同的命令,就完全看不到提交了!
如果我们回到之前的同一个提交并运行该命令,也看不到该提交。这就是我们所说的检出是安全的。
要在检出后创建新的提交,可以通过创建其他分支来实现。不过我们稍后再讨论这个问题……
我们将介绍其他一些命令,这些命令可以让你对项目的时间线进行永久性更改,例如revert和reset。
恢复
该git revert命令用于撤销项目提交历史记录中的更改。其工作原理如下:它获取一个特定的提交,将其撤销,然后创建一个新的还原提交。我们通过运行以下命令来完成此操作:
git revert
此命令后需跟要回滚的提交 ID,例如:
git revert 736ec6b
系统会打开一个名为COMMIT_EDITMSG 的临时文件,其中包含原始提交消息以及一条信息消息,告知您此次操作将撤销指定 ID 的提交。关闭该文件后,您在指定提交中所做的所有更改都将被撤销,并且时间线中将添加一个新的提交。
如果删除原始消息并将其留空,然后关闭临时文件,则会中止还原过程。
另一点需要注意的是,当您使用该git revert命令时,您不会触及其他提交的任何更改,您只会对指定的提交进行更改。
这很有用,因为你之前指定的提交中可能存在一些错误,而git revert这允许你在不更改任何其他提交的情况下修复这些错误。
重置
这条命令被称为危险或不安全命令,因为它可能会永久删除你的工作成果。所以,毋庸置疑,你必须非常小心。git reset
该git reset命令有点独特,因为它有三个不同的标志可以与它一起使用,每个标志的行为方式都不同。
这些旗帜是:
- 混合
- 柔软的
- 难的
例如:
git reset --soft 5d5751c
此命令后跟前一个提交的唯一标识符,即要删除的提交之前的提交的 ID 。
执行删除操作时,
git reset您可以选择要从哪个提交开始删除,并且只删除该提交之后的所有提交。
混合
混合标志是一个默认标志,这意味着如果我们只运行该标志,git reset混合标志无论如何都会生效。
现在你可以提交几次代码了,你应该已经熟悉整个流程了……
当我们运行该命令时:
git reset --mixed
这些提交记录似乎已从提交历史记录中移除,但它们实际上并未被删除。这是因为我们只是将它们从暂存区移除了。我们可以通过运行git status命令来验证这一点。
要在运行命令后彻底删除文件git reset --mixed,我们需要运行以下命令:
git checkout .
如您所见,git reset带有该--mixed标志的命令只会从历史记录中删除提交,并且还会从暂存区取消暂存文件,最终它们会出现在工作目录中。
柔软的
--soft标志和标志之间存在细微差别--mixed。与后者类似,--soft标志后面也跟着要更改的实际提交之前的唯一提交 ID。同样,--mixed运行命令也会从历史记录中删除提交。但关键区别在于,这些文件保留在暂存区。我们可以通过运行以下命令来验证这一点。git status
如您所见,这两个文件都是绿色的,这意味着它们仍在暂存区。要将它们从暂存区移除,我们需要运行以下命令:
git reset .
这将把它们从暂存区移除,并最终永久删除这些文件。我们运行以下命令:
git checkout .
无论哪种情况--mixed,--soft我们都需要经过几个步骤才能对文件进行更改。
难的
如果您想同时删除历史记录中的提交记录和文件,只需使用git reset该--hard标志即可。我们可以按如下方式运行该命令:
git reset --hard
接下来是你要删除的提交之前的提交(ID)。请记住,这将永久删除你的文件!
Git 忽略
到目前为止,我们已经讲解了很多内容,例如如何跟踪文件、如何将文件添加到暂存区、如何提交更改以及如何撤销操作。现在似乎是时候讨论一下如何忽略某些文件或文件夹,也就是 Git 不应该识别的文件和文件夹了。
在项目开发过程中,你可能会遇到一些实际上无需管理的文件,因为它们可能会降低工作效率。本文将介绍一种忽略这些特定文件的解决方案。
在 Git 中,我们称之为.gitignore 文件,实际上它没有名字,你只需要指定它的扩展名.gitignore即可。
首先,我们需要创建一个新文件并将其命名为 `.gitignore`,.gitignore然后我们可以检查其状态,发现它未被跟踪。为了演示其工作原理,让我们在与 `.gitignore` 文件相同的目录下创建两个文本文件。创建完成后,我们可以检查其状态,发现现在有三个文件未被跟踪。您还可以通过它们的绿色以及文件旁边的“U”符号来注意到这一点。
为了让 Git 知道我们不希望跟踪某些文件/文件夹,我们需要将它们添加到 .gitignore.gitignore文件中。添加方法是指定文件路径相对于 .gitignore 文件路径的相对位置。
当我们正确添加文件.gitignore并保存后,文件将不再显示绿色,旁边也不会再有“U”标记。Git 会立即忽略这些文件。
我想讨论一下在使用.gitignore文件时需要注意的一点。假设我们想让 Git 忽略 index.html 和 style.css 文件,我们会将它们添加到 .gitignore.gitignore文件中并保存。你可能会认为 Git 会忽略它们,但如果我们再次修改这些文件并检查状态,会发现 Git 仍然在跟踪这些文件。
出现这种现象的原因是,在我们创建.gitignore文件之前,这两个文件就已经被修改过了。为了解决这个问题,我们需要清除历史记录中的缓存。我们可以通过运行以下命令来完成此操作:
git rm -r cached .
运行此命令后,我们清除了缓存。
以下是一些使用 Git.gitignore文件的额外技巧。您可能已经注意到,每次我们想让 Git 忽略某个文件时,都必须在.gitignore文件中插入该文件的路径。想象一下,如果我们有数百个需要 Git 忽略的文件,逐个插入将会非常缓慢。因此,我们可以使用一个特殊字符来指定所有文件。这个字符就是星号*
例如,我们有一个名为 newFolder 的文件夹,其中包含数百个我们想要忽略的文件,要选择所有这些文件,我们使用星号:
newFolder/*
例如,假设同一个文件夹中包含我们项目所需的图片或 style.css 文件,而我们只想忽略该文件夹中的文本文件。如果我们使用之前的命令,Git 会忽略文件夹中的所有文件。为了解决这个问题,我们可以通过在文件扩展名前加上星号来指定 Git 应该忽略的扩展名:
newFolder/*.txt
本章到此结束,我们已经讲完了Git,接下来该探索GitHub了。希望您喜欢,如果喜欢的话,请点个赞或者点个赞.gitignore。























