Git学习笔记:版本回退

版本回退

上一章我们学习了Git的基本操作通过,git log可以查看历史记录,git show查看提交日志的相关信息。

那么假如我今天不小心把不该提交的文件给提交了。也就是修改了本地的代码,然后使用:

git add file
git commit -m '修改原因'

执行commit后,还没执行push(把修改同步到远程仓库,后面讲)时,想要撤销这次的commit,该怎么办?

这时我们可以git reset命令,如下:

$git reset --soft HEAD^

这个命令撤销commit的修改并把修改的内容回到暂存区,测试如下:

codemaxi@codemaxi-PC:~/git_test$ git commit -m "test reset"
[master cb46378] test reset
 1 file changed, 1 insertion(+)
 
codemaxi@codemaxi-PC:~/git_test$ git log
commit cb463782fb1a62be5b95acf9ece72155c1cb99ae (HEAD -> master)
Author: codemaxi <374867193@qq.com>
Date:   Wed May 26 06:56:54 2021 +0800

    test reset

commit a8d38c4eca3245e489ef1684322e5a68c6265a8b (tag: v1.0)
Author: codemaxi <374867193@qq.com>
Date:   Sun May 23 22:08:15 2021 +0800

    direct commit without add

codemaxi@codemaxi-PC:~/git_test$ 
codemaxi@codemaxi-PC:~/git_test$ git status 
位于分支 master
无文件要提交,干净的工作区
codemaxi@codemaxi-PC:~/git_test$ git reset --soft HEAD^
codemaxi@codemaxi-PC:~/git_test$ git status 
位于分支 master
要提交的变更:
  (使用 "git reset HEAD <文件>..." 以取消暂存)

	修改:     test2.txt

codemaxi@codemaxi-PC:~/git_test$ git log 
commit a8d38c4eca3245e489ef1684322e5a68c6265a8b (HEAD -> master, tag: v1.0)
Author: codemaxi <374867193@qq.com>
Date:   Sun May 23 22:08:15 2021 +0800

    direct commit without add

我们上面的测试如下:

  1. 修改文件并commit文件
  2. 通过git status查看当前已经是干净的工作区,我们使用git reset --soft HEAD^回退commit
  3. reset后再使用git status查看发现文件已经被回退到暂存区。

当然如果想要完全回退版本也是可以的,我们看下下面这个命令:

$git reset --hard HEAD^

这个命令不单撤销commit的修改并把add也撤销,并且还会删除工作空间的改动代码,也就是执行后这个文件彻被还原,测试如下:

codemaxi@codemaxi-PC:~/git_test$ git commit -m "test reset"
[master 1af76cf] test reset
 1 file changed, 1 insertion(+)
codemaxi@codemaxi-PC:~/git_test$ git status 
位于分支 master
无文件要提交,干净的工作区
codemaxi@codemaxi-PC:~/git_test$ git reset --hard HEAD^
HEAD 现在位于 a8d38c4 direct commit without add
codemaxi@codemaxi-PC:~/git_test$ git status 
位于分支 master
无文件要提交,干净的工作区
codemaxi@codemaxi-PC:~/git_test$ 

以上就是–soft 和 --hard 的区别:–hard 会清空工作目录和暂存区的改动,而 --soft则会保留工作目录的内容,并把因为保留工作目录内容所带来的新的文件差异放进暂存区

那么有些人可能需要将版本回退,但是我不想把修改全撤销,想把修改的内容退回工作区,这样还可以继续修改然后再次提交,这时reset mixed命令就很好的满足你了,如下:

$git reset --mixed HEAD^

测试如下:

codemaxi@codemaxi-PC:~/git_test$ git add -A
codemaxi@codemaxi-PC:~/git_test$ git commit -m "test reset mixed"
[master 0fa84f9] test reset mixed
 1 file changed, 1 insertion(+)
codemaxi@codemaxi-PC:~/git_test$ 
codemaxi@codemaxi-PC:~/git_test$ git reset --mixed HEAD^
重置后取消暂存的变更:
M	test.txt
codemaxi@codemaxi-PC:~/git_test$ git status 
位于分支 master
尚未暂存以备提交的变更:
  (使用 "git add <文件>..." 更新要提交的内容)
  (使用 "git checkout -- <文件>..." 丢弃工作区的改动)

	修改:     test.txt

修改尚未加入提交(使用 "git add" 和/或 "git commit -a")
codemaxi@codemaxi-PC:~/git_test$ 

使用git reset --mixed重置位置的同时,只保留Working Tree工作目录的內容,但会将 Index暂存区 和 Repository 中的內容更改和reset目标节点一致,因此原节点和Reset节点之间的【差异变更集】会放入Working Tree工作目录中。所以效果看起来就是原节点和Reset节点之间的所有差异都会放到工作目录中。

reset 如果不加参数,那么默认使用 --mixed 参数。它的行为是:保留工作目录,并且清空暂存区。也就是说,工作目录的修改、暂存区的内容以及由 reset 所导致的新的文件差异,都会被放进工作目录。简而言之,就是「把所有差异都混合(mixed)放在工作目录中」。

下面就是reset三种模式最直观的区别:

  • –hard:重置位置的同时,直接将 working Tree工作目录、 index 暂存区及 repository 都重置成目标Reset节点的內容,所以效果看起来等同于清空暂存区和工作区。
  • –soft:重置位置的同时,保留working Tree工作目录和index暂存区的内容,只让repository中的内容和 reset 目标节点保持一致,因此原节点和reset节点之间的【差异变更集】会放入index暂存区中(Staged files)。所以效果看起来就是工作目录的内容不变,暂存区原有的内容也不变,只是原节点和Reset节点之间的所有差异都会放到暂存区中。
  • –mixed(默认):重置位置的同时,只保留Working Tree工作目录的內容,但会将 Index暂存区 和 Repository 中的內容更改和reset目标节点一致,因此原节点和Reset节点之间的【差异变更集】会放入Working Tree工作目录中。所以效果看起来就是原节点和Reset节点之间的所有差异都会放到工作目录中。

如果想要回退到其他版本可以如下:

HEAD         表示当前版本
HEAD^      上一个版本
HEAD^^    上上一个版本
HEAD^^^  上上上一个版本
以此类推...

也可以使用 ~数字表示

HEAD~0 表示当前版本
HEAD~1 上一个版本
HEAD^2 上上一个版本
HEAD^3 上上上一个版本
以此类推...

撤销修改

那如果我不是想回退版本,而是想撤销工作区的修改呢?可以用:git checkout -- file,测试如下:

codemaxi@codemaxi-PC:~/git_test$ echo "add four line, test checkout" >> test.txt 
codemaxi@codemaxi-PC:~/git_test$ cat test.txt 
test-second line
test files third line
add four line, test checkout
codemaxi@codemaxi-PC:~/git_test$ git status 
位于分支 master
尚未暂存以备提交的变更:
  (使用 "git add <文件>..." 更新要提交的内容)
  (使用 "git checkout -- <文件>..." 丢弃工作区的改动)

	修改:     test.txt

修改尚未加入提交(使用 "git add" 和/或 "git commit -a")
codemaxi@codemaxi-PC:~/git_test$ git checkout -- test.txt
codemaxi@codemaxi-PC:~/git_test$ 
codemaxi@codemaxi-PC:~/git_test$ git status 
位于分支 master
无文件要提交,干净的工作区
codemaxi@codemaxi-PC:~/git_test$ 

上面的情况是,我修改了文件,但是还未add到暂存区,使用git checkout -- <file>则是从版本库中还原文件,使文件跟版本库一致。
下面再来看看这种情况:

codemaxi@codemaxi-PC:~/git_test$ git status 
位于分支 master
要提交的变更:
  (使用 "git reset HEAD <文件>..." 以取消暂存)

	修改:     test.txt

codemaxi@codemaxi-PC:~/git_test$ 
codemaxi@codemaxi-PC:~/git_test$ cat test.txt 
test-second line
test files third line
test reset --mixed
codemaxi@codemaxi-PC:~/git_test$ echo "test workspace" >> test.txt 
codemaxi@codemaxi-PC:~/git_test$ cat test.txt 
test-second line
test files third line
test reset --mixed
test workspace
codemaxi@codemaxi-PC:~/git_test$ git status 
位于分支 master
要提交的变更:
  (使用 "git reset HEAD <文件>..." 以取消暂存)

	修改:     test.txt

尚未暂存以备提交的变更:
  (使用 "git add <文件>..." 更新要提交的内容)
  (使用 "git checkout -- <文件>..." 丢弃工作区的改动)

	修改:     test.txt

codemaxi@codemaxi-PC:~/git_test$ git checkout -- test.txt
codemaxi@codemaxi-PC:~/git_test$ git status 
位于分支 master
要提交的变更:
  (使用 "git reset HEAD <文件>..." 以取消暂存)

	修改:     test.txt

codemaxi@codemaxi-PC:~/git_test$ cat test.txt 
test-second line
test files third line
test reset --mixed
codemaxi@codemaxi-PC:~/git_test$ 

上面这种情况是

  1. 修改了文件并add到暂存区
  2. 再次修改文件,这时可以看到该文件在工作区和暂存区都有变更。
  3. 使用git checkout -- <file>回退该文件,我们查看文件内容发现该暂存区的内容一直而不是版本库的。

通过上面两种测试,总结git checkout -- <file>就是把工作区的修改全部撤销,至于撤销到哪个状态这里有两种情况:

  • file自修改后还没有提交到暂存区,这时使用撤销就会回到跟版本考一样的状态。
  • file修改后如果已经添加到暂存区,然后又做了新的修改,这时使用撤销则是回到根暂存区一样的状态。

总之,就是让这个文件回到最近一次git commitgit add时的状态。

好了,今天的内容就到这里了,下章我们再继续。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值