当前位置:首页 > 英文周记 > 正文内容

revertcommit的简单介绍

更新时间:2026-07-18 11:17:53 周记网3年前 (2023-02-15)英文周记644

Git撤销与合并

1. git init

创建一个空的git repo,也就是创建一个.git的子目录,这个目录包含了几乎所有git存储和操作的东西。新初始化的.git目录的典型结构如下:

description文件仅供git web程序使用,平常无需关心。

revertcommit的简单介绍

config文件包含项目特有的配置选项。

info目录包含一个全局性排除文件,用以放置那些不希望被记录在.gitignore文件中的忽略模式。

hooks目录包含客户端或服务端的钩子脚本。

HEAD文件指向目前被检出的分支。

index文件(尚待创建)保存暂存区信息。

objects目录存储所有数据内容。

refs目录存储指向数据的提交对象的指针。

git的默认分支名字是master,git init时默认创建它。

2. git的三种状态,以及工作区(Working directory),暂存区(Index),HEAD

Git 有三种状态,你的文件可能处于其中之一:已修改(modified)、已暂存(staged)和已提交(committed)

基于刚才init的git project,做一些改动。

会看到在git add之后,.git下面多了一个index文件。

这时候,所做的改动就处于已暂存状态,体现在index文件中。

可以利用以下命令查看git缓存了的内容。

同时,.git/objects下面多了一个子文件夹,并生成了一个新文件。这个新文件就对应了刚才所做的改动。这就是git存储内容的方式--一个文件对应一条内容,以该内容加上特定头部信息一起的SHA-1校验和作为文件名。校验和的前两个字符用于命名子目录,余下的38个字符则作为文件名。后面会详叙。

可以通过cat-file命令从git那里查看存储的内容。

git cat-file -p e69de29bb2d1d6434b8b29ae775ad8c2e48c5391

由于file1.txt的内容为空,所以这里显示为空。

这时候可以往file1.txt里添加一些内容,并git add。可以看到.git/objects又多了一个object。

查看这个新的对象的内容以及类型。会发现它是一个blob对象。

接下来commit这个change。

myProject $ git commit -m "first commit"

查看这个commit 对象的类型以及内容,commit的tree对象所指向的内容, 我们会发现,这个tree指向的是一个blob,而这个blob的内容,就是我们刚刚做过改动的文件。

同时,我们查看一下暂存区的内容:

会发现,暂存区指向的也是同样的blob对象。

至此,一个commit就提交了,工作区,暂存区,以及head又指向了同样的内容。

它们更新内容的顺序为,工作区-暂存区-head

3. git reset

将做过的change撤销掉,就像没有发生过一样。

git reset 应用的顺序为 head-暂存区-工作区。

(1) git reset --soft

当前,git的状态如下。

head指向的内容为:

(head是当前分支引用的指针,总是指向该分支上的最后一次提交。)

index指向的内容为:

(索引是你的预期的下一个提交)

我们来进行一次reset。(移动HEAD, --soft)

--soft将仅仅移动HEAD的指向,而并不会移动index以及工作区。

HEAD 指的是HEAD的父节点。HEAD 是父节点的父节点,也可以写成HEAD 2.

所以这个命令本质上是撤销了上一次git commit命令。

(2) git reset --mixed

接下来,再通过reset来更新索引。(--mixed,默认行为)

(3) git reset --hard

reset更新工作目录(--hard)

git reset --hard HEAD~

--hard标记是reset命令的危险用法,它也是git会真正销毁数据的几个操作之一。

如果这个commit已经被推送到远端,可以用这个命令使远端也回退到相应的版本。

git push origin branch --force

4. git revert

将做过的change撤销掉,通过“反做”某一个版本,用一个新的commit来消除做过的change。

当前git的状态:

revert其中一个commit:

再来看,多了一个commit,也就是用来revert的commit:

而若是想要revert某个版本,但是在这个版本后又做过change,则在revert的过程中可能出现冲突,则需要解决冲突之后再提交。

5. git merge 与git rebase

先来讲讲git merge。

当前master 和 dev branch:

接下来打算将dev的工作并入master分支。

另外,还想将master的工作也并入dev。

git merge之后,会发现dev branch指向了与master相同的commit:

所以,git merge是把两个分支的最新快照,以及两者最近的共同祖先进行三方合并,合并的结果是生成一个新的快照。

接下来,用git rebase来合并分支。

当前的git状态

此时,采用git rebase,将dev的工作并入到master。

当在master branch上执行git rebase dev的时候,实际发生的事情是,找到master和dev两个分支的最近共同祖先,对比当前分支(master分支)相对于该祖先的历次提交,提取相应的修改并存为临时文件,然后将master分支指向目标基底(dev的head指向的commit),最后以此将之前另存为临时文件的修改依序应用。

可以看到,rebase使得提交历史更加整洁。尽管实际的开发工作是并行在不同branch上进行的,但是它们看上去就像是串行的一样,提交历史是一条直线没有分叉。

因此,变基是将一系列提交按照原有次序依次应用到另一分支上,而合并是把最终结果合在一起。这两种方式,整合的最终结果所指向的快照始终是一样的,只不过提交历史不同。

Git新手教程-撤销更改(七)

在前面的文章中,我们学习了标签、分支、和合并。现在我们将学习Git中另外的三个命令 git commit --amend , git revert , git reset 。下面简单的介绍中几个命令的功能:

在平时的项目开发中,有时候我们可能提交完相应文件后,才发现漏掉了几个文件没有添加,或者我们 commit 消息并没有书写完整或有错别字。那这个时候我们该整么办呢?或许我们会执行一个新的提交来添加我们遗漏的内容,但是这样一点都不优雅!!在Git中为我们提供了带有 --amend 选项的提交来修改我们 最近 的提交:

这里大家可能还是不是很明白,我们看下面这个简单的例子:

在上述例仓库中我们创建了一个 commit ,该 commit 消息并没有书写完整。这个时候我们想修改它,那么我们就可以使用命令 git commit --amend ,当输入该命令后,我们能得到如下弹窗:

这个时候,我们就可以完善该 commit 信息,然后保存并离开。这里我改成了 删除了多余的语句 ,这时我们再使用 git log 命令,我们会发现我们的 commit 消息已经被更改了。如下所示:

当然在上述例子中,我们只是简单的修改了 commit 信息,并没有修改或添加一些新的文件,如果你修改或添加了新的文件,并想将这些修改的文件添加到最近的 commit 中去的话,那么你可能要经历以下步骤:

在实际的项目中,如果你想修改最近的 commit ,那么你需要使用 git commit --amend 来更新最近的 commit ,而不是创建新的 commit 。

在上述例子中,我们知道了如何修改最近的 commit ,但是如果我们想还原这个 commit 。那这个时候,我们又该怎么办呢?我们可以使用 git revert 命令来告诉 Git 还原之前创建的commit,该命令使用的方式如下:

还是以上述例子来进行讲解,比如我们想还原下图中红色框中的 commit :

我们可以使用 git revert b71b40 ,需要注意的是使用该命令,默认会创建一个新的提交。如下图所示:

一般情况下,我们可以使用Git系统默认的 revert 信息。当我们保存并退出后,再使用 git log 命令查看我们的日志提交记录,我们能得到下图:

在上述例子中,我们学会了如何还原一个提交,但是如果我们本是这个提交就是错误的,我们并不想要这个提交,也不想仓库记录中包含 revert 的提交记录。这个时候我们又该怎么办呢?我们可以使用 git reset 命令来告诉 Git 重置 commit 。

重置(reset) 似乎和 还原(revert) 相似,但它们实际上差别很大。还原会创建一个新的 commit,并还原或撤消之前的 commit。但是重置会清除 commit!

git reset 命令相比其他 Git 命令功能要多一点,可以用来:

git reset 并不直接使用 commit 的 SHA ,而是使用特殊的 "祖先引用" 来告诉 Git 将 HEAD 指针移动到哪个commit。我们来看看这些特殊的符号。

我们可以通过以下方式引用之前的 commit:

^ 和 ~ 的区别主要体现在通过合并而创建的 commit 中。合并 commit 具有两个父级。对于合并 commit, ^ 引用用来表示第一个父 commit,而 ^2 表示第二个父 commit。第一个父 commit 是当你运行 git merge 时所处的分支,而第二个父 commit 是被合并的分支。

我们看下面的例子,来一起来理解:

因为 HEAD 指向 b71b405 commmit。

了解了祖先引用,现在我们来了解 git reset 命令的使用:

一般情况下,使用该命令,我们会添加如下选项:

直接理解这些选项比较困难,下面我们将结合图片与实际例子来进行讲解。

在下图中,假如我们的仓库中已经有了如下提交 D、E、F、G、H ,其中 master 指向最近的提交 H , HEAD 指向 master 。

这个时候我们如果使用 git reset --mixed HEAD~1 那么会将 master 与 HEAD 将会指向前一个提交 G 。同时 G 提交会移动到工作目录中。如下图所示:

当 H 提交修改的文件被移动到到工作目录后,文件的状态都为 modifed ,也就是我们需要重新添加到暂存区,然后进行 commit 。我们继续看下面的例子:

在上述仓库中有3个提交,其中 HEAD 指向 bb780f9 上的 master , 这个时候如果我们运行 git reset HEAD~ 命令,会将 commit bb780f9 中的文件移动到工作目录中,如下所示:

调用 git status 来查看我们的仓库状态,我们会发现使用 --mixed 选项,是不会暂存我们的更改的,也就是不会将相应提交的文件放入暂存区中。

当使用 --soft 选项时,不仅会移动 master 与 HEAD 指针,还会将相应修改添加到暂存区中,如下所示:

我们继续查看下面的例子:

最后我们再来看看 --hard 选项:

使用 --hard 将清除对应 commit 所作的更改,继续查看下面的?的例子:

当使用了 --hard 选项后,发现仓库中对应的提交消失了。

当我们直接使用 git reset 或 git reset HEAD 时,表示清除暂存区中的 commit 。下面我们来看这个例子:

那么如果我们只想将 B.java 文件从暂存区中移除,那我们又该怎么办呢?我们可以使用如下命令:

当然在Git中支持多个文件的取消暂存,具体命令如下:

在上述命令中 file... 代表一个或多个文件。

最后还是回到我们熟悉的图形化界面的使用流程中。我们来看看IDEA为我们提供了哪些便利吧。

在创建相应 commmit 时,我们可以勾选下图中的

Amend commit 选项。如下所示:

上述操作与使用 git commit --amend 命令的效果一样。

通过依次点击编译器底部的 Version Control - Log ,然后选择想要 revert 的 commit ,点击鼠标 右键 ,选择 Revert Commit 就可以啦~

通过依次点击编译器底部的 Version Control - Log ,然后选择想要 reset 的 commit ,点击鼠标 右键 ,选择 Reset Current Branch to Here.. 就完成第一步啦~

当然在第二步中,我们需要选择 git reset 中的选项,在 IDEA 中提供了四种选项 Soft、Mixed、Hard、Keep ,如下所示:

在上图中,我们不熟悉的只有 --keep 选项,因为该选项在平时中的项目并不常用,所以这里就不做更多介绍了,有兴趣的小伙伴,可以查看官方文档中 git reset 中对其的介绍。

站在巨人的肩膀上,才能看的更远~

git revert和git reset的区别

git revert会创建一个新的commit,这个操作不会消除已有的git历史纪录。

git reset则会改动已有的git纪录,造成历史重写。

两者都可以用于对过去的commit进行更改/撤销。但是revert可以保持历史完整,reset则会直接重写历史。如果你在你自己的branch上工作,一般可以随心所欲地reset。如果你是某个项目的管理员/拥有这个项目的master写入权限,你应该用revert多过reset。否则可能会为很多已经Pull过的其他开发者造成冲突。

标签: revertcommit

“revertcommit的简单介绍” 的相关文章

包含revertcommit的词条

包含revertcommit的词条

Git撤销与合并 1. git init 创建一个空的git repo,也就是创建一个.git的子目录,这个目录包含了几乎所有git存储和操作的东西。新初始化的.git目录的典型结构如下:...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。