看到这篇标题是不是有种很叼的感觉!?在Git的工作流程中,不仅能往前走,当然也可以后退。不仅能提交
文件,当然也能删除或者修改了。而且你想回到哪个提交节点就回到哪个提交节点,
是不是觉得自己体内的洪荒之力快抑制不住了?
别急,容我短话长说,一一道来。
在这真正讲这些也需要普及一个概念:工作区和暂存区
工作区和暂存区
如果有同学对这些概念感觉很懵逼,也没什么关系,不影响你的使用,只要扫一眼接下来的两个标题,
就不会影响理解这篇的内容了。
另外如果有同学想深入理解这个概念的原理,可以自行去Google搜一下。
工作区
比如你正在写代码,那么你当前的编译器界面的那些代码都属于工作区里的。
暂存区
当你在你的git工程里创建了一个新文件,并且执行了git add [File Name]
,
那么这个新的文件就都被add进了暂存区。
在已经提交过的代码里做修改,还不在暂存区,执行git status
,会发现这些修改过的文件提示需要add,add后会进入暂存区。
当你执行commit的时候,就是把暂存区的代码一次性提交到本地版本库上。
技能树
reset
reset这个词从翻译上来说叫做重置,我觉得用回档这个词比较好理解,每次commit都会有个log记录,相当于游戏中的存档啦,然后你可以使用reset,回档到某个记录。
几个常用的方式
git reset [HEAD] [FileName]
我经常用到这个命令,因为我在提交时,总是不小心把某些写到一半的文件也顺手给提交上去了。
先不说效果是什么,给你们演示一下:
先把之前修改的提交了:
修改一下工作区的代码,再执行git diff
查看当前修改了什么:
然后执行git log
查看我们当前的提交日志:
用红色标起来的就是[HEAD] ,看下面的”test for reset commit”,是我们刚才提交的,所以需要的下面那个HEAD。
执行 git reset ebd535064bd1b2a2739b40c3a9356ce4c0fd6cba app/src/main/java/heh/MasterCodeTest.java
:
在执行git diff
,看到这次的结果和之前第一次diff不同:
以上操作只是回档某个文件,所以log并不会变。
我每次提交不小心带上了些不该提交的文件,就用这个命令撤销一些提交。
git reset [HEAD]
如果执行的时候不带最后个[fileName],那么所有文件都会回到那次提交的节点。
如果直接执行 git reset ebd535064bd1b2a2739b40c3a9356ce4c0fd6cba
再执行git log
,看到刚刚我们提交的”test for reset commit”已经没了:
刚才所有的reset都只是把head指向了当前branch的指定commit仅此而已,可以执行git status
,发现还是需要把修改add到暂存区。
默认的都是不写模式 – mixed 模式
git reset –hard
这个用法和刚才的类似,就是多了个–hard,意味着你工作区的代码也会回档,和暂存区保持一致,都回到了那个节点的commit时的状态。
git reset –soft
–soft,意味着工作区不会收到影响,并且修改的文件也进入了暂存区,执行git status 发现没有东西需要add到暂存区。
revert
憋着急,先往下看,最后会解释的。
执行 git revert ebd535064bd1b2a2739b40c3a9356ce4c0fd6cba
代码会出现冲突的现象,因为两次结果不一样:
合并完代码,add再commit会出现如下提示:
revert 和 reset 的功能是类似的,区别就是revert不会改变log,而reset会撤销log。
revert需要一个新的commit记录这次revert。如果没冲突,那么会自动commit;如果有冲突,则会需要解决冲突后手动commit
一句话总结就是revert只是撤销某次commit,其他的commit和整个log记录不会受到影响,而reset会干掉某次commit之后的所有commit,包括log。
checkout
在上一节的分支操作里也讲过这个命令,是切换分支用的,而在这里将会讲解用checkout命令起到撤回的作用。
git checkout [fileName]
或者git checkout -- [fileName]
在提交过的文件里随便新增一行,然后在命令行中输入git status
会出现如下图所示:
说明当前修改还未进入暂存区,还是在工作区,这个时候执行git checkout [你的文件绝对路径]
:
为什么用绝对路径呢,就是避免你的文件名和branch名一样,结果就切换到分支上了。加上 – 后面的就一定是文件了
git checkout [commit] [fileName]
该命令就是将某个文件的暂存区和工作区都回撤到某个commit节点上。
git checkout .
注意到 checkout 后面有个”.”,就是代表所有文件的意思把所有文件都撤回刚才在工作区上的改动。
log
这个命令在之前的例子总经常用到,就是看提交日志用的。
之前从同事那边学来一条黑科技命令:
git log --oneline --decorate --graph --all
用一下就知道效果了,不了解里面参数的执行git log --help
查看文档。
rm
这个命令linux中也有,就是删除文件或者移动的意思。
在git中也是这个意思。
如果你在本地物理删除了一堆文件,但是没有执行git rm
,那么其实这些文件还是在git系统里的,在git project中直接执行git rm
删除要你删的文件,提交之后就可以完成删除了。
总结
写到这里把git的回撤、查看的功能都写完了,大家应该也有一个比较系统的认知了,具体还是需要多在项目中应用。
希望大家能一起讨论,共同学习进步!