Git使用憨逼指南

Table of Contents

前言

参考文档

Git几个基本概念

Git相关内容大纲

Git使用故事大赛

一、代码改坏了怎么办?

二、代码提交

三、新的分支!

四、n次提交

五、大麻烦!代码丢失?

六、新麻烦!有冲突!!

七、git pull & git pull --rebase?

1、rebase赢了

2、偏要多分叉

3、rebase的麻烦

八、栈存(是暂存,也不是暂存)

九、当前在哪一步?(工作区、暂存区、版本库)

十、里程碑

结束语


前言

  1. 为什么会有这份Git使用憨逼指南:生活所迫;Git文档很多很全,直接看印象不深,遇到了实际的应用场景,依然不知道要如何下手使用什么指令。

  2. Git的特点:学了就忘。

  3. Git憨逼指南的功能:因为学了就忘,所以忘了就查,方便查找主要的Git指令以及使用它们。

  4. Git憨逼指南可以学习到的技能:

    1)再也不用觉得官方文档很难看;

    2)不需要靠复制多份不同的代码来以防代码丢失。

    3)不需要在代码里通过注释的方式留着以前的代码逻辑。

    4)合并代码时不用担心误删了同事的代码被同事diao;

    5)自己憨逼删了自己辛辛苦苦写的代码以为找不回来再重写一遍。

  5. Git憨逼指南的愿景:让你从一个Git憨逼成长为Git master。

  6. Git憨逼指南的不足:更深入的知识,比如Git的实现原理,还得靠各位自己摸索。

参考文档

  1. 官方文档:https://git-scm.com/book/zh/v2/

  2. 廖雪峰:https://www.liaoxuefeng.com/wiki/896043488029600

  3. Git学了就忘(繁花似锦fighting的简书):https://www.jianshu.com/u/fa63cd14aa2c

  4. Git 笔记:将两个提交合并为一个:https://blog.csdn.net/jerechen/article/details/89556281

  5. Git:pull --rebase 和 merge --no-ff:https://www.cnblogs.com/welhzh/p/8028496.html

  6. git stash 用法总结和注意点:https://www.cnblogs.com/zndxall/archive/2018/09/04/9586088.html

Git几个基本概念

  1. 仓库(本地和远程)

  2. 分支(逻辑上可以理解为有多少份代码)

  3. 版本(每次修改后想存储的)

  4. origin,master

  5. 工作区、版本库、暂存区

Git相关内容大纲

 

Git使用故事大赛

一、代码改坏了怎么办?

祝小婷运气爆棚一不小心拿到了心仪公司的Offer,开开心心地去上班,结果上班第一天,mentor对他说,你把电脑装好,环境配好,代码下载下来熟悉一下,然后就走了,祝小婷听了,一拍大腿,今天看来很轻松。

新电脑拆开,插上电源通上电,再将装机必备的搬砖工具VS,Git,Everything等等一下载,从git上把代码拉下,因为代码数量庞大,光拉代码就花了近半小时,编译运行好装模做样的看起来功能和实现代码。

快下班的时候,metor走过来了,说,你把这个文案修改一下。改个文案嘛,简单!进去代码一看,一个文案涉及到十几个文件,祝小婷一个个改完,还在必要的地方加了中文的注释,看起来很完美,编译,运行!what the fuck,编译不过了?而且这个error的定位在文件的开头,可是祝小婷根本没有修改头文件呀。立刻百度找原因,但是并没有结果,祝小婷心想,最开始是可以编译成功的呀,肯定是修改了什么地方导致编译失败了,那恢复到刚下载的状态就可以了呀。遗憾的是,祝小婷虽然在学校里使用过Git,可是对Git的使用只在clone,pull、commit和push的状态,他又去花了30分钟clone了一份代码,再重新找问题所在,就在他clone了3次代码之后,他发现是文件中文编码方式的问题导致了这个编译错误,致使下班时间整整延后2小时,少看3集隐秘的角落。

其实他不知道的是,有个命令git checkout 可以放弃对没有commit的单个文件或者是所有文件的修改。

二、代码提交

第二天,给mentor检查了文案的修改结果,mentor说没问题,你提交吧,祝小婷知道git commit -a -m "xxx"就可以提交至本地,至于本地到底是个什么概念,也不太清楚。成功后,祝小婷还用git status查了一下当前的状态:

嗯,可以push了!git push后

 

哦,有同事在这期间提交了代码,祝小婷知道要git pull别人的代码下来再提交,git pull

 

成功!没有冲突!然后git push!祝小婷的第一个工作内容完成~

三、新的分支!

mentor看祝小婷第一个任务做的还可以,就给他分配了一个难度升了一级的任务。这个任务大约需要3天完成,metor让祝小婷拉一个新的分支来实现。祝小婷对分支并不是很熟悉,上网查了一下,大概有这么几个命令git branch,git checkout,怎么又是git checkout?

git branch可以查看本地的分支,git branch <name>可以创建一个新的分支,git branch -r可以查看远程的分支。祝小婷用git branch创建了一个分支,再用git branch查看了一下本地分支,看到了自己新建的那个分支,又试了一下git branch -r并没有看见新建的分支,说明git branch <name>只是在本地新建了一个分支,那么问题来了,怎么把新建的分支在远程仓库里也能有一个对应的分支呢?

面向互联网编程这个问题很容易,git push origin <name>,祝小婷试了一下,再使用git branch -r之后,发现远程也有了这个分支,very good!但是,当祝小婷写好代码使用git push的时候给了这个提示:

 

查一查发现是本地分支并没有和远程分支建立联系,所以不能直接使用git push,虽然git push <name>是成功给远程新建了分支,却没有建立联系,所以下次可以直接使用git push --set-upstream origin <name>或者git branch --set-upstream-to <name> oribin/<name>来建立本地分支与远程分支的联系,这样以后就可以直接使用git push啦。

四、n次提交

考虑到这个三天的需求有点复杂,祝小婷将这个大需求划分成了7个小需求来实现,在实现了第四个小需求commit了之后,他发现第四个需求里有一部分测试的代码也被提交上去了,完了完了,这要是被mentor发现,可是50个俯卧撑的下场,他把测试代码删掉后,心想,如果再commit一次那还是会被发现的哇,于是又百度起来,发现有一个命令,git commit --amend,好像是可以把本次提交合并到上次的,完美解决问题,而且这个git commit --amend不仅能够把本次代码提交合并到上次还可以修改当前提交的commit信息,这样再也不用担心commit内容写的文不对题又不知道要在哪里修改的问题了。

当祝小婷写完第5个小需求的时候,他又发现问题了,这第5个小需求,他提交了6次commit,这一个小需求就6次commit,commit未免也太多了把,也不方便mentor系统的给他code review哇,有没有什么方法可以合并这些commit成一个commit呢?他找到了一篇blog,这个blog里面的知识点在廖雪峰和Git学了就忘里面都没有看到呢~具体的做法用到了git rebase -i 这个指令,这个在憨逼指南里面也没有提到,比较复杂,但是功能很强大。参考Git 笔记:将两个提交合并为一个:https://blog.csdn.net/jerechen/article/details/89556281

 

-i后面写到第几次commit id就会显示到第几次commit的所有信息,然后可以在vim编辑器里修改commit的状态,可以合并,压缩,修改log等等。不详细说明,有需要自行研究。就这样,祝小婷最终一共提交了7个commit,他使用了git log命令后可以查看所有的commit的信息。整理commit提交也算是一个比较好的习惯,有利于团队合作开发,而且整理的过程也是自己对开发这个功能的回顾思考。

五、大麻烦!代码丢失?

其实祝小婷在第7次提交的时候遇到过一个大麻烦!他把自己开发一天半的代码给弄丢了!!Git不是只要提交了的代码就不会丢了吗?第7次commit最多也就半天的工作量,怎么会丢了一天半的代码呢?

原来那天祝小婷提交了第7个commit后,发现业务逻辑写的有很大的漏洞,他想把代码回退到第6次提交的时候,他知道用git reset --hard + commit id可以回退到那次的commit,结果他估计那天刚睡醒脑子还晕着,复制到第3次的commit id,并且reset了,完了完了,虽然git log可以查看commit的信息,但现在第4、5、6次的commit都没有了,git log根本看不到。祝小婷崩溃了,他把自己辛辛苦苦写了一天半的代码弄丢了,但是他不敢和mentor说,只能在社畜群里小声逼逼。逼逼完后又花了近3小时将这一天半的代码重写了一遍。人生啊~~

后来,祝小婷下定决心要好好学习一下git,写下git憨逼指南的时候,他发现有一个命令叫git reflog,它可以查看所有做过的操作过的命令,那么第4、5、6次甚至第7次的commit id是都可以看到的,只要再用git reset --hard + commit id一下,就可以恢复了!!如果当时,祝小婷知道这个指令,也不用火急火燎慌慌张张的,轻轻松松跳去第六次commit的结果了。当然reset在commit这里属于危险操作,还是考虑慎用把。

六、新麻烦!有冲突!!

你以为祝小婷那天写完第7个commit之后就顺利提交了吗?他git push失败,就去git pull,结果git pull下来之后依然不能git push,原因是代码和同事冲突了!!祝小婷很慌,他不会解决冲突哇,万一冲掉同事的代码怎么办??他只好叫来了mentor,mentor不愧是git master,一顿操作,成功解决了冲突,并将代码提交了。祝小婷也不是干瞪眼的,他默默记下了mentor的操作,先用tortoise git检查了每一个文件,将都需要的代码合并,并设置为冲突解决状态,当处理完每一个文件后,又在cmd里进行了commit,然后就可以成功git push了。看来解决冲突的时候还是用git图形界面工具方便些。

不过这次祝小婷遇到的冲突都是通用文件的代码冲突,等真正和同事操作了同一块部分的业务逻辑代码,还是得叫上对应的同事一起来解决这个冲突。mentor给祝小婷解决完问题后对祝小婷说,你下次提交的时候在后面加上--rebase。--rebase?这是什么?

 

这样的分支,乱吗?

七、git pull & git pull --rebase?

1、rebase赢了

祝小婷听了mentor的要求后,又上了百度查了查这个git pull后面加上--rebase是什么操作?和之前那个git rebase -i有关系吗?答案是,一点关系都没有。原来git从本地提交到远程的本质就是将本地的分支与远程的分支合并,这就是为什么前面讲的需要将本地和远程的分支建立联系。

有一个策略叫做fast forwarded,而按照 Git 的默认策略,如果远程分支和本地分支之间的提交线图有分叉的话(即不是 fast-forwarded),Git 会执行一次 merge 操作,因此产生一次没意义的提交记录,从而造成了像上图那样的混乱。

那么使用git pull --rebase就可以解决这个问题。参考Git:pull --rebase 和 merge --no-ff:https://www.cnblogs.com/welhzh/p/8028496.html

 

并且,当使用git pull --rebase拉下代码解决冲突后,不需要再commit一次,直接使用git rebase --continue就可以成功完成冲突解决,或者使用git rebase --abort来放弃本次pull。

不过,如果对使用 git 还不是十分熟练的话,建议还是git pull --rebase多练习几次之后再使用,因为 rebase 在 git 中,算得上是『危险行为』

同时,在cmd中使用 git log --graph命令也可以看到这样的分支图,不需要借助git图形界面工具,这个命令后面还可以带很多参数,有不同的展示效果。

2、偏要多分叉

祝小婷暂时还没有遇到偏要多分叉的场景,但是既然有学习到,就分享一下。git merge --no-ff <name>的策略是反行其道,刻意地弄出提交线图分叉出来。

假设你在本地准备合并两个分支,而刚好这两个分支是 fast-forwarded 的,那么直接合并后你得到一个直线的提交线图,当然这样没什么坏处,但如果你想更清晰地告诉你同伴:这一系列的提交都是为了实现同一个目的,那么你可以刻意地将这次提交内容弄成一次提交线图分叉。

执行 git merge --no-ff <branch-name> 的结果大概会是这样的:

git merge --no-ff

3、rebase的麻烦

祝小婷的三天需求还没完,因为祝小婷是在一个新的分支上写的这个三天的需求,所以他还要把他写的东西合并到现在同事们在开发的分支上去。

之前已经成功在本地创建分支并且关联到远程,现在是将远程的分支拉取下来到本地,git checkout -b 本地分支 origin/远程分支,怎么又是checkout,不管了,先实现再说。成功拉到本地后,就需要把自己在本地另一个分支写的三天需求合并到当前分支上,其实这和git pull是一回事,只不过一个是将本地分支和远程分支合并,现在是本地分支和本地分支合并,直接用git merge或者git rebase就可以了,策略也和在git pull的时候是一样的。

考虑到分支图的好看,祝小婷信心满满地选择了git rebase来操作,然鹅万万没想到,当他解决了冲突,git rebase --continue后,又有冲突,祝小婷慌了,难道自己操作错了?不应该啊,明明上次mentor就是这样操作的,他只能又叫来mentor给他看看,mentor看完后,说,你下次不要用git rebase,用git merge,???,祝小婷满脸问号脸,之前刚说的用rebase啊。祝小婷没想到的时,他以为这句是自己地内心OS,实际上脱口而出了,mentor看了他一眼解释道,使用rebase会对你的每一次commit进行合并,如果有冲突需要一次次的解决,git merge就会将它们直接合并了。原来如此,rebase也有造成麻烦的地方哇。如果这个时候有哪个憨逼要问,这是什么原理?对不起,祝小婷也不知道,可以自行学习。

八、栈存(是暂存,也不是暂存)

祝小婷终于打破了三天需求魔咒,开始了新的需求,但是,生活怎么可能轻易的停止碾压他,这不,mentor过来了,让他把手上的需求停一停,把一个新的需求赶工完。祝小婷应下以后开始思考,我手上这个需求,才干了一个开头,放弃是不可能放弃的,那也不能先commit上去和这个代码一起提交呀,那创建一个新的分支开发新的需求?原先这个先commit了放这?听起来都挺麻烦的。

祝小婷已经忘记了是怎么知道还有这个指令git stash的,但是就是被他知道了,这个git stash解决了他的烦恼,他使用git stash后,当前的代码恢复到了最后一次commit后的状态,但是依然在当前的分支,他可以当作啥事没有来开发新的需求了。

那上一个需求的代码去了哪里呢?原来是git把它推到了一个栈里,使用git stash list就可以查看这个栈里的存储的代码修改记录,等祝小婷开发完,再使用git stash pop,就会弹出最上面的代码修改,并且在栈里删除掉。当然这个stash的所有操作基本和stack栈是一样的,方便又好用。

git stash是把文件暂存起来了,但是它和暂存区的文件是完全没有关系的,它是对工作区的文件进行暂存。那么工作区,暂存区和版本库又是什么关系呢。

九、当前在哪一步?(工作区、暂存区、版本库)

我们对代码的所有操作都是在工作区进行的,修改,添加,删除,以及stash。

当我们使用git add的时候,就会将工作区的代码添加到暂存区,暂存区是在本地版本库里的一块区域,本地版本库里除了有暂存区还有分支以及指向分支的指针。当使用git commit的时候就是将暂存区的内容添加到当前分支上增加了一个新的版本。

我们对这些区域的所有主要操作也不过就是提交到上一级或者还原到前一个状态。那么首先需要确认的就是我们当前需要对哪个区域操作。

  • 工作区:提交 git add/git rm 还原:git checkout

  • 暂存区:提交 git commit 还原:git reset

  • 版本库:提交 git push 还原:git reset(危险!)

这些操作可以对单个文件也可以对所有文件。

十、里程碑

祝小婷在写Git使用憨逼指南的时候发现有个指令叫git tag,看起来是给版本打标签用的,俗称里程碑?但是具体有什么用他也不清楚。

但是在前两天祝小婷参加了一个大富翁的比赛,他需要把自己写的代码打包发布到一个平台上,那个平台上要求正式发布的版本代码必须是打上标签的,其实tag就是一个commit的快照,所以,是一个让人容易记住的有意义的名字,它跟某个commit绑在一起。

具体还有什么特别的,祝小婷也不清楚了。

结束语

至此,Git使用憨逼指南就结束了,感觉上,Git常用到的内容都在里面使用场景的方式提及到了,更复杂的以及Git的实现原理,就不适合Git憨逼来看了,需要Git master们给出答案。

里面可能有一些错误的地方希望Git master们能提出批评并指正。

希望每一个Git憨逼最终都是Git master。

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值