您的位置:首页 > 其它

git详解(三)回退操作

2016-11-27 21:40 162 查看

git详解(三)回退操作

摘要: 在我们使用git修改文件需要回到修改之前的状态时,就需要git的回退操作,回退操作对于我们很重要,本文主要介绍关于git回退操作的内容。包括git reset ,git checkout。通过本文,我们可以对git的回退操作有一个很好的理解。

关键字:  回退,reset, checkout

git详解三回退操作
 git logreflog

git reset

git checkout

conclusion

1. git log/reflog

master这个引用指向我们最新的提交,类似于一个游标,通过git reset可以对游标进行修改。

fox@fox:~/Documents/demo$ git log --oneline
539d895 add new.log
ba7f561 commit
0e94145 add test.txt
fox@fox:~/Documents/demo$ git reset --hard ba7f561
fox@fox:~/Documents/demo$ git log --oneline
ba7f561 commit
0e94145 add test.txt


发现在执行git reset的时候,master发生了变化,git log也随之进行了变化,那么问题来了,是不是我们只能git reset 历史commit呢?也就是这样的游标只能往后,不能往前,其实不是的。我们继续看一下提交log。

fox@fox:~/Documents/demo$ cat .git/logs/refs/heads/master
0000000000000000000000000000000000000000 0e94145e01eb5da2420dd8a47d103aeab1dff44b fox <leehaoran111@163.com> 1476806519 +0800   commit (initial): add test.txt
0e94145e01eb5da2420dd8a47d103aeab1dff44b ba7f561a2798f2b41a7131888bdbc58531ba89c5 fox <leehaoran111@163.com> 1478435045 +0800   commit: commit
ba7f561a2798f2b41a7131888bdbc58531ba89c5 d4c1f0765b0b58ce464d95989f2ebfe4094f4f54 fox <leehaoran111@163.com> 1478439077 +0800   commit: ok
d4c1f0765b0b58ce464d95989f2ebfe4094f4f54 ba7f561a2798f2b41a7131888bdbc58531ba89c5 fox <leehaoran111@163.com> 1480241004 +0800   reset: moving to HEAD^
ba7f561a2798f2b41a7131888bdbc58531ba89c5 539d8955e8820776f914d93f5778e2025884f0a6 fox <leehaoran111@163.com> 1480241093 +0800   commit: add new.log
539d8955e8820776f914d93f5778e2025884f0a6 ba7f561a2798f2b41a7131888bdbc58531ba89c5 fox <leehaoran111@163.com> 1480241299 +0800   reset: moving to HEAD^
ba7f561a2798f2b41a7131888bdbc58531ba89c5 539d8955e8820776f914d93f5778e2025884f0a6 fox <leehaoran111@163.com> 1480242249 +0800   reset: moving to 539d895
539d8955e8820776f914d93f5778e2025884f0a6 ba7f561a2798f2b41a7131888bdbc58531ba89c5 fox <leehaoran111@163.com> 1480242306 +0800   reset: moving to ba7f561
fox@fox:~/Documents/demo$ git cat-file -p 539d8955
tree b5f005e70497d197ba637c9576621beda3ec7233
parent ba7f561a2798f2b41a7131888bdbc58531ba89c5
author fox <leehaoran111@163.com> 1480241093 +0800
committer fox <leehaoran111@163.com> 1480241093 +0800

add new.log
fox@fox:~/Documents/demo$ git cat-file -p b5f005e
100644 blob 6594dfffc7a1e8b880c02eb5f97d11caef98a6d0    new.log
100644 blob 7aeee4f72cc77cc564fcc3aa7fd03caea3542fcb    test.txt
fox@fox:~/Documents/demo$ git cat-file -p 6594dfff
git reset demo


发现可以在git 的提交log中找到历史的master commit id.  也就是539d8955e88。

通过git reset 539d8955e88 会发现new.log又回来了。

fox@fox:~/Documents/demo$ git reset --hard 539d8955e
HEAD is now at 539d895 add new.log
fox@fox:~/Documents/demo$ ll
total 20
drwxrwxr-x  3 fox fox 4096 11月 27 18:35 ./
drwxr-xr-x 10 fox fox 4096 11月  6 22:06 ../
drwxrwxr-x  8 fox fox 4096 11月 27 18:35 .git/
-rw-rw-r--  1 fox fox   15 11月 27 18:35 new.log
-rw-rw-r--  1 fox fox   45 11月  6 21:18 test.txt


前面log文件中记录的master变化是顺序的,也就是最新的在最下面,git reflog可以看到倒序的变化,这样方便我们查看。

fox@fox:~/Documents/demo$ git reflog
539d895 HEAD@{0}: reset: moving to 539d8955e
ba7f561 HEAD@{1}: reset: moving to ba7f561a
539d895 HEAD@{2}: reset: moving to 539d8955e
ba7f561 HEAD@{3}: reset: moving to ba7f56
539d895 HEAD@{4}: reset: moving to 539d8955e8
ba7f561 HEAD@{5}: reset: moving to ba7f561
539d895 HEAD@{6}: reset: moving to 539d895
ba7f561 HEAD@{7}: reset: moving to HEAD^
539d895 HEAD@{8}: commit: add new.log
ba7f561 HEAD@{9}: reset: moving to HEAD^
d4c1f07 HEAD@{10}: commit: ok
ba7f561 HEAD@{11}: commit: commit
0e94145 HEAD@{12}: commit (initial): add test.txt


这样,我们可以通过git log 和git reflog就可以查看之前之后的提交commit id.

2. git reset

在知道了怎样查找commit id之后,我们就可以借助git reset来按照我们的需求切换commit id了。

git reset可以加路径也可以不加路径,加路径表示更改一个文件。

git reset [--soft | --mixed [-N] | --hard | --merge | --keep] [-q] [<commit>]


git reset 后面加–soft,–hard,–mixed是有区别的,这也经常会用到,我们举一个例子看一下区别

step 1:let us create a file demo.c
fox@fox:~/Documents/demo$ git st
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)

demo.c

nothing added to commit but untracked files present (use "git add" to track)
fox@fox:~/Documents/demo$ git add *
fox@fox:~/Documents/demo$ git st
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)

new file:   demo.c
fox@fox:~/Documents/demo$ git reset --hard HEAD
HEAD is now at 539d895 add new.log
fox@fox:~/Documents/demo$ git st
On branch master
nothing to commit, working directory clean
fox@fox:~/Documents/demo$ ll
total 20
drwxrwxr-x  3 fox fox 4096 11月 27 19:02 ./
drwxr-xr-x 10 fox fox 4096 11月  6 22:06 ../
drwxrwxr-x  8 fox fox 4096 11月 27 19:02 .git/
-rw-rw-r--  1 fox fox   15 11月 27 18:35 new.log
-rw-rw-r--  1 fox fox   45 11月  6 21:18 test.txt
发现用--hard时,staging和工作区的修改和HEAD一样了。同时工作区demo.c也不见了。这时要恢复demo.c就比较麻烦了,需要在objects里面挨个找了。
我们新建一个demo.c,继续看--mixed
fox@fox:~/Documents/demo$ echo "i am demo.c" >demo.c
fox@fox:~/Documents/demo$ git st
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)

demo.c

nothing added to commit but untracked files present (use "git add" to track)
fox@fox:~/Documents/demo$ git add *
fox@fox:~/Documents/demo$ git st
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)

new file:   demo.c

fox@fox:~/Documents/demo$ git reset --mixed HEAD
fox@fox:~/Documents/demo$ git st
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)

demo.c

nothing added to commit but untracked files present (use "git add" to track)
可以看到--mixed用mstaer中的内容覆盖staging中的内容,但不修改工作区的修改。而且--mixed是默认的选项。
能猜到,--soft的话就是仅仅修改HEAD指向的commit id,不影响staging和工作区。


3 git checkout

git reset可以在当前分支中切换commit id,但是当我们想到切换HEAD指向的分支时该怎么办呢?我们知道在每一次git commit的时候,都是当前的HEAD指向的commit id会成为父提交。这时候就需要用到checkout.checkout也是经常会用到的一个命令。

git checkout [-q] [-f] [-m] [<branch>]
git checkout [-q] [-f] [-m] --detach [<branch>]
git checkout [-q] [-f] [-m] [--detach] <commit>
git checkout [-q] [-f] [-m] [[-b|-B|--orphan] <new_branch>] [<start_point>]
git checkout [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <paths>...
git checkout [-p|--patch] [<tree-ish>] [--] [<paths>...]
checkout有以下用法:
用法一:分支切换:
fox@fox:~/Documents/demo$ git br
fixbug
* master
fox@fox:~/Documents/demo$ git co fixbug
Switched to branch 'fixbug'
fox@fox:~/Documents/demo$ git br
* fixbug
master
用法二:显示staging和版本库的区别:
fox@fox:~/Documents/demo$ ll
total 16
drwxrwxr-x  3 fox fox 4096 11月 27 21:23 ./
drwxr-xr-x 10 fox fox 4096 11月  6 22:06 ../
drwxrwxr-x  8 fox fox 4096 11月 27 21:24 .git/
-rw-rw-r--  1 fox fox   45 11月  6 21:18 test.txt
fox@fox:~/Documents/demo$ echo "add more" >> test.txt
fox@fox:~/Documents/demo$ git st
On branch fixbug
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:   test.txt

no changes added to commit (use "git add" and/or "git commit -a")
fox@fox:~/Documents/demo$ git add test.txt
fox@fox:~/Documents/demo$ git st
On branch fixbug
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)

modified:   test.txt

fox@fox:~/Documents/demo$ git co
M   test.txt
用法三:用其它分支的文件代替本分支staging和工作区的文件:
fox@fox:~/Documents/demo$ git cat-file -p master:new.log
git reset demo
fox@fox:~/Documents/demo$ ll
total 16
drwxrwxr-x  3 fox fox 4096 11月 27 21:28 ./
drwxr-xr-x 10 fox fox 4096 11月  6 22:06 ../
drwxrwxr-x  8 fox fox 4096 11月 27 21:28 .git/
-rw-rw-r--  1 fox fox   45 11月 27 21:28 test.txt
fox@fox:~/Documents/demo$ git co master new.log
fox@fox:~/Documents/demo$ git st
On branch fixbug
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)

new file:   new.log

fox@fox:~/Documents/demo$ cat new.log
git reset demo
用法四: 撤销工作区的修改:
fox@fox:~/Documents/demo$ echo "retort some demo" >> test.txt
fox@fox:~/Documents/demo$ git st
On branch fixbug
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:   test.txt

no changes added to commit (use "git add" and/or "git commit -a")
fox@fox:~/Documents/demo$ git co .
fox@fox:~/Documents/demo$ git st
On branch fixbug
nothing to commit, working directory clean


4 conclusion

this blog show some usage of git reset and git checkout, which can help us change the commit id the HEAD pointed to ,then we can cancel or renew some modifies on staging or workspace.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  git reset checkout