新人入职手册之git

第一步,把代码拉到本地(clone)

进公司第一件事应该就是看别人的代码,熟悉一下业务,而代码都是在github或者gitlab之类的代码仓库里的,所以我们首先要做的,就是把代码拉到本地。

这是我的github,比如要拉图中这个goStudy项目,要做的就是把它clone到本地。

首先点clone or download那个绿色的按钮,然后会弹出一个框,写着clone with ssh,并且给出一个url,url右边有个复制按键,点击这个按键复制url,准备到本地clone。

在clone之前,还需要一步,因为我们是通过ssh从github上拉代码,因此需要先将我们本机上git的ssh的公钥告诉github,不然没法和github通信。

首先,在本地生成我们的公钥,只需要以下3个命令。

cd ~/.ssh
ssh-keygen
cat ~/.ssh/id_rsa.pub

执行ssh-keygen的过程中会停下来让你输入,直接回车就好了。

生成好的公钥在id_rsa.pub文件里,直接复制这个文件的全部内容即可,复制之后,回到github,准备将这个公钥配上去。

首先进入github的setting界面

然后点ssh and gpg keys 

然后点new ssh key

最后把刚才复制的公钥复制到key那里就可以了,title可以随便写

到这里,本机的ssh配置就大功告成了,接下来就可以拉代码了。

在本地,选择一个路径(我们要拉的代码会下载到这个路径),然后,就可以git clone了!

git clone后面跟的url就是一开始复制的那个,这步执行完,就会发现,这个项目已经被下载到了本地。

接下来,就可以用各种功能强大的ide去打开这个项目然后学习代码啦~

第二步,看别人的提交

对某些人来说,可能第二步就是提交代码了,但是我比较菜,为了写第一个需求,代码看了好几天,结果老大等不及了,自己写了。。。

这个时候,我就很好奇,他是怎么改的代码?为此,我要看看他做了哪些修改。

在github上可以很清楚的看到别人的每一次提交,首先,点开commit。

然后就能看到每一次提交。

 然后根据标题选择你想看的那次提交,然后点进去,就能看到这次提交的所有修改了,比如我的这次提交新增了一个文件。

最后就是看咯,看看别人是怎么用短短几行代码做到我瞪眼看了几天也没搞出来的功能。。。

第三步,更新自己的代码(pull/fetch)

 别人把代码改了并且提交上去以后,你的代码就不是最新的了,这时候,为了保证你能继续学习最新的代码,或者在最新的代码上做改动,你需要先更新自己的代码。

更新自己的代码其实是做两件事,第一件是把最新的代码从github上拉下来,第二步是和自己本地的代码合并,合并之后我们本地的代码就是最新的了。

这两步操作有两种做法,第一种,直接用git pull 命令。

git pull <远程主机名> <远程分支名>:<本地分支名>

其中,远程主机名如果没有特殊配置过,就是origin,远程分支名就是master、dev这样的分支,看你要拉哪个了,本地分支就拉下来远程分支之后和你的哪个分支合并,如果不填本地分支,就默认和你的当前分支合并。

第二种,就是按照我们最开始的想法,分两步做,先拉取,再合并。

git fetch origin master //从远程主机的master分支拉取最新内容 
git merge FETCH_HEAD    //将拉取下来的最新内容合并到当前所在的分支中

注意,git merge的时候,如果你自己本地的代码做过修改,那么是有可能和github里的代码存在冲突的,这时候还需要手动解决冲突。

不过,我到这一步的时候,代码还是一点没动过,所以并没有遇到冲突。。。

冲突以后一定会遇到的,到了那一步再补充。。。

第四步,修改代码(checkout/diff)

一段时间过去了,老大终于又给我安排了一个改代码的活,憋了这么久,这次我也想明白了,不能再畏手畏脚了,直接动手改,管他对不对呢。。。

修改代码之前,首先要创建一个自己的分支,分支这个概念嘛,刚到这一步也解释不清楚,后面几步全部读完就能明白了,下面是创建分支的命令。

git checkout -b 分支名

分支名的话,一般根据这次修改代码的内容来起,如果是增加功能,一般以feature开头,比如增加了删除用户的功能就可以把分支名起成feature-delete-user,如果是改bug一般以fix开头,比如修改了用户名为空时登陆崩溃的bug就可以把分支名起成fix-crash-when-username-null。

执行完这条命令,你就已经创建了一个新的分支并且切换到这个分支上了。接下来就可以在这个新的分支上修改代码了。

 修改代码的过程中,不得不提git diff这个命令。我是怎么知道git diff这个 命令的呢?之前实习的时候,有一次开会坐在一个清华毕业的大佬后面,看他一直在git diff,让我觉得,这是一个优秀的习惯,所以我也要用起来。。。

git diff是用来看你的代码跟之前比做了哪些改动,也就是确认一下自己做了些啥。注意,跟之前比,这个之前,又可以分好几类,可以是暂存区里的版本,也可以是某次提交之后的版本。啥是暂存区,这个后面再说,这里先直接上命令。

git diff

git diff后面什么参数都没有,就是跟暂存区的版本比较,比如下图,我先在代码里加了一行,然后用git diff看,就是这样的,这个就是对比暂存区的修改。

之后,我把代码提交到暂存区,然后再用git diff,就看不出任何区别了。

这是因为git diff是比较当前代码与暂存区代码的区别,我们刚把最近的修改提交到了暂存区,之后没有任何修改,因此当前代码和暂存区代码没有任何区别,git diff自然也就没有结果了。 

这里其实就可以看出来了,执行git add .就是把代码提交到暂存区,暂存区是干啥用的呢?这个我也不知道,以后再补充。。。

第五步,提交修改的代码(add/commit)

到了这一步,说明我们第一次对代码的修改告一段落了,也就是说,我们已经写好了一个新功能,或者改完了一个小bug,这时候,我们需要把现在的代码留存一个版本,就要用到提交了。

注意,提交的是暂存区的代码,因此,提交前记得先将你要提交的修改存到暂存区,也就是先

git add .

add后面可以跟文件名,也可以像上面那样写一个“.”,意思就是修改的全都保存到暂存区,我一般就用“.”,毕竟修改的肯定都是要提交的嘛,不提交改它干嘛。。。

接下来就是提交,直接上提交命令。

git commit -m"commit message"

其实git commit后面可以跟很多参数,不过我目前只用了最简单的,也就是只加了一个commit message,这个参数是用来描述你的这次提交的,可以写一句简短的话描述这次提交做了哪些修改。补充一句,不是我懒或者不会用其他参数,大多数情况下,提交的时候加上-m就足够了。。。

注意提交命令执行完会有提交的信息,包括修改了几个文件,做了几处修改,一定要根据这个信息确认一下,避免提交了意料之外的代码。。。

这节最后要做一个重要提示,是我自己踩过的一个坑,因为很坑,所以另起炉灶单独记了一篇,一定要点开看。。。

goland里面看到的程序和外面不一致

第六步,推送到远程仓库(push)

在上一步,我们将代码提交到了自己的本地仓库,这个时候我们的代码修改在本地已经保存好了,但这还不够。还记得我们的代码是怎么拿到的吗?没错,是在第一步从github上拉下来的。为什么代码要放到github上?我觉得有一下几个原因:

  • 备份:就是像网盘一样,把你的代码在网上存一份,这样万一你自己的电脑坏了,网上还能找到你的代码。。。
  • 分享:传到github上,别人也能看到你的代码,这是一种分享。。。
  • 多人协作:这里加粗又标红,因为这一条才是最重要的,在公司,一个服务的代码不只你一个人维护,可能你在做一个功能的同时,另外一个人在改一个bug,这个时候,你俩的程序改完了怎么办?难道把你改的拷贝到他的电脑上然后手动合并吗?那是原始人的方式。。。git给我们提供的解决办法是,所有人改完都提交到github,在github上合并!这样,完全不认识的人也可以一起开发同一个项目,只要有人在github上合并大家的代码就欧克了~

总之,就是你的代码写完一定要推送到远程仓库,也就是github或者gitlab之类的。

直接上推送命令。

git push origin head

这里,origin是我们的远程仓库,origin后面要跟我们要推送的分支,这里写了head,就是我们当前的分支,head后面还可以跟远程分支比如head:master,就是把你当前的分支,推送到远程仓库的head分支,这种高端操作我是用不着的,只是提一下。。。

总之,我的这行命令就是,把自己的当前分支,推送到远程仓库,因为自己的这个分支是拉下代码以后自己创建的,所以远程并没有这个分支,而执行完这条命令之后,远程仓库就会创建这个分支!

下面直接来个全套操作:

这里首先创建了一个分支,名称为feature-add-branch,然后修改了一下array.go文件,然后保存到暂存区,然后提交到本地,最后用上面的命令推送到远程仓库,推送完成后,看我们的仓库。

会发现这里出现了我们刚刚推送的分支,到这里,推送到远程仓库就算是成功啦~

第七步,合并分支

我们每次改代码之前都会创建一个新的分支,一个分支上可能有一个新的功能,或者一个bug的修复。

而正式环境运行的代码只能是一个版本,这个版本要包含所有的新功能,也需要修复所有的bug,因此,我们开发时创建的不同分支,需要合并到一起,形成一个大一统版本!

github里一般会有几个比较重要的分支,比如dev分支,这个是开发分支,上面是最新的代码,也就是说,我们要开发新的功能,一定是先切到dev分支,然后,创建自己的分支,开发完之后再把自己的分支合并到dev分支。除了dev分支,一般还会有一些正式版本分支,比如release1.0这样的分支,一般这种分支发布后不会再新增什么大的功能,只会一些维护,比如改改bug,那么改bug的时候,就会先切到release分支,然后修改bug,最后再合并到release分支。

不管是往哪种分支上合并,步骤都是一样的。在远程仓库合并版本不需要什么命令,只需要在界面上操作即可。

如果是github,在提交一个新的分支之后,github的仓库首页就会出现第六步最后那张图片里的那个“compare & pull request”,我们点击这个按钮。

点击之后,会进入一个这样的界面,这里可以在输入框中填写关于这次pull request的描述。

等下,不是在说merge么?怎么突然出来个pull request?其实pull request就是merge的前奏,它的作用就是告诉这个仓库,我更新了代码,想把我更新的这部分合并进去,请你把我提交这部分拉下来然后和你的代码合并了。嗯,就是这么个意思。

往下看,会看到这次的代码和你要合入的那个分支的diff

检查一下这些diff,确认无误以后,就可以点击create pull request了

 然后,就会发现这个仓库出现了一个pull request

 这个界面的下方有一个merge pull request按钮,这其实就是仓库收到了pull request,也就是代码修改者的请求,这个时候,如果确认没有问题,就可以点这个按钮,把他的更新合并进去了。

这个界面仔细看的话还有几个细节,一个是merge pull request按钮上面两行写了一句,continuous intergration has not been set up,就是说未设置CI。CI是啥?翻译过来是可持续集成。CI所做的,是确保你这次提交,是不影响这个仓库长期稳定发展的,也就是说,不能因为合并了你这个代码,以前的功能就不能用了,或者以后的人就不能在这次提交的基础上继续开发了。具体点说,CI做的事是这样的,第一,是把你提交的代码先合并了,然后,根据你设置的CI规则,去检查合并之后的代码。公司的CI一般会设置代码规范检查,和单例测试,也就是用你的代码运行起来,然后调用所有的接口看看好不好使。代码规范检查,各个语言一般有自己的库或者检测工具,比如go语言的gofmt,而单例测试一般是公司自己写的脚本。如果设置了CI,pull request创建之后,会默认开始运行所有的CI,只有所有的CI全部通过了,merge pull request那个按钮才能点下去。

那为啥截图里没设置CI呢,因为这是我自己的仓库,我自己自然是不会给自己平时学习写的代码设置CI这种东西了。。。不过公司的代码,或者开源项目的,肯定是有的~

另一个细节,看页面的右侧,有一个reviewers,状态是no reviewers。reviews是啥?就是检查你代码的人,前面说了CI,CI是自动执行的脚本,只能根据一些特定的规则去检查,还不够智能,不够理性,因此,CI通过之后,还需要找个人给你review一下代码,看看你这样写到底好不好。

当然了,我自己的仓库肯定也是不会设置这个的。。。

在公司的github上,这两步都通过了,merge pull request就可以点了,点完之后效果是这样的。

到这里,合并就成功了!

最后提一下,gitlab的界面和github是有一些不同的,比如gitlab上,不会因为你提交了一次代码,就弹出了pull request,你需要自己去提merge request,它的界面是这样的。

就是你得从左边的菜单栏点如merge request,然后再点new merge request按钮去创建merge request

 之后选择你要把哪个分支合并到哪个分支上面去。之后也会有CI,review之类的。

看似有很大不同,但是如果你能理解这个过程,那么这些显示上的差异其实是不会对你造成什么阻碍的。

欧克,到这里,合并就也完成了。一次正常的代码提交到这一步其实也就算完事儿了,之后在把合并后的代码放到线上去运行,这次开发任务就算结束了。当然了,实际场景远不止这么简单,那些额外的场景,等我遇到了,再继续往下补充,哈哈。

补充1:合并多次提交(rebase)

第一次开发,虽然只是修改了一个小功能,但还是修修补补了很多次,因此也产生了多个commit,最后开发完提了merger request之后,mentor一看,你这什么乱七八糟的,这么多次提交,给我合成一次!

把多次commit合成一次,git有个专门的命令用来干这个事儿,那就是rebase。下面演示一下合并多次commit的全套操作~

首先,用git log命令查看你最近的提交,比如我的长这样。

一般情况下,最近的几次提交就是你最近开发的那个小功能,就拿上面的图里来说,为了做个啥功能(比如图里为了演示rebase),我提交了3次,第3次提交后的代码终于通过了测试,代码也没啥要改进的了,欧克,这个时候我们就可以把这3次提交合并成1次了。

直接上命令。

git rebase -i head~3

这个命令就是,合并最近的6次提交,下面我们看看执行了这个会发生什么。

首先输入该命令并回车。

然后界面自动跳转到了这样一个文件里。

我们看到最上面3行,就是即将被合并的3次提交。我们用vim的命令修改一下这个文件,改成下面这样。

这个意思是,把第2次提交和第3次提交,合并到第1次里面,也就是说,合并完之后,应当只剩下一次commit。下面保存并退出,看看是不是我说的这样。

保存并退出后,又跳转到了这个文件里。

这里显示了,合并后的提交将显示的commit内容,如果不修改,commit-message将会变成3行,分别是这3次commit的message。我们合并后既然是一次提交,当然希望message也是一条总结性的,所以修改一下。

修改成这样之后,保存并退出。

 终于,又回到了命令行,而且,可以看到信息,successfully rebase,成功了,哈哈。

成功之后啥样呢,再用git log看一下。

可以看到,刚才的3个learn rebase的提交合并成了一个,而且,message是我们最后修改的那个message,到这里,合并3次commit就大功告成了,还是很简单的,哈哈。 

补充2:删除远程分支

我们每次开发,都会创建一个新的分支,开发完之后,将这个分支推送到远程仓库,然后合并到dev或者release等分支上面去。

那么问题来了,你每次开发都建一个分支,那最后远程仓库岂不是会有数不清的分支,到时候,从分支列表里想找一个分支,可能就要找半天。

如果一个分支已经被合入到dev或者release分支了,那么这个分支其实就没有用了,我们应该把它删掉,保证远程仓库里只保留几个重要的分支。

欧克,明白了为什么要删除远程分支,下面就是上命令了。

git push origin 【空格】【冒号】【需要删除的分支名字】

下面演示一下。

首先,我的github里有以下分支。

都是为了写上面的内容创建的,哈哈,所以随便删,这次选择删除pushTest。 

根据执行完的提示信息,删除成功了,去github上刷新一下,果然没有了!

其实呢,github界面上面直接可以删。。。但是我一开始不知道。。。

不过既然用了,而且成功了,不记下来可惜了。。。而且我相信,这条命令以后一定用得上!

好吧,还是看看github界面上怎么删。

仓库首页有个这个branch,点进去。

嗯,然后点那个垃圾桶就删掉了。 

 gitlab呢,自然也是有这个的。

甚至还支持一键删除merged分支。

好吧,到这里我想说,对于github,gitlab这种广为使用的远程仓库,你想做的,界面基本上都支持,与其去搜命令,不如直接找找界面上有没有对应的按钮。。。

补充3:对比分支

 为什么要对比分支?场景是这样的:

我自己的分支推到gitlab以后,在测试环境拉下来编译运行测试都通过了,然后,我就把这个分支合并到了dev分支,然后准备到正式环境上线,然鹅,上线的时候公司的上线平台有个警告⚠️,说你这个代码还没在测试环境跑过。

???我心想,跑了啊?

啊!测试环境跑的是我自己分支的代码,而不是我合并到dev之后的dev分支的代码。。。

这两个有没有区别呢?可能在你开发的过程中,别人有代码合并到dev分支了,然后你的代码再合并进去,可能从文本层面没有冲突,但是功能上会相互影响,总之,这个时候怎么能确保没有问题呢?那就是比较一下你自己的分支,和合并后的dev分支,如果这俩就是一样的,那说明这次合并之前没有其他人合并过,那么你在测试环境验证过的分支就是现在合并后的dev分支,直接上线肯定就是没有问题的喽~

好了,下面就是操作了,有了上一步的教训,我直接去界面上找,看看有没有对比分支功能。

这一找,果然有!

点击左侧的compare,然后右边的界面就会然你选择source和target分支,选好,点compare,看到的就跟commit时候的diff一样了。

github也是有的。

点击这个compare,然后也是可以选两个分支。这里我特意选了两个有不同的,看看效果。

发布了17 篇原创文章 · 获赞 22 · 访问量 3027

猜你喜欢

转载自blog.csdn.net/u013536232/article/details/103774263