1、checkout

  • git checkout 命令:用于切换分支。
  • git checkout –file.ext 撤销对文件的修改
[root@linux-node5 test]# git branch   #查看当前分支
* master
  test
[root@linux-node5 test]# echo "2233" >> index.html   #对文件进行修改
[root@linux-node5 test]# git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   index.html

no changes added to commit (use "git add" and/or "git commit -a")
[root@linux-node5 test]# git checkout -- index.html  #撤销文件
[root@linux-node5 test]# git status
On branch master
nothing to commit, working directory clean
[root@linux-node5 test]# tail -1 index.html   #此刻发现已经没有修改的2233了
111

2、git reset

  • --soft 缓存区和工作目录都不会被改变
  • --mixed 默认选项。缓存区和你指定的提交同步,但工作目录不受影响
  • --hard 缓存区和工作目录都同步到你指定的提交

--soft 缓存区和工作目录都不会被改变

#对首页文件及news页面进行修改
[root@linux-node5 test]# echo "2233" >> index.html 
[root@linux-node5 test]# echo "2233" >> news.html 

#对news页面进行提交
[root@linux-node5 test]# git add  news.html

#可以看到news在暂存区,index在工作区
[root@linux-node5 test]# git status 
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    modified:   news.html

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   index.html

#查看提交日志
[root@linux-node5 test]# git log 
commit 912f315d1542ade0a38f91fd52c9ebfe02c91305
Author: liyanzhao <1210353303@qq.com>
Date:   Thu Mar 28 17:06:28 2019 +0800

    about2

commit 7ecca1f5b20edced0272f352936e74acc7822da3
Author: liyanzhao <1210353303@qq.com>
Date:   Thu Mar 28 17:02:37 2019 +0800

    about

commit 6ab971b1f4679b213a05749f4aceb844ffe2d29a    #这里的字符串在提交回滚时,复制部分即可
Author: liyanzhao <1210353303@qq.com>
Date:   Thu Mar 28 16:33:05 2019 +0800

    pay

commit 0510d3d204d4f3f770927e98d8d17688e27cb61b
Author: liyanzhao <1210353303@qq.com>
Date:   Thu Mar 28 16:31:40 2019 +0800

    news

commit aa802c2fe39d27c11eba7e9659b12b32a2fe2304
Author: liyanzhao <1210353303@qq.com>
Date:   Thu Mar 28 16:27:13 2019 +0800

    first commit

#用 --hard 回滚到pay 
[root@linux-node5 test]# git reset --hard 6ab971b1f467
HEAD is now at 6ab971b pay

#再次查看时,发现工作目录及暂存区没被清空了
[root@linux-node5 test]# git status 
On branch master
nothing to commit, working directory clean

#再次查看发下本地仓库只剩三次提交了。
[root@linux-node5 test]# git log 
commit 6ab971b1f4679b213a05749f4aceb844ffe2d29a
Author: liyanzhao <1210353303@qq.com>
Date:   Thu Mar 28 16:33:05 2019 +0800

    pay

commit 0510d3d204d4f3f770927e98d8d17688e27cb61b
Author: liyanzhao <1210353303@qq.com>
Date:   Thu Mar 28 16:31:40 2019 +0800

    news

commit aa802c2fe39d27c11eba7e9659b12b32a2fe2304
Author: liyanzhao <1210353303@qq.com>
Date:   Thu Mar 28 16:27:13 2019 +0800

    first commit

#验证about及about2 已经不存在了
[root@linux-node5 test]# ll
total 12
-rw-r--r-- 1 root root  4 Mar 29 09:12 index.html
-rw-r--r-- 1 root root  5 Mar 29 09:12 news.html
-rw-r--r-- 1 root root 11 Mar 28 16:32 pay.html



#提示:如果上回滚到两次前的操作,也可以用下面的命令
git reset HEAD~2

3、git reflog

过了一分钟发现我不需要回滚,还要回到最初的状态

[root@linux-node5 test]# git reflog  #查看所有的操作
6ab971b HEAD@{0}: reset: moving to 6ab971b1f467
912f315 HEAD@{1}: checkout: moving from test to master
5748933 HEAD@{2}: commit: test
912f315 HEAD@{3}: checkout: moving from master to test
912f315 HEAD@{4}: merge about: Fast-forward
6ab971b HEAD@{5}: checkout: moving from about to master
912f315 HEAD@{6}: commit: about2        #这一行
7ecca1f HEAD@{7}: checkout: moving from master to about
6ab971b HEAD@{8}: checkout: moving from about to master
7ecca1f HEAD@{9}: commit: about
6ab971b HEAD@{10}: checkout: moving from master to about
6ab971b HEAD@{11}: commit: pay
0510d3d HEAD@{12}: commit: news
aa802c2 HEAD@{13}: commit (initial): first commit

#开始回滚
[root@linux-node5 test]# git checkout 912f315
Note: checking out '912f315'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

HEAD is now at 912f315... about2

#这里已经找到想要的了
[root@linux-node5 test]# git log 
commit 912f315d1542ade0a38f91fd52c9ebfe02c91305
Author: liyanzhao <1210353303@qq.com>
Date:   Thu Mar 28 17:06:28 2019 +0800

    about2

commit 7ecca1f5b20edced0272f352936e74acc7822da3
Author: liyanzhao <1210353303@qq.com>
Date:   Thu Mar 28 17:02:37 2019 +0800

    about

commit 6ab971b1f4679b213a05749f4aceb844ffe2d29a
Author: liyanzhao <1210353303@qq.com>
Date:   Thu Mar 28 16:33:05 2019 +0800

    pay

commit 0510d3d204d4f3f770927e98d8d17688e27cb61b
Author: liyanzhao <1210353303@qq.com>
Date:   Thu Mar 28 16:31:40 2019 +0800

    news

commit aa802c2fe39d27c11eba7e9659b12b32a2fe2304
Author: liyanzhao <1210353303@qq.com>
Date:   Thu Mar 28 16:27:13 2019 +0800

    first commit
[root@linux-node5 test]# ll
total 16
-rw-r--r-- 1 root root  4 Mar 29 09:34 about2.html
-rw-r--r-- 1 root root  0 Mar 29 09:34 about.html
-rw-r--r-- 1 root root  4 Mar 29 09:12 index.html
-rw-r--r-- 1 root root  5 Mar 29 09:12 news.html
-rw-r--r-- 1 root root 11 Mar 28 16:32 pay.html

#此刻发现这些还不在master分支
[root@linux-node5 test]# git status
HEAD detached at 912f315
nothing to commit, working directory clean

#此状态新建一个分支为reset的分支
[root@linux-node5 test]# git branch reset
[root@linux-node5 test]# git branch 
* (HEAD detached at 912f315)
  master
  reset
  test

#切换至master分支
[root@linux-node5 test]# git checkout master 
Previous HEAD position was 912f315... about2
Switched to branch 'master'

#合并reset分支到master
[root@linux-node5 test]# git merge reset 
Updating 6ab971b..912f315
Fast-forward
 about.html  | 0
 about2.html | 1 +
 2 files changed, 1 insertion(+)
 create mode 100644 about.html
 create mode 100644 about2.html

#经过验证,发现已经达到想要的状态了
[root@linux-node5 test]# git status 
On branch master
nothing to commit, working directory clean
[root@linux-node5 test]# git log 
commit 912f315d1542ade0a38f91fd52c9ebfe02c91305
Author: liyanzhao <1210353303@qq.com>
Date:   Thu Mar 28 17:06:28 2019 +0800

    about2

commit 7ecca1f5b20edced0272f352936e74acc7822da3
Author: liyanzhao <1210353303@qq.com>
Date:   Thu Mar 28 17:02:37 2019 +0800

    about

commit 6ab971b1f4679b213a05749f4aceb844ffe2d29a
Author: liyanzhao <1210353303@qq.com>
Date:   Thu Mar 28 16:33:05 2019 +0800

    pay

commit 0510d3d204d4f3f770927e98d8d17688e27cb61b
Author: liyanzhao <1210353303@qq.com>
Date:   Thu Mar 28 16:31:40 2019 +0800

    news

commit aa802c2fe39d27c11eba7e9659b12b32a2fe2304
Author: liyanzhao <1210353303@qq.com>
Date:   Thu Mar 28 16:27:13 2019 +0800

    first commit
[root@linux-node5 test]# ll
total 16
-rw-r--r-- 1 root root  4 Mar 29 09:38 about2.html
-rw-r--r-- 1 root root  0 Mar 29 09:38 about.html
-rw-r--r-- 1 root root  4 Mar 29 09:12 index.html
-rw-r--r-- 1 root root  5 Mar 29 09:12 news.html
-rw-r--r-- 1 root root 11 Mar 28 16:32 pay.html

4、使用场景:

5、理论总结

Checkout一个文件和带文件路径git reset 非常像,除了它更改的是工作目录而不是缓存区。不像提交层面的checkout命令,它不会移动HEAD引用,也就是你不会切换到别的分支上去。

如果你缓存并且提交了checkout的文件,它具备将某个文件回撤到之前版本的效果。注意它撤销了这个文件后面所有的更改,而git revert 命令只撤销某个特定提交的更改。

当检测到文件路径时,git reset 将缓存区同步到你指定的那个提交。比如,下面这个命令会将倒数第二个提交中的foo.py加入到缓存区中,供下一个提交使用。

git reset HEAD~2 foo.py

运行git reset HEAD foo.py 会将当前的foo.py从缓存区中移除出去,而不会影响工作目录中对foo.py的更改。

--soft、--mixed和--hard对文件层面的git reset毫无作用,因为缓存区中的文件一定会变化,而工作目录中的文件一定不变。

git reflog 命令分析你所有分支的头指针的日志来查找出你在重写历史上可能丢失的提交。

文档更新时间: 2019-03-29 10:47   作者:李延召