时光一去不复返,我们都知道的道理,但是在git的世界里.我们可以很轻松的回到过去.
要想随意的将代码切换到过去的某一个版本,那我们肯定要先熟悉的一个命令就是查看历史,git log。
默认情况下,会根据提交时间列出提交历史。每一个历史都会有一个ID,该ID是一个SHA1计算的值,用16进制表示的。
如果想看最近的两次记录可以添加 -2 参数。如果你想看每次提交修改的内容可以添加 -p 参数如果历史太多,第一次使用的时候会发现,怎么退出不了。这时你就可以直接按q键就退出来了。
别的参数自己可以去看看git官网。接下来我们开始时空穿梭吧!
在之前的分享中,我们介绍了git的几个区。我们先根据这几个区来分别说一下,怎么进行回滚
工作区。
工作区相对比较简单,我们可以用git checkout 来回滚(这里我们用撤销感觉能好一点)
git checkout test1.txt // 撤销指定文件git checkout . //撤销整个工作区,后面不要忘记有个点的哦
这样就结束了么?NO!我们来看看能不能撤销到指定版本。首先我们先提交三个版本到远程分支上。
echo "submit 1" >test1.txt echo "submit 1">test2.txt git commit -m"提交1" test1.txt test2.txtgit push origin masterecho "submit 2" >test1.txtecho "submit 2">test2.txtgit commit -m"提交2" test1.txt test2.txtgit push origin masterecho "submit 3" >test1.txtecho "submit 3">test2.txt git commit -m"提交3" test1.txt test2.txtgit push origin master
然后git log查看一下提交记录
git log
我们可以看到我们提交的两次记录,现在我们是在提交3那个版本。我们要回到提交1那个版本怎么做呢?
git checkout 'commit id' test1.txt // 回滚一个文件git checkout 'commit id' . // 回滚整个工作区
如果你不想回去了,还是想朝前看,那你就可以
git checkout HEAD test1.txt git checkout HEAD .
他是回滚到HEAD指向的那个提交。(HEAD是一个指针,指向的是当前本地分支的最头上的那个提交)
其实,我们可以看出来,我们此次的回滚,修改的记录直接给我们放在暂存区,那上面的问题也可以当成如何回滚暂存区的代码?下面我们会说到这个问题.各位看官,不要着急
git checkout [commit id] 不算是版本的回滚,只能说是代码的回滚。文件变成了指定版本的文件内容。但是版本号还是没有变化的。
如果我们不加文件名,只用git checkout [commit id] 呢?这个就是另外一番景象了.
这样我们可以看出来,这其实是从你的commit id,分离出了一个新的相当于临时分支的东西,你可以在这个分支上做任何正常的操作.但是你切换到别的分支.当前分支的修改也会丢失.你当然也不可能push的到远程仓库的.
但是你可以从当前的临时分支创建一个新的分支出来.这样就可以保存临时分支中的所有修改.个人理解,这个命令就是从一个指定的版本创建出一个分支.平常我们创的分支都是从当前HEAD创建的一个新的分支.如果工作区或者暂存区有修改,会终止操作的.
暂存区
暂存区,是我们工作区add进的。通过上图,我们可以发现,人家已经跟你说怎么回滚了。对!你没想错,就是
git reset HEAD
这个操作仅是将暂存区的修改,撤回到了工作区,在工作区,你还需要
git checkout
来撤销修改
这块看起来还比价简单,那接下来我们看看我们commit后的怎么来回滚吧
commit
这个应该真正的算是版本回滚了
我们再修改一下工作区,并提交到本地分支
echo "submit 4">test1.txtgit commit -m"提交4" test1.txtgit log
此时我们可以看到我们刚才提交的记录
然后我们还是使用
git reset HEAD^ // HDEA^表示的是前一个分支,HEAD^^标识前连个分支.你也可以用HEAD~数字表示前几个分支,可以代替具体的commit idgit log
我们可以看到,上面的的提交记录的第一条没有了,这样就实现了版本回退.你本地版本回退了,但是跟远程仓库不能保持一致了.所以你在本地修改了,要想提交就有可能出现冲突.冲突是可以解决的,但是冲突多了就很烦了呀.
不是很建议在本地的开发环境进行版本回退.建议在生产环境使用.通常是某个人代码引起了事故,一时半会还解决不了.只能先回退,等解决了,再更新成最新的.
当然你能回退,可能还是能撤销回退的.你想撤销,你要知道最开始的那个commit id,然后git reset 就可以了.不能用HEAD代替了.此时HEAD的指针,已经指到你回退的那个版本了.
这个还可以加几个参数
git reset --soft HEAD^ // 回退后,撤销了commit,保留暂存区的git reset --mixed HEAD^ //(和不加参数是一样的效果) 回退撤销了commit,撤销暂存区的后,保留在工作区git reset --hard HEAD^ // 回退后,撤销commit,撤销暂存区,撤销工作区的
通常我们修改的代码不知不觉丢了,应该就是使用了git reset --hard来回退代码.我这里还可以分享一个小技巧,IDE有个本地历史记录可以使用哦
其实呢,还有另外一个命令git rever操作.这个能不能算是版本回退,应该叫版本向前.他是把以前的一个版本弄成一个新的提交
我revert的那个版本跟我们当前有冲突,解决了一下冲突
然后我们git log看一下
可以看出来我们的版本是向前提交了一个记录.
这种操作也要慎用呀,最好是不要用,尤其是多人协作工作的时候(你要是自己一个人,随意折腾),因为这样会把你回滚那个版本后面所有的提交都给覆盖了,如果你直接提交到线上了.那别人写的代码也会消失了,这个损失.就无法估量了.一定要慎用.
总结:
看完是不是觉得版本回滚很容易呀.做一个时空穿梭者是不是很爽呢.其实这个代码回滚是我想写这一系列的初衷,后面想了想,中间还有很多细节不了解.所以才决定从头到尾学习分享一下.虽然不是那么详细,感觉应对工作中的大部分问题足够了.