Git重置说明-如何使用重置命令保存一天

2020-10-01 05:21:52

这听起来耳熟吗?“救命!我上错了分店!“。“它又发生了,…。我的承诺呢?“。

嗯,我去过那里好多次了。当GIT出问题时,有人叫我的名字来帮忙。这不仅发生在我教学生的时候,也发生在与经验丰富的开发人员一起工作的时候。

我们一直使用git,通常  它帮助我们完成工作。但有时,事情会出差错,而且这种情况比我们想要的要频繁得多。

也许我们承诺了错误的分支机构。也许我们丢失了我们编写的一些代码。也许我们做了一些我们不想做的事。

有很多关于GIT的在线资源,其中一些(比如这个)实际上关注的是在这些不受欢迎的场景中会发生什么。

但我总觉得这些资源缺乏“为什么”的 。当提供一组命令 时,每个命令执行什么操作?那你是怎么得到这些命令的呢?🤔。

在上一篇文章中,我提供了Git内部的可视化介绍。虽然了解git的内部原理很有用,但获得理论知识几乎永远不够。我们如何应用我们对git内部结构的知识,并用它来解决我们已经陷入的问题呢?

在这篇文章中,我想要弥合这一差距,  并详细说明git重置命令。我们将了解Git Reset在幕后做些什么,然后将这些知识应用到解决各种场景中。😎

为了了解GIT重置的内部机制,了解在GIT 中记录更改的过程非常重要。具体地说,我指的是工作目录、索引和存储库。

如果您对这些术语有信心,请随意跳到下一节。如果你想要更深入的解释,请看上一篇文章。

当我们处理源代码时,我们从工作目录 - 文件系统上有关联存储库的任何目录开始工作。它包含我们项目的文件夹和文件,还有一个名为.git的目录。

在我们做了一些更改之后,我们希望将它们记录在我们的存储库中。存储库(简称repo)是提交的集合,每个提交都是项目工作树在过去日期的存档,无论是在我们的机器上还是在其他人的机器上。

相反,更改首先在称为索引或临时区域的东西中注册。这两个术语指的是同一件事,它们经常在git文档中使用。我们将在这篇文章中互换使用这些术语。

当我们使用git add时,我们将文件(或文件中的更改)添加到临时区域。让我们在前面创建的文件上使用此命令:

正如git状态所显示的那样,我们的文件已经准备就绪(并且准备好“提交”)。然而,它不是任何提交的一部分。换句话说,它现在位于工作目录和索引中,但不在存储库中。

接下来,当我们使用git COMMIT时,我们根据索引的状态创建一个COMMIT。因此,新的COMMIT(下面示例中的COMMIT 3)将包括预先添加到索引中的文件。

换句话说,工作目录与索引和存储库具有完全相同的状态。

命令git Commit还使当前分支主机指向新创建的提交对象。

我喜欢将git Reset看作是一个命令,它可以逆转上述过程(对工作目录进行更改,将其添加到索引中,然后将其提交到存储库)。

Git重置有三种操作模式 - --软、--混合或--硬。我认为它们有三个阶段:

首先,git重置会更新head指向的任何内容。对于GIT RESET--HARD HEAD~1,它会将HEAD指向的内容(在上例中为MASTER)移动到HEAD~1。如果使用 - -SOFT标志,GIT RESET将停止。

继续上面的示例,head将指向Commit 2,因此new_file.txt将不是当前提交树的一部分。然而,它将是索引和工作目录的一部分。

查看git状态,我们可以看到文件确实已暂存但未提交:

换句话说,我们将流程恢复到使用git add,但尚未使用git Commit的阶段。

如果我们使用git Reset--MIXED HEAD~1,那么在将指向(Master)的任何head更新为head~1之后,git不会停止。它还会将索引更新为(已经更新的)head。

在我们的示例中,这意味着索引将具有与提交2相同的状态:

因此,在使用git add - 之前,我们将流程恢复到阶段新创建的文件现在是工作目录的一部分,但索引和存储库不是。

通过使用GIT重置 - Hard Head~1,在将指向(主)的任何Head更新为Head~1之后,以及将索引更新为(已经更新的)Head之后,GIT将继续并更新工作目录以使其看起来像索引。

在我们的示例中,这意味着工作目录将具有与索引相同的状态,而索引已经具有与提交2相同的状态:

现在我们了解了GIT重置是如何工作的,让我们应用这些知识来拯救我们的生活吧!💪。

让我们考虑一下以下情况。我们用字符串this创建了一个非常重要的文件,暂存并提交了它。

嗯,现在我们知道我们可以很容易地解决这个问题了。我们可以恢复上次提交,并使用git Reset--MIXED HEAD~1将文件返回到工作目录。现在,我们可以编辑文件的内容,暂存并再次提交它。

提示:在这种特定情况下,我们还可以使用git Commit--amendate,如下所述。

2.哎呀!我将某些内容提交给了错误的分支机构 - ,我需要在新的分支机构上使用它。

我们都有过这样的经历。我们做了一些工作,然后提交给…。

哦,不,我们承诺了主分支,尽管我们应该创建一个新分支,然后发出拉取请求。🙈。

在这个阶段,我发现将我们所处的状态以及我们想要达到的目标形象化是很有帮助的:

首先,新分支指向我们最近添加的提交。其次,主服务器指向前一次提交。第三,Head指向new。

首先,使新的分支指向最近添加的提交 - ,这可以通过使用GIT BRANCH NEW简单地实现。因此,我们达到以下状态:

其次,让master指向前一次提交(换句话说,指向head~1)。我们可以通过使用GIT RESET--HARD HEAD~1来实现这一点。因此,我们达到了以下状态:

最后,我们想要在新的分支上,也就是说,把头指向新的。这很容易通过执行git checkout new来实现。

3.哎呀!我将某些内容提交给了错误的分支 - ,并且我需要在另一个已存在的分支上使用它。

在本例中,我们经历了与前一个场景中相同的步骤 - 我们做了一些工作,然后提交了…。

哦,不,我们承诺了主分支机构,尽管我们应该承诺另一个已经存在的分支机构。🙈。

首先,我们需要现有分支上的最新提交。由于master当前指向它,我们可以简单地要求git从master分支获取最近的提交,并将其应用于现有分支,如下所示:

GIT挑选主 - 将主分支上的最后一次提交应用于当前(现有)分支。

现在我们只需要让master指向以前的提交,而不是最近的提交。为此,我们可以:

GIT重置--Hard Head~1 - 现在我们回到原来的分支。

在这篇文章中,我们了解了GIT Reset是如何运行的,并阐明了它的三种操作模式 - --Soft、--Mixed和--Hard。

然后,我们应用我们关于git重置的知识来解决一些使用git的实际问题。

通过了解git的操作方式,我们可以自信地处理各种情况,并且 也会欣赏这个工具😎的美妙之处。

在以后的帖子中,我们将介绍更多的git命令,以及它们如何帮助我们解决各种不受欢迎的情况。

Omer Rosenbaum,Swimm的首席技术官。网络培训专家和Checkpoint Security Academy的创始人。“计算机网络”(希伯来语)的作者。访问我的YouTube频道。

免费学习编码。FreeCodeCamp的开源课程已经帮助超过4万人找到了开发人员的工作。开始