本篇文章主要是基于Android Studio(IDE)下研究git版本回退的五个参数的使用方法,当然其它职业的开发着也可以进行部分借鉴.
当我们用git不小心提交了一次错误的内容的时候,我们就可能会想到要进行版本回退.这时候我们就会使用到git reset命令.
在说git reset命令之前,我们先需要了解一下git的三个工作区域.
那分别是
1.刚开始 working tree 、 index 与 repository(HEAD)里面的內容都是一致的
2.当git管理的文件夹里面的内容出现改变后,此時 working tree 的內容就会跟 index 及 repository(HEAD)的不一致,而Git知道是哪些文件(Tracked File)被改动过,直接将文件状态设置为 modified (Unstaged files)。
3.当我們执行 git add 后,会将这些改变的文件內容加入 index 中 (Staged files),所以此时working tree跟index的內容是一致的,但他们与repository(HEAD)內容不一致。
4.接着执行 git commit 後,將Git索引中所有改变的文件內容提交至 Repository 中,建立出新的 commit 节点(HEAD)后, working tree 、 index 與与repository(HEAD)区域的内容 又会保持一致。
当我们了解了git的三个工作区域之后,我们再来了解一下Android Studio自带的插件是如何操作 git的.
首先我们在控制台中输入git init的时候,我们会发现,所有的文件都变为咖啡色.
这代表当前文件在Working Tree.
当我们执行 git add . 的时候,我们会发现这些文件全都变成了绿色.
这代表文件开始进入了Index/Cache 暂存区域,同时表明Repository区域没有这些文件.顾名思义,暂存区的文件就是即将要提交的文件.
接下来我们执行 git commit -m “this is a commit”,我们会发现文件变成了黑色.
这代表文件已经进入Repository工作区域了,即git仓库,并且有了一条提交记录,同时还说明,Working Tree和Index/Cache与Repository的内容是一致的.
最后我们执行 git push 推送到远程仓库即可.
后面的提交都是重复上述1-4步操作,但是当我们使用Android Studio自带的git工具提交的时候,为了方便,Android Studio会将git add 和git commit 一起打包操作.提交界面如下:
当我们了解了git的三个工作区域之后,我们再来详细解释一下git reset --soft --mixed --hard --merge --keep 这五个参数的区别.
首先我将–soft --mixed --hard --merge --keep分为两大类
--mixed 和–soft其实区别并不大,它们都是较为安全的版本回退操作.首先它们都会将之前的提交记录删除,同时保留之前提交记录的内存.
它们的不同在于–mixed操作会将之前的提交记录全部退回到Working Tree.中,而–soft会将提交记录的内容全部退回到Index/Cache中.
比如我新加了一次提交,新增了Test2文件.
当我使用git reset --mixed的时候它是这样的
可见提交记录没了,版本回退了,原来修改的内容退回到了Working Tree中.
当我使用git rest --soft的时候它是这样的
可见提交记录没了,版本回退了,原来修改的内容退回到了Index/Cache中.
--hard可能是我们使用较为频繁的一个参数了,但它回退之后,我们在后面提交的内容都会“不复存在”了.但为了尽量挽回损失 ,–merge,–keep,稍微改进了一下,它们并不会撤销所有提交的内容.它们只会撤销后面新增的文件.而对于待退回分支中已有的文件,它们则会保留改动记录.并且将它们退回到working Tree中.
比如我现在新增了一次提交:新增了Test2,同时改动了Test,但并未提交.如下
Test改动如下,新增了一条注释
当我使用 git rest --hard的时候,效果 如下
可见,提交记录回退了,并且之前所有的提交记录都清除了.Test中的改动也一并清除,Test文件变成了黑色.此时三个工作区保持一致了.
那么如果我用git reset --merge有什么效果呢?
我们会发提交记录回退了,但是并没有全部回退,“this is a commit”这次提交中包含的文件如果被改动了,它不会被回退.只有"this is a commit"中没有的文件,才会被回退掉.
那么如果即改动了Test也改动了Test2,这时候如果我进行版本回退会出现什么情况呢?
答案是会回退失败.
这是因为merge对,Index/Cache中的文件有保护作用,我们可以从官方文档中找到解释.
翻译过来就是:
重置索引,并删除HEAD与待退回的版本之间不同的文件(如上面的Test2文件),前提是那些不同的文件在Working Tree中没有缓存.但是会保留那些HEAD与之间相同的文件的改动内容,并将改动记录放入Work Tree中.如果HEAD与之间不同的文件,在Working Tree中有缓存,(即改了内容,但没提交,比如我刚刚改了Test2但没提交),那么这次操作就会终止.
但是如果我在提执行git reset --merge之前,执行一下 git add. 将WorkTree中Test2的修改内容移至到Cache中,那么本次回退就会成功了,读者可以尝试一下.
那么接下来我们再看 git reset --keep的效果.
在Android Studio中 执行 git reset --keep的效果其实和git reset --merge效果是一模一样的.唯一与–merge细微的差别就是,如果是–keep,即使使用了git add . 再执行git reset --keep,回退操作也会被终止. 我们从官方说明中也可以找到答案
第二句的意思就是,如有有一个文件是中没有,而HEAD中有的,只要你发生了改动,无论是在Working Tree中还是Cache中,操作都会终止.
由于Android Studio提交时简化了操作,git add 和git commit 会被打包执行,这也是为什么Android Studio自带的工具中回退选项只有四个选项的原因.
好了,五个参数的就介绍到这.小伙伴有没有理解呢.
部分内容转载自https://www.jianshu.com/p/c2ec5f06cf1a
如果任何疑问,请联系邮箱:[email protected]