git reset 命令常用操作

在实际开发会中经常会碰到这一场景,你想在commit A提交的版本上修改,你从代码仓拉下一份最新的代码,但是最新的代码以及有人提交了commit B、C、D好几次新的commit,这时你需要回退到commit A提交的版本,git reset命令用于将当前HEAD重置到指定状态。一般用于撤消之前的一些操作(如:git add,git commit等)。

首先了解一下“三棵树”的基本概念

作用
HEADHEAD 是当前分支引用的指针,它总是指向该分支上的最后一次提交,下一次提交的父结点
Index预期的下一次提交
Working Directory工作区

HEAD 是当前分支引用的指针,它总是指向当前branch最顶端的一个commit。 这表示HEAD将是下一次提交的父结点。 通常,理解HEAD的最简方式,就是将它看做该分支上的最后一次提交的快照。
Index(索引)也就是使用git add添加后的文件,是一堆将在下一次commit中提交的文件,提交之后它就是当前HEAD的父节点。这个概念被引用为Git的“暂存区”。
Working Directory(工作区)即实际工作目录。

git reset一般常用的形式:git reset [<mode>] [<commit>]
这种形式将当前分支HEAD重设为<commit>,并可能更新暂存区和工作区,具体取决于<mode>。如果省略了<mode>,默认为--mixed

<mode>常用的有以下几种,<commit>可以使用引用或者提交ID,如果省略<commit> 则相当于使用了HEAD的指向作为提交ID。

git reset --hard HEAD^
硬重置,此处<commit>使用对HEAD的引用。HEAD,Index(暂存区),Working Directory(工作区)同时改变到要reset的那个commit(上一次提交的状态)。HEAD指向的提交历史被删除,HEAD重新指向上一次提交,并且被git管理的工作区以及暂存区未提交的内容都会被彻底丢弃(慎用)。

git reset --soft HEAD^
软重置,HEAD改变到要reset的那个commit(上一次提交commit),HEAD指向的提交历史被删除,HEAD重新指向上一次提交,Index(暂存区),Working Directory(工作区)不会改变。

git reset --mixed HEAD^或者git reset HEAD^( 缺省即为–mixed)
默认重置,HEAD,Index(暂存区)改变到要reset的那个commit,HEAD指向的提交历史被删除,HEAD重新指向上一次提交,Index(暂存区)被重置,Working Directory(工作区)不重置(即保留已修改的文件,但不标记为提交)并报告未更新的内容,当修改了一个文件,工作区不再和index和HEAD相同了,所以当文件有改动,git会标记这些文件。

git reset -- filename或者git reset HEAD filename
仅将文件filename撤出暂存区,暂存区中其他文件不改变。相当于对命令git add filename的反向操作。


如果没有记下重置前master分支指向的提交ID,想要重置回原来的提交真的是一件麻烦的事情(去对象库中一个一个地找)。幸好Git提供了一个挽救机制,通过.git/logs目录下日志文件记录了分支的变更。默认非裸版本库(带有工作区)都提供分支日志功能,这是因为带有工作区的版本库都有如下设置:

$ git config core.logallrefupdates
true

cat .git/logs/refs/heads/master即可查看master分支的日志文件中的内容。
Git提供了一个git reflog命令,对这个文件进行操作。使用show子命令可以显示此文件的内容。

$ git reflog show master | head -5
9e8a761 master@{0}: 9e8a761: updating HEAD
e695606 master@{1}: HEAD^: updating HEAD
4902dc3 master@{2}: commit: does master follow this new commit?
e695606 master@{3}: commit: which version checked in?
a0c641e master@{4}: commit (amend): who does commit?

使用:command:git reflog的输出和直接查看日志文件最大的不同在于显示顺序的不同,即最新改变放在了最前面显示,而且只显示每次改变的最终的SHA1哈希值。还有个重要的区别在于使用git reflog的输出中还提供一个方便易记的表达式:<refname>@{<n>}。这个表达式的含义是引用之前第次改变时的SHA1哈希值。
那么将引用master切换到两次变更之前的值,可以使用下面的命令。

$ git reset --hard master@{2}
HEAD is now at 4902dc3 does master follow this new commit?

重置后工作区中文件又变回来了。提交历史也回来了。
此时如果再用git reflog查看,会看到恢复master的操作也记录在日志中了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值