git重置

如果你使用git完成了commit之后又后悔了,git reset命令会给你一次吃后悔药的机会,本篇博客将会演示如何使用git reset命令,以及这个命令到底做了些什么。

#关于HEAD

我们之前的操作中,很多地方会用到HEAD,有过编程经验的人一般都知道,HEAD是头指针,在链表中通过移动HEAD来访问其它元素。在git中,我们也是通过移动HEAD来访问每一次提交的。

在git中,HEAD的信息保存在.git/HEAD文件中。在我的git仓库中,这个文件的内容是

ref: refs/heads/master

意思就是,HEAD是一个引用,指向refs/heads/master这个地址。打开refs/heads/master文件,看看是什么东西:

723687a41685667a01dbd6254eb148d19501c3f1

可以看出来,里面是一个哈希值id。这个id其实是我最新的一个提交的id。
到现在,我们就清楚git是如何通过HEAD来访问到每一次提交了:HEAD指向一个分支(这里是指向master分支),分支指向一个commit,而commit的parent又指向它的上一次提交,上一次提交的parent又指向上上一次提交,一直可以访问到第一次提交。
每一次提交,又关联一个文件树,所以,git通过HEAD还能访问到每一次提交时的所有文件的内容。

下面是一张比较完整的git对象库的图
这里写图片描述

#git reset的原理
通过对上面内容的理解,其实不就是通过HEAD来操作链表嘛!HEAD指向master,master指向一个最新的提交,回到本篇博客开头的那个问题,如果提交错了,如何吃后悔药,其实很简单,让master指向最新提交的上一次提交就可以了。

git reset --soft HEAD^

^符号代表parent。这个命令的意思是,让当前分支(这里是master)指向HEAD的上一次提交。关于--soft参数,我们稍后再讨论。
此时,运行git log命令,会发现最新的一次提交不见了。

#git reset的用法

git reset有两种用法,分别是

  1. git reset [commit] --<file>
  2. git reset [--soft | --mixed | --hard | --merge | --keep] [commit]

两种用法中都可以提供一个commit,默认是HEAD所指向的提交id。
第一种用法在git 暂存区这篇博客中提到过,就是用版本库中的某次提交时的文件树中的某个文件来覆盖暂存区的某个文件,从而撤销git add命令对暂存区的修改。

第二种用法就是我们今天讨论的,它会重置分支的引用,从而使当前分支指向某个提交id。

##git reset的参数

git reset命令的第二种用法可以添加不一样的参数,下面介绍一下常用的参数。

  • --soft参数仅仅重置分支的引用,不会修改暂存区和工作区。吃后悔药仅仅是为了修改注释的话,一般都使用这个参数
  • --mixed参数是默认值,它除了重置分支的引用以外,还会重置暂存区
  • --hard参数最干脆,因为它除了重置分支的引用以外,还会重置暂存区和工作区。

#如何挽救错误的重置?
通过git reset命令重置了分支的引用之后,通过git log已经无法查询出重置之前最新的提交id了,如果reset之后又后悔了,那该怎么办呢?git总是有办法的。
打开.git/logs/HEAD文件,会发现这里面记录着每一次移动HEAD时的历史记录,假设里面的内容是这样子的

0000000000000000000000000000000000000000 1a29bde9519195f14e98270c29d125e9d18b8d87 zdk <zdk@menhoo.com> 1497192021 +0800	commit (initial): 新增了a.txt和b.txt文件
1a29bde9519195f14e98270c29d125e9d18b8d87 723687a41685667a01dbd6254eb148d19501c3f1 zdk <zdk@menhoo.com> 1497796049 +0800	commit: add c.txt
723687a41685667a01dbd6254eb148d19501c3f1 1a29bde9519195f14e98270c29d125e9d18b8d87 zdk <zdk@menhoo.com> 1497796077 +0800	reset: moving to HEAD^

可以看出来,每移动一次HEAD的指向就会产生一条记录,并且HEAD是从第一个ID指向了第二个ID。首先,HEAD从一个空指针(40个0)指向了1a29bde9519195f14e98270c29d125e9d18b8d87,然后又从1a29bde9519195f14e98270c29d125e9d18b8d87指向了723687a41685667a01dbd6254eb148d19501c3f1,然后,又从723687a41685667a01dbd6254eb148d19501c3f1指向了1a29bde9519195f14e98270c29d125e9d18b8d87

有了这些操作记录中的提交id,我们就可以继续通过git reset [commit]来让HEAD指向你希望的那次提交了。

git为我们提供了git reflog命令来查看HEAD的移动历史记录,只是,git reflog命令返回的历史记录与.git/logs/HEAD文件中的历史记录的顺序正好相反。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值