文学起点网
当前位置: 首页 文学百科

git回退详细教程(如何在Git中重置)

时间:2023-07-11 作者: 小编 阅读量: 2 栏目名: 文学百科

在这里我们有一个在Git中表示一系列提交的示意图。在Git中一个分支简单来说就是一个命名的、指向一个特定的提交的可移动指针。恢复gitrevert命令的实际结果类似于reset,但它的方法不同。reset命令(默认)是在链中向后移动分支的指针去“撤销”更改,revert命令是在链中添加一个新的提交去“取消”更改。我们移动了指针,然后reset代码回到前一个提交,但它并没有删除任何提交。从本质上来说,Git将一个分支中的每

编译自: https://opensource.com/article/18/6/git-reset-revert-rebase-commands

作者: Brent Laster

译者: qhwdw

用简洁而优雅的 Git 命令撤销仓库中的改变。

使用 Git 工作时其中一个鲜为人知(和没有意识到)的方面就是,如何轻松地返回到你以前的位置 —— 也就是说,在仓库中如何很容易地去撤销那怕是重大的变更。在本文中,我们将带你了解如何去重置、恢复和完全回到以前的状态,做到这些只需要几个简单而优雅的 Git 命令。

重置

我们从 Git 的 reset 命令开始。确实,你应该能够认为它就是一个 “回滚” —— 它将你本地环境返回到之前的提交。这里的 “本地环境” 一词,我们指的是你的本地仓库、暂存区以及工作目录。

先看一下图 1。在这里我们有一个在 Git 中表示一系列提交的示意图。在 Git 中一个分支简单来说就是一个命名的、指向一个特定的提交的可移动指针。在这里,我们的 master 分支是指向链中最新提交的一个指针。

图 1:有仓库、暂存区、和工作目录的本地环境

如果看一下我们的 master 分支是什么,可以看一下到目前为止我们产生的提交链。

$ git log --oneline

b764644 File with three lines

7c709f0 File with two lines

9ef9173 File with one line

如果我们想回滚到前一个提交会发生什么呢?很简单 —— 我们只需要移动分支指针即可。Git 提供了为我们做这个动作的 reset 命令。例如,如果我们重置 master 为当前提交回退两个提交的位置,我们可以使用如下之一的方法:

$ git reset 9ef9173

(使用一个绝对的提交 SHA1 值 9ef9173)

或:

$ git reset current~2

(在 “current” 标签之前,使用一个相对值 -2)

图 2 展示了操作的结果。在这之后,如果我们在当前分支(master)上运行一个 git log 命令,我们将看到只有一个提交。

$ git log --oneline

9ef9173 File with one line

图 2:在 reset 之后

git reset 命令也包含使用一些选项,可以让你最终满意的提交内容去更新本地环境的其它部分。这些选项包括:hard 在仓库中去重置指向的提交,用提交的内容去填充工作目录,并重置暂存区;soft 仅重置仓库中的指针;而 mixed(默认值)将重置指针和暂存区。

这些选项在特定情况下非常有用,比如,git reset --hard <commit sha1 | reference> 这个命令将覆盖本地任何未提交的更改。实际上,它重置了(清除掉)暂存区,并用你重置的提交内容去覆盖了工作区中的内容。在你使用 hard 选项之前,一定要确保这是你真正地想要做的操作,因为这个命令会覆盖掉任何未提交的更改。

恢复

git revert 命令的实际结果类似于 reset,但它的方法不同。reset 命令(默认)是在链中向后移动分支的指针去“撤销”更改,revert 命令是在链中添加一个新的提交去“取消”更改。再次查看图 1 可以非常轻松地看到这种影响。如果我们在链中的每个提交中向文件添加一行,一种方法是使用 reset 使那个提交返回到仅有两行的那个版本,如:git reset HEAD~1。

另一个方法是添加一个新的提交去删除第三行,以使最终结束变成两行的版本 —— 实际效果也是取消了那个更改。使用一个 git revert 命令可以实现上述目的,比如:

$ git revert HEAD

因为它添加了一个新的提交,Git 将提示如下的提交信息:

Revert "File with three lines"

This reverts commit b764644bad524b804577684bf74e7bca3117f554.

# Please enter the commit message for your changes. Lines starting

# with '#' will be ignored, and an empty message aborts the commit.

# On branch master

# Changes to be committed:

# modified: file1.txt

#

图 3(在下面)展示了 revert 操作完成后的结果。

如果我们现在运行一个 git log 命令,我们将看到前面的提交之前的一个新提交。

$ git log --oneline

11b7712 Revert "File with three lines"

b764644 File with three lines

7c709f0 File with two lines

9ef9173 File with one line

这里是工作目录中这个文件当前的内容:

$ cat <filename>

Line 1

Line 2

图 3 revert 操作之后

恢复或重置如何选择?

为什么要优先选择 revert 而不是 reset 操作?如果你已经将你的提交链推送到远程仓库(其它人可以已经拉取了你的代码并开始工作),一个 revert 操作是让他们去获得更改的非常友好的方式。这是因为 Git 工作流可以非常好地在分支的末端添加提交,但是当有人 reset 分支指针之后,一组提交将再也看不见了,这可能会是一个挑战。

当我们以这种方式使用 Git 工作时,我们的基本规则之一是:在你的本地仓库中使用这种方式去更改还没有推送的代码是可以的。如果提交已经推送到了远程仓库,并且可能其它人已经使用它来工作了,那么应该避免这些重写提交历史的更改。

总之,如果你想回滚、撤销或者重写其它人已经在使用的一个提交链的历史,当你的同事试图将他们的更改合并到他们拉取的原始链上时,他们可能需要做更多的工作。如果你必须对已经推送并被其他人正在使用的代码做更改,在你做更改之前必须要与他们沟通,让他们先合并他们的更改。然后在这个侵入操作没有需要合并的内容之后,他们再拉取最新的副本。

你可能注意到了,在我们做了 reset 操作之后,原始的提交链仍然在那个位置。我们移动了指针,然后 reset 代码回到前一个提交,但它并没有删除任何提交。换句话说就是,只要我们知道我们所指向的原始提交,我们能够通过简单的返回到分支的原始链的头部来“恢复”指针到前面的位置:

git reset <sha1 of commit>

当提交被替换之后,我们在 Git 中做的大量其它操作也会发生类似的事情。新提交被创建,有关的指针被移动到一个新的链,但是老的提交链仍然存在。

变基

现在我们来看一个分支变基。假设我们有两个分支:master 和 feature,提交链如下图 4 所示。master 的提交链是 C4->C2->C1->C0 和 feature 的提交链是 C5->C3->C2->C1->C0。

图 4:master 和 feature 分支的提交链

如果我们在分支中看它的提交记录,它们看起来应该像下面的这样。(为了易于理解,C 表示提交信息)

$ git log --oneline master

6a92e7a C4

259bf36 C2

f33ae68 C1

5043e79 C0

$ git log --oneline feature

79768b8 C5

000f9ae C3

259bf36 C2

f33ae68 C1

5043e79 C0

我告诉人们在 Git 中,可以将 rebase 认为是 “将历史合并”。从本质上来说,Git 将一个分支中的每个不同提交尝试“重放”到另一个分支中。

因此,我们使用基本的 Git 命令,可以变基一个 feature 分支进入到 master 中,并将它拼入到 C4 中(比如,将它插入到 feature 的链中)。操作命令如下:

$ git checkout feature

$ git rebase master

First, rewinding head to replay your work on top of it...

Applying: C3

Applying: C5

完成以后,我们的提交链将变成如下图 5 的样子。

图 5:rebase 命令完成后的提交链

接着,我们看一下提交历史,它应该变成如下的样子。

$ git log --oneline master

6a92e7a C4

259bf36 C2

f33ae68 C1

5043e79 C0

$ git log --oneline feature

c4533a5 C5

64f2047 C3

6a92e7a C4

259bf36 C2

f33ae68 C1

5043e79 C0

注意那个 C3' 和 C5'— 在 master 分支上已处于提交链的“顶部”,由于产生了更改而创建了新提交。但是也要注意的是,rebase 后“原始的” C3 和 C5 仍然在那里 — 只是再没有一个分支指向它们而已。

如果我们做了这个变基,然后确定这不是我们想要的结果,希望去撤销它,我们可以做下面示例所做的操作:

$ git reset 79768b8

由于这个简单的变更,现在我们的分支将重新指向到做 rebase 操作之前一模一样的位置 —— 完全等效于撤销操作(图 6)。

图 6:撤销 rebase 操作之后

如果你想不起来之前一个操作指向的一个分支上提交了什么内容怎么办?幸运的是,Git 命令依然可以帮助你。用这种方式可以修改大多数操作的指针,Git 会记住你的原始提交。事实上,它是在 .git 仓库目录下,将它保存为一个特定的名为 ORIG_HEAD 的文件中。在它被修改之前,那个路径是一个包含了大多数最新引用的文件。如果我们 cat 这个文件,我们可以看到它的内容。

$ cat .git/ORIG_HEAD

79768b891f47ce06f13456a7e222536ee47ad2fe

我们可以使用 reset 命令,正如前面所述,它返回指向到原始的链。然后它的历史将是如下的这样:

$ git log --oneline feature

79768b8 C5

000f9ae C3

259bf36 C2

f33ae68 C1

5043e79 C0

在 reflog 中是获取这些信息的另外一个地方。reflog 是你本地仓库中相关切换或更改的详细描述清单。你可以使用 git reflog 命令去查看它的内容:

$ git reflog

79768b8 HEAD@{0}: reset: moving to 79768b

c4533a5 HEAD@{1}: rebase finished: returning to refs/heads/feature

c4533a5 HEAD@{2}: rebase: C5

64f2047 HEAD@{3}: rebase: C3

6a92e7a HEAD@{4}: rebase: checkout master

79768b8 HEAD@{5}: checkout: moving from feature to feature

79768b8 HEAD@{6}: commit: C5

000f9ae HEAD@{7}: checkout: moving from master to feature

6a92e7a HEAD@{8}: commit: C4

259bf36 HEAD@{9}: checkout: moving from feature to master

000f9ae HEAD@{10}: commit: C3

259bf36 HEAD@{11}: checkout: moving from master to feature

259bf36 HEAD@{12}: commit: C2

f33ae68 HEAD@{13}: commit: C1

5043e79 HEAD@{14}: commit (initial): C0

你可以使用日志中列出的、你看到的相关命名格式,去重置任何一个东西:

$ git reset HEAD@{1}

一旦你理解了当“修改”链的操作发生后,Git 是如何跟踪原始提交链的基本原理,那么在 Git 中做一些更改将不再是那么可怕的事。这就是强大的 Git 的核心能力之一:能够很快速、很容易地尝试任何事情,并且如果不成功就撤销它们。


via: https://opensource.com/article/18/6/git-reset-revert-rebase-commands

作者: Brent Laster 选题: lujun9972 译者: qhwdw 校对: wxy

本文由 LCTT 原创编译, Linux中国 荣誉推出

点击“了解更多”可访问文内链接,
    推荐阅读
  • 苏州旅游攻略景点必去(苏州旅游必去景点有哪些)

    位于苏州市东北街一百七十八号,始建于明朝正德年间。虎丘是AAAAA级景区及全国文明单位,首批十佳文明风景旅游区示范点。中午,周庄最为欢闹,游人穿梭熙熙攘攘,船儿来回摇摇荡荡,各地的游客与热情的商铺融为一体,热闹非凡,安静的古镇着实多了些欢闹的气息。狮子林为苏州四大名园之一,位于苏州市市城东北园林路。

  • 买的玉米种子是瘪的(去年买的玉米种子剩了很多)

    去年买的陈玉米种子建议不要用针对去年的陈玉米种子,大多情况下不建议再次使用,会影响到玉米后期的生长和产量情况。陈年的因为保管的问题,可能会出现很多因素影响玉米的出苗率或者后期的生长。陈玉米种子隔了一年后再种植,种子自身水分含量降低,水分降低严重的情况下,影响播种的效率和玉米的后期生长,由于活性降低,即使能出芽,也不一定能出苗。

  • 173.2亿!国庆消费火爆 国庆消费市场

    今年国庆、重阳两节叠加,全省消费市场呈现平衡较快增长态势,服装、家电、汽车等商品消费亮点突出,大众餐饮、旅行休闲、文体娱乐等主要服务消费备受青睐。根据商务部业务统一平台生存必需品监测系统显示,国庆黄金周期间,全省生存必需品市场供应充沛,价格总体平衡。除了买买买,国庆还是婚庆、团圆、会友高峰,各地亲友聚餐、婚寿宴等大众化餐饮生意兴隆。

  • 吴承恩是怎么写出的西游记(吴承恩怎么写出的西游记)

    吴承恩怎么写出的西游记诸葛长青:吴承恩写西游记诸葛长青:吴承恩怎么写出的《西游记》西游记,广泛流传西游记,作者吴承恩西游记,包含了儒释道大智慧那么,吴承恩是怎么写出的《西游记》呢?诸葛长青把自己对吴承恩写《西游记》,研究成。

  • 李逵扮演者(大家一起来看看吧)

    我们一起去了解并探讨一下这个问题吧!李逵扮演者赵小锐的李逵应该算是很多人印象当中的经典所在了,他的李逵也是很粗犷,但是这种粗犷当中却带着细腻,也是因为这个角色,他开始受到了不少的观众的关注和喜爱。其实之前的他也有出演过一些电视剧的,但是可惜的是一直都没能够真正的红起来,是李逵这个角色,让他一夜成名爆火了。

  • 汽车空间大小怎么看轴距(什么因素会影响车内空间)

    大众速腾,长度4655mm,轴距2651mm。看外观就明白了,因为宝马320i是后驱车,发动机采用纵置布局;而大众速腾是前驱车,发动机采用横置布局。而且由于发动机纵置,后驱设计,对于车内空间侵占较为严重,所以宝马320的长轴距实际上对于空间的帮助是“虚高”的。前面我们就提到了,宝马3系采用了后驱,大众速腾采用了前驱。回到我们的主题,通常来说,麦弗逊与扭力梁对于车辆空间的侵占是最小的,而多连杆和双叉臂对于车辆空间侵占是要更大的。

  • 湖南省医保局2015年工作思路与安排 湖南省医疗保障局领导班子组成人员

    督促指导各统筹地区核实提高缴费基数,强化保险费足额征收。继续加强工伤认定参与,把好工伤入口关。认真核实、积极处理群众举报问题,始终保持高压态势。加强生育医疗服务管理,规范生育津贴发放。二是启动实施工伤保险信息系统改造升级,改进工伤职工异地就医联网结算,方便工伤职工救治。三是加强财务、业务数据清理,提高数据质量;通报全省“三险”基金运行分析,指导市州加强基金运行风险管控。

  • 民国最渣四大渣男(民国著名4大渣男)

    当时很多文人在接受自由恋爱的思想时,家中已经有了父母为之安排的妻子。郁达夫一生有过三位妻子,一位同居情人。郁达夫后来还是和王映霞离婚,1940年在新加坡认识了比他小20岁的播音员李莜英,两人很快就同居了。第二任妻子佐藤富子,是个日本女人,为了和郭沫若在一起,不仅改名为“郭安娜”,还和父母断绝了关系。1937年,郭沫若抛弃妻子回国,和女明星于立群同居,两人于2年后再重庆结婚。

  • 电脑怎么连打印机教程(教会你快速学会电脑如何连接打印机的安装使用方法)

    最近很多网友都在私信给小编,小编也无法一一回复,有些问题也无法简约介绍,所以只能在头条文章内与大家共享。

  • 爱吃鸡蛋的注意了这3种鸡蛋不能买(这些鸡蛋没你想的那么好)

    营养均衡的孩子没必要补这种元素;真正缺乏硒,靠富硒蛋补,根本起不了多大作用。这类蛋再好,也别给孩子吃那就是全生或半熟的蛋,比如溏心蛋。一般溏心蛋的加热时间短,不能完全杀死细菌,生蛋液根本没有处理细菌,对于抵抗力低、易感染的宝宝来说,非常容易被细菌感染。