Git使用问题(一)

Git使用问题(一)

1.前言

感觉要被Git魔法搞糊涂了,之前也曾系统的学习过Git, 但是当时只是走马观花的过了一遍,也没实践,看着尚硅谷老师的演示,感觉这玩意实在太草了,然后听完就过去了,之后也是遇到过很多使用上面的问题,但是按照网上的教程一步步解决之后,就没有继续深究,这样是不行滴,下面总结几个最近遇到的问题

2.git add git commit git push

这三个操作一直经常使用,但只是本本分分、老老实实的顺序执行这三个命令,不敢耍什么滑头,生怕出错,但是今天突然想到,为什么commit之前总是要进行add操作,没有不行嘛?add之后文件到了哪里?为什么要将一次推到远端的操作分成三部?

要想了解这三个操作的区别以及实现原理,那么就需要了解Git的内部结构:

图片来自:https://juejin.im/post/6844903603694469134

image-20200907143710853

image-20200907143738843

可以看出,内部结构一共存在三个组成部门,分别是:

  • 工作区
  • 暂存区
  • 本地仓库

git add是将代码从工作区提交到暂存区,git commit是将代码从暂存区提交到本地仓库,git push是将本地仓库的代码提交到远端仓库

回答上面的问题,没有add直接进行commit不行嘛?

实践出真知,我对工作区的内容进行修改,不执行add,直接进行commit:

image-20200907133415257

注意标记的内容,大概意思就是修改没有被暂存起来以备提交,所以修改一定要提交到暂存区才能被commit

说了这么多,为什么要有暂存区?也就是为什么要将一个提交代码的操作分三步进行?因为目前我遇到的场景还不多,结合自己的体会以及网上的答案,主要有以下几点原因:

  • 将commit粒度细化

    解释一下,将每次commit的内容进行细化是一个比较好的习惯,这样当出现问题想要进行版本回滚的时候,可以非常具体的定位到某一次提交,而目前假如说有这么一种情况,我在工作区新增的代码特别多,而且属于两个功能,跨度比较大,这时候我们可以先将一个功能的代码进行add操作提交到暂存区,然后再进行提交,接下来的一个功能完成之后进行同样的操作,这样就可以达到目的。

  • 配合stash进行代码的临时保存

    我想这种情况以后一定会经常遇到,假如说目前你在一个分支上开发新的功能,但是另外一个分支上面的代码出现了问题,优先级比较高,这时候需要你进行紧急修复,但是目前分支上面的代码还没有完成,你总不能提交上去一个半成品不是,这时候就可以使用git stash命令将内容保存到暂存区,这时候工作区就是干净的了,切换到其他分支进行修改提交之后,再切换到目前分支,执行git stash pop,就可以将暂存区的代码重新拉取回来,继续没完成的工作!

  • 忘记切换分支

    可能还有一种情况就是你开发的时候忘记切换分支了,这时候可以使用git stash & git checkout进行改动

总结起来就是,暂存区赋予了Git更大的灵活性,在计算机领域的问题中,我发现往往在两个东西之间再加上一些什么,往往会起到一种事半功倍的效果,暂存区就是,缓存也是,可能这就是一种中间件的思想吧,致敬Linus Torvalds大神!

3.git reset git diff

完成了上面内部结构的区分之后,这两个命令就方便多了,主要就是参数的使用问题

表格来自:https://blog.csdn.net/qq_32452623/article/details/78417609

image-20200907140803796

image-20200907140845435

4.git merge git rebase

最后这个问题,也是我在面试中被问到的问题,这两个命令之间的区别???

总的来讲,这两个命令都是用来合并代码的,但是需要根据具体的场景选择使用哪种方式,下面进行一个比较:

图片参考:https://www.jianshu.com/p/cca69cb695a6

从master拉下来一个mywork分支进行开发,此时其他开发者提交了新的代码到主分支:

image-20200907154314006

使用merge的方式进行合并:

image-20200907154343196

使用rebase方式进行合并:

image-20200907154424350

可以很明显的看到的区别就是,rebase直接将mywork分支的commit追加到了master分支后面,rebase,官方说法叫变基,也就是重新定位的意思,使用这种方法进行代码的合并,分支更加清晰简洁,而使用merge方法继续宁合并,可以发现每一次合并时候都会产生一个merge commit,也就是C7,当合并次书非常多的时候,这种“无用”的commit就会变多,影响分支简洁和清晰

即使使用rebase可以保证我们的分支commit是线性的,但是有一个问题,就是rebase这种方法会改变提交历史,从上面的图片可以看出,变基过程中,拼接到C4后面的C5'、C6‘都是mywork分支中C5、C6的副本,可能会改变SHA-1值

总结起来就是还是要根据具体的场景来选择哪种合并方式,如果要保证最纯粹的提交历史,还是使用merge比较好。如果提交历史改变这一点可以容忍,那么rebase也没问题

5.这是结尾

越来越觉得,Git真的是一个大学问,正所谓“工欲善其事必先利其器”,在实习期间我也出现过没有使用明白Git,在进行merge的时候将其他人的代码搞丢了的情况,另外也出现过代码不合理进行回滚的情况,如果要是能够熟练的使用Git,确确实实是一个不错的本领,这篇文章的标题我加上了一个“一”,也算是Git系列的第一篇文章吧,相信后面的使用过程中还会出现各式各样的问题,我会开设一个专栏,专门用来记录Git的问题~

See you next bolg!