Git使用 - 回退到历史提交版本
描述
Git是个很好用的分布式版本库软件,这里总结一下如何将代码回退到想要的某个历史提交(commit)版本上。
实验
实验环境:
Ubuntu 14.04 64-bit
git version 1.9.1
1.建立一个实验的版本库,创建文件夹test_git_project
,运行git init
,创建一个空的git代码版本库
junyu@ubuntu:~/test/git/test_git_project$ git init
Initialized empty Git repository in /home/junyu/test/git/test_git_project/.git/
2.创建一个readme.txt,增加两行内容,每行内容为一次提交,结果展示如下:
junyu@ubuntu:~/test/git/test_git_project$ cat readme.txt
1. first line added
2. second line added
junyu@ubuntu:~/test/git/test_git_project$ git log
commit 082d72355e6f26fe44ad1ad235f91f4b546a7f39
Author: dengyao.dy <dengyao.dy@alibaba-inc.com>
Date: Sat Mar 12 16:47:17 2016 +0800
add second line
commit 2123c3804f2e7cedd60591d3162cb684a29cbf2d
Author: dengyao.dy <dengyao.dy@alibaba-inc.com>
Date: Sat Mar 12 16:46:13 2016 +0800
add first line
junyu@ubuntu:~/test/git/test_git_project$ git diff 2123c3804f 082d72355e
diff --git a/readme.txt b/readme.txt
index 41d08d5..df238de 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1 +1,2 @@
1. first line added
+2. second line added
其中,注意到,git在使用commit的版本序列号的时候不用使用完整的序列,直接使用开头的一部分就可以了。
3.现在是在增加了第二行的版本上,若想回到只有第一行的版本上,可以使用下面两种方法。
3.1 使用git checkout方法
第一行的版本的commit的序列号是2123c3804f2e7cedd60591d3162cb684a29cbf2d,所以我们直接使用命令
git checkout 2123c3804f2e7
junyu@ubuntu:~/test/git/test_git_project$ git checkout 2123c3804f2e7
Note: checking out '2123c3804f2e7'.
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 2123c38... add first line
但这里是detached HEAD state,查看分支情况:
junyu@ubuntu:~/test/git/test_git_project$ git branch -av
* (detached from 2123c38) 2123c38 add first line
master 082d723 add second line
可以看出,master仍然在最新的commit版本上,只不过相当于有一个临时分支,即detached from xxxx分支,不过可以通过checkout命令生成一个新分支,这个新分支就在你想回退的版本上,如下面命令行所示,从一个临时分支创建出了一个新的only_one_line
分支,这个新分支的代码版本就在add first line
这个commit上,即实现了代码版本的回退,同时还保留了master的最新版本:
junyu@ubuntu:~/test/git/test_git_project$ git checkout -b only_one_line
Switched to a new branch 'only_one_line'
junyu@ubuntu:~/test/git/test_git_project$ git branch -a
master
* only_one_line
junyu@ubuntu:~/test/git/test_git_project$ git status
On branch only_one_line
nothing to commit, working directory clean
junyu@ubuntu:~/test/git/test_git_project$ git log
commit 2123c3804f2e7cedd60591d3162cb684a29cbf2d
Author: dengyao.dy <dengyao.dy@alibaba-inc.com>
Date: Sat Mar 12 16:46:13 2016 +0800
add first line
junyu@ubuntu:~/test/git/test_git_project$ cat readme.txt
1. first line added
其实,这个使用git checkout commit_id
等效于使用git checkout --detech commit_id
。
3.2 使用git reset命令
若想将当前分支回溯到历史某个版本,而不需要另起分支,则可以使用git reset命令,比如下面将master完全恢复到前一个版本:
junyu@ubuntu:~/test/git/test_git_project$ git reset --hard HEAD^
HEAD is now at 2123c38 add first line
junyu@ubuntu:~/test/git/test_git_project$ cat readme.txt
1. first line added
可以看出,使用reset指令,加上–hard选项,成功的将版本库恢复到上一个版本,即readme.txt只有1行文本了。上述命令中有个HEAD
,HEAD
是表示当前版本库指向的commit版本,它是一个代码版本指针,HEAD^
表示上一次commit的版本,同理HEAD^^
表示上上一次commit的版本,若表示上100次提交的版本,则使用HEAD~100
。当然,这里不用HEAD^
也可以使用commit的序列号来代替的。
这时,使用git log
命令看一下:
commit 2123c3804f2e7cedd60591d3162cb684a29cbf2d
Author: dengyao.dy <dengyao.dy@alibaba-inc.com>
Date: Sat Mar 12 16:46:13 2016 +0800
add first line
发现,原来的第二次提交不再git log里的了,那如果后悔了,想重新恢复最新的提交怎么办呢,没关系,使用git reflog
指令,它能看到,你的HEAD指向过的所有的commit版本,这些可还是保留在本地版本库中的:
junyu@ubuntu:~/test/git/test_git_project$ git reflog
...
...
082d723 HEAD@{10}: checkout: moving from 2123c3804f2e7cedd60591d3162cb684a29cbf2d to master
2123c38 HEAD@{11}: checkout: moving from master to 2123c3804f2e7ce
082d723 HEAD@{12}: commit: add second line
2123c38 HEAD@{13}: commit (initial): add first line
看到082d723 HEAD@{12}: commit: add second line
这一行,082d723
就是它的commit id,我们再使用一次git reset
命令就能恢复了:
junyu@ubuntu:~/test/git/test_git_project$ git reset --hard 082d723
HEAD is now at 082d723 add second line
junyu@ubuntu:~/test/git/test_git_project$ git status
On branch master
nothing to commit, working directory clean
junyu@ubuntu:~/test/git/test_git_project$ git log
commit 082d72355e6f26fe44ad1ad235f91f4b546a7f39
Author: dengyao.dy <dengyao.dy@alibaba-inc.com>
Date: Sat Mar 12 16:47:17 2016 +0800
add second line
commit 2123c3804f2e7cedd60591d3162cb684a29cbf2d
Author: dengyao.dy <dengyao.dy@alibaba-inc.com>
Date: Sat Mar 12 16:46:13 2016 +0800
add first line
junyu@ubuntu:~/test/git/test_git_project$ cat readme.txt
1. first line added
2. second line added
所以,基本就是这样了。