git reset的用法

git reset的讲解

分支游标 master

我们仔细了解一下 git 的分支管理,就可以知道,其实 git 的所有管理都是通过 commit id 实现的,我们常用的 HEAD, master 以及分支名其实都只是代表的一个 commit id 而已,只不过是为了方便我们的记忆以比较 human 的方式表示。master 以及其他的 分支名对应的 commit id都存放在 .git/refs/heads 目录下,远程分支名存放在 .git/refs/remotes 目录下。

基本的三种reset 命令

首先讲三条不同参数下 reset 的命令,然后做一下个人的总结:

  • git reset –hard commit-id

    这条命令是最凶狠的,这条命令会将游标指向 commit-id指向的那次提交,并且暂存区也会更新到指定的那次提交时的内容,更狠的是暂存区的内容也会被覆盖。

  • git reset –mixed commit-id

    OK,这条命令没那么厉害,仓库和暂存区指向都会改变,不过工作区的内容不会改变。这也是默认的参数,–mixed可以不写。

  • git reset –soft commit-id

    这条命令是最弱的,只会改变仓库的游标。

我们在使用reset的时候需要很小心,因为在使用了reset命令之后,我们的游标就发生了变化,而我们使用 git log 时则找不到之前最新修改的 commit id, 即表示我们回不到最新的修改了,特别是如果使用了 –hard 参数,则真的就无力回天了。(实际上通过其他的途径也可以找到这个commit id,下面会讲到一种方法)

用 reflog 挽救错误的重置

我们在上面说过用 reset 命令会导致通过 git log命令找不到 commit-id 的问题,这里提供了一种挽救的机制(但是再次重申一下,如果是使用了–hard 参数,则丢失的修改是怎么也找不回来的,只能节哀了)reflog。
cat .git/logs/refs/heads/master (我们这里以master作为分析,对应哪一条分支就找相应的分支路径)的内容,我们可以看到如下的一些内容

712c0af3a20d370417b2af9a1dc4cb69d457a32b dcc27a803507baa3bf84832134c2def2589b4d1f xiongxing @oppo.com> 1427540691 +0800       pull: Fast-forward
dcc27a803507baa3bf84832134c2def2589b4d1f 712c0af3a20d370417b2af9a1dc4cb69d457a32b xiongxing @oppo.com> 1427541028 +0800       reset: moving to HEAD^
712c0af3a20d370417b2af9a1dc4cb69d457a32b dcc27a803507baa3bf84832134c2def2589b4d1f xiongxing @oppo.com> 1427544280 +0800       pull origin: Fast-forward
dcc27a803507baa3bf84832134c2def2589b4d1f 712c0af3a20d370417b2af9a1dc4cb69d457a32b xiongxing @oppo.com> 1427549639 +0800       reset: moving to HEAD^
712c0af3a20d370417b2af9a1dc4cb69d457a32b c6c5d37b13d8bfc112ccfbf3a06353c5a1d136c0 xiongxing @oppo.com> 1427549663 +0800       reset: moving to HEAD^^
c6c5d37b13d8bfc112ccfbf3a06353c5a1d136c0 dcc27a803507baa3bf84832134c2def2589b4d1f xiongxing @oppo.com> 1427549710 +0800       reset: moving to dcc27a803507baa3bf84832134c2def2589b4d1f

不难看出的是这个文件的内容记录了我们的每一次提交 commit-id 的变迁,第一列表示的是上一次提交的id,第二列表示的是操作后的id,如果我们知道之前的head对应的是哪一种,那么就可以非常容易地回到开始的位置。

另一种方式,通过 git reflog 命令也可以打印出该文件的内容,并且显示方式更加友好,如果用git reflog show <分支名>,则可以显示出具体分支的改动。

xing@ubuntu-15-121:~/work/GitTest/HelloWorld$ git reflog show master
3de57a5 master@{0}: reset: moving to HEAD@{2}
54c93a8 master@{1}: commit: add another line
6c16b56 master@{2}: reset: moving to HEAD^^
3de57a5 master@{3}: commit: add third line
109e443 master@{4}: commit: add second line
6c16b56 master@{5}: reset: moving to HEAD^
9eca0a6 master@{6}: commit: fifth file
6c16b56 master@{7}: reset: moving to HEAD^
2dfaece master@{8}: commit: delete all files
6c16b56 master@{9}: reset: moving to HEAD^
65cd018 master@{10}: commit: add second line
6c16b56 master@{11}: commit (initial): first add 1 2 3 4

并且使用 git reset master@{n} (n为上面数字中的一个)就可以回到对应的修改处。

git reset 的第二种用法

  • git reset [-q] [] [–]

这种用法和上面介绍的用法的区别在于,这种用法可以在命令中包含路径。并且不会重置引用,更不会改变工作区,而只是用指定提交状态()下的文件()替换掉暂存区中的文件。

注意,这条命令是替换暂存区中的文件,工作区和仓库中的文件不会受到影响。-q 是表示 quiet ,只显示出错的信息。

你可能感兴趣的:(工具)