?????有自己思想,拒绝纯复制黏贴!!!
??????有自己思想,拒绝纯复制黏贴!!!
???????有自己思想,拒绝纯复制黏贴!!!
???????这里说个题外话,现在网上有一种现象让我深恶痛绝,就是很多网友对别人所发的博文不加验证,便进行纯复制转发,我很想知道,转发了之后意义在哪?自己都没有去验证所转发的内容是否有效便进行纯复制转发,你们这是在污染网络环境,每次我遇到问题,网上一搜,搜索引擎前面几页一模一样的答案,而且还不是有效的博文,看着这些千篇一律的东西,真的是让我抓狂!!!小小吐槽一下
----------------------------------------------------------------------------------以下是正文-----------------------------------------------------------------------------------
一、背景
???????回退版本是Git的另一重要功能,特别常用,同样需要我们熟练掌握,用好了,可以在不用历史版本来回穿梭,省时省力,让我们不用为了实现同一功能重复编码。 ???????由于涉及工作区、暂存区、本地仓库和远程仓库,所以回退版本有多种实现方式,效果会有些许不同。所以我们要根据需求选择合适的方式进行回退,比如有时候我们只是想要工作区回退到某个版本,但暂存区、本地仓库和远程仓库不回退;有时候我们想要让工作区、暂存区、本地仓库和远程仓库全部回退到某个版本;等等。 ???????我们创建一个GitTest项目,里边只有一个test.txt文件,进行过三次提交推送,提交推送信息如下: ???????第一次提交推送,test.txt文件的内容为“0000000000???????第一个版本”, ???????第二次提交推送,test.txt文件的内容为“1111111111???????第二个版本”, ???????第三次提交推送,test.txt文件的内容为“2222222222???????第三个版本”,
二、模拟场景
0、第零种 git checkout
- - - git checkout [commitId] ???????我们先说一下这个命令git checkout [commitId],它的作用不是回退版本,准确来说应该是从某个历史版本检出到工作区,而本地仓库和远程仓库没有变化。 ???????比如,我们想检出到第二个版本,操作如下, ???????工作区已变成第二个版本, ???????从上面几张图你们就可以看到,HEAD指针已经移动到了第二个版本上,工作区的内容也变成第二个版本了,不过本地仓库master指针和远程仓库origin/master指针没有变化,依旧在第三个版本上,而且使用这个命令会使HEAD指针处于游离状态(想了解游离状态的小伙伴可到该系列的第一篇(总结篇:Git使用总结)查看),这便是这个命令的效果。 ???????之后,可以使用命令git checkout master回到最新的提交,离开游离状态,回到正常的轨道。注意,想回到正常轨道,使用git check 3bb1900是不行的,它依旧是游离状态,IDEA的黄标签旁边的感叹号应该就是游离状态的意思。有人可能觉得3bb1900不是最新提交(第三个版本)的commitId吗?应该跟命令git checkout master是一个效果呀?感觉是?但我们还是得按事实说话,看下图, 延伸:当我们git checkout到第二个版本后,我们用git log查看提交信息,却看不到第三个版本的提交信息,所以我感觉,git log这个命令应该是查看HEAD指针当前所指的版本以及之前的版本,之后的版本查看不到,所以想查看HEAD指针之后的提交信息,可以使用命令git reflog。 ???????真正用于版本回滚的是接下来的这两种命令git reset和git revert。
1、第一种 git reset
- - - git reset —— 回退版本,将HEAD指针和本地分支指针往前移并删掉后面的版本 ???????git reset有三种模式:mixed、soft和hard。 ???????测试这三个模式之前,我们先布置一个初始状态。项目初始状态是处于最新提交Commit3, ???????且我们在工作区对test.txt文件的内容进行修改,如下, ???????以上便是初始状态,运行以下三个命令都是分别从这个初始状态开始的。 ???????说明:在Git中,HEAD表示当前版本,上一个版本用HEAD^表示, ?????????????????上上一个版本就是HEAD^^, ?????????????????当然,往上100个版本就写100个^,不过这样太麻烦累赘,所以我们也可以用另一种写法,即HEAD~100, ?????????????????当前版本就用HEAD~0。 ?????????????????那么,以我们这个案例来说就是,第一个版本(3478bab)对应HEAD^^或HEAD~2, ???????????????????????????????????????????????????????????????????????第二个版本(eb11af5)对应HEAD^或HEAD~1, ???????????????????????????????????????????????????????????????????????第三个版本(3bb1900)对应HEAD或HEAD~0,即最新提交的版本是当前版本。 ???????注意:因为要查看暂存区内容,防止做这三个测试的时候版本窜了,下面三个命令我打算建三次项目和三次远程仓库来测试,他们初始状态全部都一样,唯独三个提交记录的commitId会不一样,放心,我会在每一块前面说明好。 ???????① --mixed(默认,可省略不写) ???????这块测试的提交版本号为第一个版本(533bfa9)、第二个版本(57965be)、第三个版本(c4cfe71), ???????回退前,我们先看一下暂存区的内容, ???????此时,我们开始用这个模式回退到第二个版本,操作如下,相当于命令git reset --mixed HEAD^或者git reset --mixed HEAD~1或者git reset --mixed 57965be, ???????回退后的结果如下, ???????结果:工作区最新修改且未添加到暂存区的内容没有被清掉;暂存区的内容回退到了第二个版本;HEAD头指针和master本地分支指针移动到了第二个版本,origin/master远程分支指针没变化,还在第三个版本那里。 ???????② --soft ???????这块测试的提交版本号为第一个版本(7c29d81)、第二个版本(f7fe33f)、第三个版本(65be711), ???????回退前,我们先看一下暂存区的内容, ???????这里我们用这个模式回退到第一个版本,使用命令git reset --soft HEAD^^或者git reset --soft HEAD~2或者git reset --soft 7c29d81, ???????回退后的结果如下, ???????结果:工作区最新修改且未添加到暂存区的内容没有被清掉;暂存区的内容没有回退,依旧是第三个版本的内容,这样暂存区跟本地仓库就不一致了,所以我们用git status查看状态时就提示有文件未提交(暂存区这块也可以这样理解,就是暂存区也回退到了第一个版本,只是原来的最新版本在回退版本之后紧接着就被暂存在暂存区里了,这样就符合IDEA的那段解释“差异将被暂存以便提交”);HEAD头指针和master本地分支指针移动到了第一个版本,origin/master远程分支指针没变化,还在第三个版本那里。 ???????③ --hard ???????这块测试的提交版本号为第一个版本(79fe18b)、第二个版本(90fdc15)、第三个版本(f2a53db), ???????回退前,我们先看一下暂存区的内容, ???????这里我们用这个模式同样回退到第一个版本,使用命令git reset --hard HEAD^^或者git reset --hard HEAD~2或者git reset --hard 79fe18b, ???????回退后的结果如下, ???????结果:工作区最新修改且未添加到暂存区的内容被清掉了,替换成了回退到的那个版本的内容;暂存区的内容回退到了第一个版本;HEAD头指针和master本地分支指针移动到了第一个版本,origin/master远程分支指针没变化,还在第三个版本那里。
最终总结: ???????1)、使用–mixed和–soft可以不用太过慎重,但使用–hard就要慎重、慎重、再慎重,因为用–hard这种模式去回退版本,是会把你工作区最新修改且未添加到暂存区的内容给清掉的(虽说也有方法可以抢救,但还是比较繁琐的,所以慎重一点好,相比不慎重再去抢救要简单得多) ???????2)、用上面命令进行版本回退后,结果是只回退了本地仓库的,若想让远程仓库也同步回退,只需要将本地仓库push上去即可,这里要注意,普通push会操作失败,需要强制push才行。 ???????3)、使用三个模式的结果 ???????初始状态,工作区内容在第三个版本前提下进行了修改,暂存区、本地仓库和远程仓库都在第三个版本那; ???????–mixed,回退到第二个版本,结果是工作区最新修改且未添加到暂存区的内容没有被清掉;暂存区的内容回退到了第二个版本;HEAD头指针和master本地分支指针移动到了第二个版本,origin/master远程分支指针没变化,还在第三个版本那里。 ???????–soft,回退到第一个版本,结果是工作区最新修改且未添加到暂存区的内容没有被清掉;暂存区的内容没有回退,依旧是第三个版本的内容,这样暂存区跟本地仓库就不一致了,所以我们用git status查看状态时就提示有文件未提交(暂存区这块也可以这样理解,就是暂存区也回退到了第一个版本,只是原来的最新版本在回退版本之后紧接着就被暂存在暂存区里了,这样就符合IDEA的那段解释“差异将被暂存以便提交”);HEAD头指针和master本地分支指针移动到了第一个版本,origin/master远程分支指针没变化,还在第三个版本那里。 ???????–hard,回退到第一个版本,结果是工作区最新修改且未添加到暂存区的内容被清掉了,替换成了回退到的那个版本的内容;暂存区的内容回退到了第一个版本;HEAD头指针和master本地分支指针移动到了第一个版本,origin/master远程分支指针没变化,还在第三个版本那里。
2、第二种 git revert
- - - git revert —— 回退版本,创建之前的版本到后面 特别注意:本人建议,不要在工作区有未提交到本地仓库的最新修改情况下进行git revert操作,不然会卡在REVERTING。我一开始就是在这种情况下进行git revert,然后就一直卡在master|REVERTING,用命令git revert --continue之后又会报错,我不知道如何处理了,如果你知道如何操作,那就忽略我这个建议,顺便在评论区跟我说一下处理方式,不胜感激,抱拳! ???????我们先布置一个初始状态。项目初始状态是处于最新提交Commit3, ???????以上便是初始状态,运行以下命令是从这个初始状态开始的。 ???????这块测试的提交版本号为第一个版本(052ca89)、第二个版本(234064f)、第三个版本(193bc82), ???????那么,现在我们将版本回退到第一个版本,操作如下, ???????紧接着就会弹出冲突窗口,我们点击“Merge…”按钮, ???????在弹出的窗口不修改,直接点击“Apply”按钮, ???????然后,会弹出这个窗口,如下, ???????可以直接点击“Commit”按钮,或者你想远程仓库一并同步,也可以点击“Commit”按钮旁边的三角,接着点击其下拉框的“Commit and Push…”按钮便可以了。 ???????说明:这里的推送只是普通推送,不需要强制推送,因为我们的提交记录是往后的,而git reset是往前的,它们原理不一样。用git reset回退版本,之后的版本我们会看不到,但用git revert回退版本,所有的版本都会有记录,都能查看得到,这种方式回退版本是比较推荐的。 ???????回退后的结果如下, ???????结果:工作区回退到第一个版本的内容;暂存区的内容也回退到了第一个版本;HEAD头指针和master本地分支指针移动到了第一个版本,origin/master远程分支指针没变化,还在第三个版本那里。上面的图之所以显示origin/master远程分支指针在第一个版本那里,是因为我在提交的时候选择的是“Commit and Push…”按钮。
???????好了,本系列内容到此就结束了,感谢观看!!! |=============================================================================|
【IDEA Git系列(共x篇)】文章清单
总结篇:Git使用总结 第1篇:Git和Gitea介绍、建立远程仓库以及推送和下拉代码 第2篇:提交代码时提示冲突如何处理 第3篇:如何回退版本(此时在这里) |=============================================================================|
|