Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1502051
  • 博文数量: 228
  • 博客积分: 1698
  • 博客等级: 上尉
  • 技术积分: 3241
  • 用 户 组: 普通用户
  • 注册时间: 2008-12-24 21:49
个人简介

Linux

文章分类

全部博文(228)

文章存档

2017年(1)

2016年(43)

2015年(102)

2014年(44)

2013年(5)

2012年(30)

2011年(3)

分类: LINUX

2016-01-12 23:30:34

.git/refs/heads/master指向当前最新的提交,当有新的提交产生时,其再次指向更新的提交。

Git支持git reset命令,可以将"master"指向任意一个存在的提交ID,下面具体看一下:

首先HEAD^代表了HEAD的上一次的提交,当前的提交日志,列举了最新的三次提交
点击(此处)折叠或打开
  1. [root@S-LAB-52 demo]# git log
  2. commit 6ca2d9e296e88155eefa1cbf4881745c58fd6295
  3. Author: test_01 <test_01@gmail.com>
  4. Date: Tue Dec 29 16:41:00 2015 +0800

  5.     add new welcome.txt

  6. commit 5205e4d591b6b8c1e2f9c7920f80cbe701976b4d
  7. Author: test_01 <test_01@gmail.com>
  8. Date: Tue Dec 29 11:44:38 2015 +0800

  9.     Add Bye to a/b/c/hello.txt

  10. commit cce206f9557381a1312aa131ed1b6c4da9f1f73e
  11. Author: test_01 <test_01@gmail.com>
  12. Date: Tue Dec 29 11:43:54 2015 +0800

  13.     Test
然后执行git reset --hard HEAD^,更新master的指向
点击(此处)折叠或打开
  1. [root@S-LAB-52 demo]# cat .git/refs/heads/master 
  2. 6ca2d9e296e88155eefa1cbf4881745c58fd6295
  3. [root@S-LAB-52 demo]# git reset --hard HEAD^
  4. HEAD is now at 5205e4d Add Bye to a/b/c/hello.txt
  5. [root@S-LAB-52 demo]# git reset --hard HEAD^
  6. HEAD is now at cce206f Test
可以看到最早的commit ID为6ca2....,执行第一次reset --hard HEAD^后,master指向5205e4d,执行第二次后,指向cce206f。我们确认一下
点击(此处)折叠或打开
  1. [root@S-LAB-52 demo]# cat .git/refs/heads/master 
  2. cce206f9557381a1312aa131ed1b6c4da9f1f73e
最新的两次提交记录丢失了,只有第三次的更新提交记录,同样文件内容也退回了第三次的状态
点击(此处)折叠或打开
  1. [root@S-LAB-52 demo]# git log -2
  2. commit cce206f9557381a1312aa131ed1b6c4da9f1f73e
  3. Author: test_01 <test_01@gmail.com>
  4. Date: Tue Dec 29 11:43:54 2015 +0800

  5.     Test

  6. commit 9975c5d8cd5b25b33349bd30144d6bac5b24afe8
  7. Author: test_01 <test_01@gmail.com>
  8. Date: Mon Dec 28 17:34:55 2015 +0800

  9.     which version checked in
除了支持重置到前一次提交,可以根据commit ID重置到任意一次提交
点击(此处)折叠或打开
  1. [root@S-LAB-52 demo]# git log --pretty=oneline
  2. cce206f9557381a1312aa131ed1b6c4da9f1f73e Test
  3. 9975c5d8cd5b25b33349bd30144d6bac5b24afe8 which version checked in
  4. 582e8137c51efc81cec1f17026ef97d282208aa2 who does commit
  5. 5c67e19b479ecf9892844491465c7cbaf75196ef New File For GIT
  6. [root@S-LAB-52 demo]# 
  7. [root@S-LAB-52 demo]# git reset --hard 5c67e19b479ecf9892844491465c7cbaf75196ef
  8. HEAD is now at 5c67e19 New File For GIT
  9. [root@S-LAB-52 demo]# git log -1
  10. commit 5c67e19b479ecf9892844491465c7cbaf75196ef
  11. Author: root <root@S-LAB-52.(none)>
  12. Date: Mon Dec 28 08:46:39 2015 +0800

  13.     New File For GIT
重置命令很危险,除了更改文件内容外,git log的记录也会被更改,使用时需要注意。重置之前记录了早期的各个commitID,还是可以直接通过
git reset --hard commitID,直接找回来。

那错误重置之后,没有记住早期的commitID,怎么可以还原回来呢?
点击(此处)折叠或打开
  1. [root@S-LAB-52 demo]# cat .git/logs/refs/heads/master 
  2. 0000000000000000000000000000000000000000 5c67e19b479ecf9892844491465c7cbaf75196ef \
  3. root <root@S-LAB-52.(none)> 1451263599 +0800    commit (initial): New File For GIT
  4. 5c67e19b479ecf9892844491465c7cbaf75196ef 93cc8866be680eb909d68c02148e9e7d689fa14a \
  5. root <root@S-LAB-52.(none)> 1451272489 +0800    commit: who does commit
  6. 93cc8866be680eb909d68c02148e9e7d689fa14a b76d431352e65c90e2f6c57793b16f8114d6ca05 \
  7. aaabbb <aaabbb@163.com.cn> 1451273334 +0800    commit (amend): who does commit
  8. b76d431352e65c90e2f6c57793b16f8114d6ca05 db8bd631c8ea69e968c583d009bd97224e110738 \
  9. test <test@staff.sina.com.cn> 1451273448 +0800    commit (amend): who does commit
  10. db8bd631c8ea69e968c583d009bd97224e110738 582e8137c51efc81cec1f17026ef97d282208aa2 \
  11. test_01 <test_01@gmail.com> 1451274083 +0800    commit (amend): who does commit
  12. 582e8137c51efc81cec1f17026ef97d282208aa2 9975c5d8cd5b25b33349bd30144d6bac5b24afe8 \
  13. test_01 <test_01@gmail.com> 1451295295 +0800    commit: which version checked in
  14. 9975c5d8cd5b25b33349bd30144d6bac5b24afe8 cce206f9557381a1312aa131ed1b6c4da9f1f73e \
  15. test_01 <test_01@gmail.com> 1451360634 +0800    commit: Test
  16. cce206f9557381a1312aa131ed1b6c4da9f1f73e 5205e4d591b6b8c1e2f9c7920f80cbe701976b4d \
  17. test_01 <test_01@gmail.com> 1451360678 +0800    commit: Add Bye to a/b/c/hello.txt
  18. 5205e4d591b6b8c1e2f9c7920f80cbe701976b4d 6ca2d9e296e88155eefa1cbf4881745c58fd6295 \
  19. test_01 <test_01@gmail.com> 1451378460 +0800    commit: add new welcome.txt
  20. 6ca2d9e296e88155eefa1cbf4881745c58fd6295 5205e4d591b6b8c1e2f9c7920f80cbe701976b4d \
  21. test_01 <test_01@gmail.com> 1451378748 +0800    HEAD^: updating HEAD
  22. 5205e4d591b6b8c1e2f9c7920f80cbe701976b4d cce206f9557381a1312aa131ed1b6c4da9f1f73e \
  23. test_01 <test_01@gmail.com> 1451378760 +0800    HEAD^: updating HEAD
  24. cce206f9557381a1312aa131ed1b6c4da9f1f73e 5c67e19b479ecf9892844491465c7cbaf75196ef \
  25. test_01 <test_01@gmail.com> 1451379373 +0800    5c67e19b479ecf9892844491465c7cbaf75196ef: updating HEAD
  26. 5c67e19b479ecf9892844491465c7cbaf75196ef 6ca2d9e296e88155eefa1cbf4881745c58fd6295 \
  27. test_01 <test_01@gmail.com> 1451379551 +0800    6ca2d9e296e88155eefa1cbf4881745c58fd6295: updating HEAD
.git/logs/refs/heads/master记录了master分支指向的变迁,最新的改变追加到文件的末尾,我们可以通过该文件的记录还原reset的修改。

Git提供了git reflog命令,可以对该文件进行操作,使用show子命令可以显示该文件的内容
点击(此处)折叠或打开
  1. [root@S-LAB-52 demo]# git reflog show master
  2. 6ca2d9e master@{0}: 6ca2d9e296e88155eefa1cbf4881745c58fd6295: updating HEAD
  3. 5c67e19 master@{1}: 5c67e19b479ecf9892844491465c7cbaf75196ef: updating HEAD
  4. cce206f master@{2}: HEAD^: updating HEAD
  5. 5205e4d master@{3}: HEAD^: updating HEAD
  6. 6ca2d9e master@{4}: commit: add new welcome.txt
  7. 5205e4d master@{5}: commit: Add Bye to a/b/c/hello.txt
  8. cce206f master@{6}: commit: Test
  9. 9975c5d master@{7}: commit: which version checked in
  10. 582e813 master@{8}: commit (amend): who does commit
  11. db8bd63 master@{9}: commit (amend): who does commit
  12. b76d431 master@{10}: commit (amend): who does commit
  13. 93cc886 master@{11}: commit: who does commit
git reflog的输出将最新的修改放在了最前面显示,而且只显示每次改变最终的SHA1的值,另外,其输出中还标识了当前是第几次改变。
点击(此处)折叠或打开
  1. [root@S-LAB-52 demo]# git reset --hard master@{1}
  2. HEAD is now at 5c67e19 New File For GIT
  3. [root@S-LAB-52 demo]# git reflog show master
  4. 5c67e19 master@{0}: master@{1}: updating HEAD
  5. 6ca2d9e master@{1}: 6ca2d9e296e88155eefa1cbf4881745c58fd6295: updating HEAD
  6. 5c67e19 master@{2}: 5c67e19b479ecf9892844491465c7cbaf75196ef: updating HEAD
  7. cce206f master@{3}: HEAD^: updating HEAD
  8. 5205e4d master@{4}: HEAD^: updating HEAD
  9. 6ca2d9e master@{5}: commit: add new welcome.txt
  10. 5205e4d master@{6}: commit: Add Bye to a/b/c/hello.txt
  11. cce206f master@{7}: commit: Test
  12. 9975c5d master@{8}: commit: which version checked in
  13. 582e813 master@{9}: commit (amend): who does commit
  14. db8bd63 master@{10}: commit (amend): who does commit
  15. b76d431 master@{11}: commit (amend): who does commit
  16. 93cc886 master@{12}: commit: who does commit
  17. [root@S-LAB-52 demo]# git reset --hard master@{1}
  18. HEAD is now at 6ca2d9e add new welcome.txt
可以直接根据 master@{1} 进行设置

git reset有两种用法:
点击(此处)折叠或打开
  1. git reset [-q] [<commit>] [--] <paths>....
  2. git reset [--soft | --mixed | --hard | --merge | --keep] [-q] [<commit>]
其中commit是可选项,可以用引用或提交ID,当省略commit时相当于使用HEAD的指向作为提交ID。

第一种用法,不会重置引用,也不会改变工作区,会使用指定提交状态的文件替换掉暂存区中的文件。
当commitID省略时,为了避免paths与commitID冲突,需要在paths前面增加--以示区分。
第二种用法,会重置引用,根据选项定义,可以对暂存区或者工作区进行重置:
1)--hard,git reset --hard :会替换引用的指向;会替换暂存区;会替换工作区;替换后工作区/暂存区/引用指向的内容相同
2)--soft,git reset --soft :只更改引用的指向,不会影响暂存区和工作区
3)--mixed,默认值,git reset :更改引用的指向,重置暂存区,不改变工作区

git reset:用HEAD指向的目录树重置暂存区,工作区不受影响,引用未改变,相当于撤销git add命令更新到暂存区的内容撤出暂存区
git reset HEAD:同git reset
git reset -- filename:将filename的改动撤出暂存区,暂存区其他文件不变,相当于git add filename的逆向操作
git reset HEAD filename:同git reset -- filename
git reset --soft HEAD^:工作区和暂存区不变,引用向前回退一次
git reset HEAD^:工作区不变,暂存区回退到上一次提交之前,引用向前回退一次
git reset --mixed HEAD^:同git reset HEAD^
git reset --hard HEAD^:撤销最近的修改,工作区和暂存区都回退到上一次提交的状态

========================================================================================

下面看一下git checkout的使用,有三种用法:

用法一:git checkout  [-q]  []  [--]  [paths]......
commitID是可选的,
当省略commitID时,相当于从暂存区检出(覆盖指定文件),检出命令主要是覆盖工作区,
当指定commitID时,相当于从版本库检出(覆盖指定文件),同时替换暂存区和工作区的相应文件

用法二:git checkout  []
不用paths时,会改变HEAD指针指向对应的分支,此时主要用于切换分支。
当省略branch时,相当于对工作区进行状态检查。

用法三:git checkout  [-m]  [-b | --orphon]    []
用于创建和切换到新的分支,新的分支从指定的提交开始创建。

git checkout:汇总工作区、暂存区与HEAD的差异
git checkout HEAD:同git checkout
git checkout -- filename:用暂存区中的filename覆盖工作区的文件
git checkout branch -- filename:HEAD指向不变,用branch指向的提交中的filename覆盖暂存区和工作区中的相应文件
git checkout .:取消所有工作区中的修改(相对于暂存区),即用暂存区中的文件覆盖工作区中的所有文件
阅读(1452) | 评论(0) | 转发(0) |
0

上一篇:git stash

下一篇:FFmpeg for Linux

给主人留下些什么吧!~~