1、在工作区创建一个新文件,并提交到版本库中:
查看master分支中最新提交的ID,发生改变,指向新的提交:
查看提交日志:
引用refs/heads/master像一个游标,可以指向新的提交。
git reset命令可以将游标指向任意一个存在的提交ID。
重置到父提交(–hard参数,会破坏工作区未提交的改动以及暂存区的修改内容,包括重置文件和其他文件中的未提交修改都会丢失):
可以发现新添加的文件new-commit.txt也丢失了。在工作区的文件也丢失了。
可以重置比较早的历史文件,会回退到原始版本库,曾经的修改都丢失了:
使用重置命令很危险,会彻底地丢弃历史,也不能通过浏览提交历史的提交ID找回。让提交历史都改变了:
如果是reset 当前的提交时,不会修改历史记录和修改:
但是如果重置历史之前的提交,那么最近修改的记录都会被删除,即使已经提交到版本库,它也会丢失。
如果再往前重置,在最初提交之后的文件都会被重置丢失:
找出重置丢失的文件
查看重置前master分支指向的提交ID:日志文件记录了分支的变更(最新的改变追加到文件的结尾,ID由89e566变成611f143):
也可以使用reflog查看:
该命令将最新的改变放在最前面,可以将引用master切换到指定的变更:
会发现之前丢失的修改和文件又回来了。而且提交的历史也回来了:
详解git reset命令
1、使用参数 –hard,如:git reset –hard <\commit>。其中commit的值可以是引用HEAD或提交ID。
执行该命令后,会导致:
a、替换引用的指向。引用会指向新的提交ID
b、替换暂存区。替换后,暂存区的内容和引用指向的目录树一致。
c、替换工作区。替换后,工作区的内容和暂存区一致,也和HEAD所指向的目录树一致。
2、使用参数 –soft,如:git reset –soft <\commit>。
执行该命令后,会导致:
a、只改变引用的指向,不改变暂存区和工作区。
会发现只是master的指向发生改变了,而暂存区的文件还在,而且工作区的修改也还在。
3、使用参数 –mixed 或不使用参数(默认为 –mixed) ,例如:
git reset –mixed <\commit> 或 git reset <\commit>
执行该命令后,会导致:
a、更改引用的指向 和重置暂存区
b、但是不改变工作区
工作区的修改没有变化,暂存区未提交的文件也没有丢失,但是上一次提交的文件重新回到暂存区。同时master指向也发生变化。
总结:
–hard HEAD^:引用回退到前一次,而且工作区和暂存区都会回退到上一次提交的状态。自上次以来的提交都会全部丢失。
–mixed HEAD^:工作区不改变,但是暂存区回退到上一次提交之前,引用也会回退一次。
HEAD^:同上;
–soft HEAD^:工作区和暂存区不改变,但是引用向前回退一次。
其中,下面的两条命令是等价的:
git reset HEAD:仅用HEAD指向目录树的重置暂存区,工作区不会受到影响,相当于将之前用git add 命令更新到暂存区的内容撤出暂存区。引用也不会改变。引用重置到HEAD,相当于没有重置。
git reset:同上;
下面的两条命令也是等价的:
git reset – fileName:仅将文件filename的改动撤出暂存区,暂存区中其他文件不改变。相当于对命令git add filename的反向操作。
git reset HEAD filename:同上;