写给zct
小可爱的Git
和Github
入门学习材料。😆
1. 一些场景
在学习Git
或者Github
之前,我们先来看一些生活中很常见的场景。如果你对这些场景有所体会,后面可以更好地理解我们为什么要学习使用Git
,Github
。
毕业论文撰写
开题后第一周,你洋洋洒洒地写完了论文的初稿,然后高高兴兴地发给老师审阅。老师拿到论文一看,脱口而出就是一句:“这写的什么玩意”。“背景介绍这里,引用呢?这个句子,念都念不通顺。这个系统设计,写得比做作业还简单。还有这里的错别字……”老师毫不留情地给你指出了一堆错误,让你回去先修改。
场景一:历史版本丢失
回去之后,你就开始了慢长的修改历程。但是在这个修改过程中,你全部都是在同一个doc文件上进行修改的。有一天,你辛辛苦苦修改了一整天的文档,在半夜的时候突然睡着了😪。最糟糕的是,你之前的文档没有保存。你睡着的时候不小心趴在的键盘上,把前面写的文字变成了”sa1243UASI&DA*&Shasdf”这样的乱码,而且还保存了!早上你起来一看,简直想死的心都有了😫。全都要重新写了。
场景二:历史版本不明
这一次,你学聪明了。在每修改完一部分,你就将这份文档另存为一份。久而久之,你依次保存了以下这些文件
- 毕业论文初稿(副本1).doc
- 毕业论文初稿(副本2).doc
- 毕业论文初稿(副本3).doc
- …
然后你又兴高采烈地把改好的论文拿给老师看。老师一看,说:“嗯,改得还行,错误比之前少了很多。诶,你怎么把算法设计的地方给改了啊,那个地方你写得挺好的。你改了之后还没有以前的好呢。你这篇论文,其它部分暂时不用动,先把算法设计部分换回以前的部分”。
可是,头晕脑胀的你,根本不记得之前的算法设计是怎么写的了。突然,你灵光一现:“对啊,我不是有存副本吗!”。然而,回到家里的之后的你,看着电脑上那些“副本1”,“副本2”,“副本3”,根本不知道哪个副本做了什么修改,只好一个个打开这么文档去看,到底是在哪个文档中对“算法设计”这个部分做了修改。
场景三:历史版本差异不明
吃一堑,长一智。这一次,你又改变了你的文档保存策略。现在,你做完文档的修改之后,都会根据你对哪里做了修改来命名你的文档。然后,你依次保存了以下这些文件:
- 毕业论文初稿(修改摘要版).doc
- 毕业论文初稿(修改错别字版).doc
- 毕业论文初稿(修改系统设计版).doc
- …
- 毕业论文初稿(恢复算法设计版).doc
修改完成后,你又一次去找指导老师评阅论文。老师看完你的论文之后对你说:“做得不错。但是系统设计这部分还是有些问题。这样吧,你之后改完之后在线上发给我看一下,如果还是有小问题的话,我直接让你改,你就不用每次都来我这里了”。于是,你又开始了你的论文修改工作。经过了多次与老师的交流,你又产生了以下的这些文件:
- 毕业论文初稿(系统设计修改版1).doc
- 毕业论文初稿(系统设计修改版2).doc
- 毕业论文初稿(系统设计修改版3).doc
- …
这段时间,你一直都在修改系统设计这些部分,通过文件名也可以很容易找到你在哪些文档对系统设计做了修改。但是,面对这么多的“系统设计修改版”的文档,你不知道到底哪个文档相比起上一次做了什么修改。于是,你又要一个个打开这些文档,去比较你到底做了什么修改……
场景四:多人协作不方便
慢慢地,你开始着手算法实现的工作。虽然你自己也会写代码,但是有些地方你不知道应该怎么实现,于是你去找了几个学霸来帮助你一起coding。你把你要实现的代码分成了几个模块:
- main —> ct同学完成
- module A —> 学霸A完成
- module B —> 学霸B完成
- module C —> 学霸C完成
因为学霸A、B、C 互不认识,所以他们的代码都是发给你来整理和调度。每次他们发来的代码,你都要自己去调整位置,因为他们都不知道你写的代码是怎样的。
有一天,学霸A对你说:“我这个模块需要调用module B里的一个函数,不提供的话我没法继续写“。这个函数刚好是学霸B在写,但是学霸A又不知道学霸B什么时候写好,于是他就天天问你,你再去询问学霸B,然后等到学霸B回复你之后再进行转告……
然后另一天,学霸C又对你说:“哎呀这个module A里写的funA函数怎么有Bug啊”。然后你又开始了与学霸A、C之间的相互转告工作……
于是你始终没有办法很好地继续你的工作,因为你总是因为要进行各种转告、合并工作,导致效率极低,多人工作甚至还不如你自己工作……
2. Git是什么?
Git是一款免费的、开源的、分布式的版本控制系统。(小声BB:“所以Git到底是个啥东西啊?什么是分布式啊?什么是版本控制啊?”)
3. 说人话
前面的介绍Git
还是不够直观,那么我们来看看,Git
是如何帮助我们处理前面提到的那些场景的。
版本控制
前面的场景一我们提到,由于没有历史的版本,导致我们无法回溯到以前的工作。而Git
恰恰提供了版本控制的功能,能帮助我们回溯到文件的历史版本。假如我现在有一个名为my-big-project
的项目要开始进行了,那么Git
是如何帮助我们实现版本控制的呢?
后面的操作命令,如果你不懂也没有关系,你只需要大概知道我每一步干了什么就行了。具体操作可以以后再学习。
首先我们需要先初始化一个
Git
仓库(repository
)。所谓仓库呢,就是我们就进行版本控制的地方。就好像你在写论文时,你会找的参考资料,正在写的稿子放到某个文件夹里。这里以
my_big_project
文件夹为例git init
开始我们的工作,并在完成一定的工作后将文件进行提交
假设我现在在
my_big_project
文件夹下创建了一个essay.md
的文档,并编辑这个文档写入了如下内容:# My Big Project ## 摘要 我完成了摘要的工作啦哈哈哈。我现在要先保存一下这些内容。
现在我们把已经完成的工作保存一份历史记录。
$ git add essay.md $ git commit -m "完成摘要编写"
虽然你可能还不知道我干了什么,但是现在我确实已经完成了一次历史版本的提交。
同样的操作,接下来我们继续编写我们的
essay.md
文档,添加背景介绍内容:# My Big Project ## 摘要 我完成了摘要的工作啦哈哈哈。我现在要先保存一下这些内容。 ## 背景介绍 我完成了背景介绍的工作啦哈哈哈。我现在要再一次保存一下这些内容!
和之前的操作一样,我们再保存一份历史记录
$ git add essay.md $ git commit -m "完成背景介绍编写"
现在我们可以使用
Git
的一些GUI
图形界面程序来看一下,我们到底完成了什么工作在上图我们可以明显看出,
Git
帮助我们保存两份essay.md
的副本。这样子我们就解决了历史版本丢失的问题Git commit message帮助我们解决历史版本不明的问题
也许你注意到了我前面使用
commit
命令提交时,加上了一个-m
参数。这个参数就是给本次提交添加一个描述,例如”完成摘要编写“,”完成背景介绍编写等等“。这样子,我们通过commit message
,就能很容易区分不同的历史版本了。Git可以帮助我们比较历史版本间的差异
假设我们在之前的基础上,又依次完成了系统设计、算法设计、改善算法设计几个步骤。我们过了很长一段时间没有写这篇文档了,已经忘记了之前做了什么工作。那么
Git
可以帮助我们比较不同历史版本间文件的差异。例如我们这里想要看一下,改善算法设计到底在完成算法设计的基础上做了什么工作。
通过这里我们很方便地看出,原来我们在
essay.md
的文档的第16行,添加了2+3=5
。
多人协作
正如下图所示,我们可以找多个人来帮我们协同完成一个项目,每个人分别负责不同的板块。
在Git
里面,我们可以用不同的branch
分支来划分不同的工作,例如:
- 学霸A在学霸A
branch
里开发module A
- 学霸B在学霸B
branch
里开发module B
- 学霸C在学霸C
branch
里开发module C
当他们的工作完成之后,ct
同学就可以将他们的工作merge
到自己的master
分支上,这样就可以把大家的工作协同起来了。当然,在合并大家的工作时,有时候可能会产生“冲突”(conflict),这时候需要手动去解决一下冲突。
那么,怎么体现Git
的分布式特性呢?所谓分布式,通俗点来理解就是把一份东西分到了多个不同地方去。当我们在协同工作时,我们可以通过git clone
命令来克隆别人仓库。用上面的例子来说的话,就是学霸A、B、C他们每个人都可以有一份你的仓库的副本,其中这个仓库副本里包括所有人的历史版本信息。
也就是说,只要学霸A定时将它的仓库与你的仓库保持更新,他就能获取到你、学霸B、学霸C所完成的工作,而不必像以前一样必须通过你才能知道别人完成到了什么程度,是不是非常方便呢?😎
并且,学霸A、B、C都可以在他们克隆下来的仓库下面随便操作,因为他们操作的都是他们本地的副本仓库,根本不会影响到远程仓库或者别人克隆的仓库。这样子就避免了大家在同一个开发环境下一起工作,导致出现混乱的场面。例如,由于学霸A不小心把学霸B的文件给删除了,导致学霸B无法工作这样的场景是绝对不可能出现的!因为他们在各自不同的本地仓库local repository
上操作。
4. 总结一下
至此,我们已经通过列举一些十分常用的场景里会遇到的坑,以及Git
是如何帮助我们解决这问题的,来认识到Git
的一些重要特性——版本控制、协同工作。当然,Git
的功能十分强大,远远不止我上面提到的这些。虽然理解和学习Git
的过程可能会有一点困难,但我个人而言还是十分推崇学习Git
的。
前面提到的例子,是我以比较通俗的语言去介绍Git
的一些使用场景。如果Git
刚好有满足到你的痛点,那么赶紧来学习吧~
至于Github
到底是什么❓有什么用❓怎么用❓我会在下一篇文章里告诉你。所谓Github
,可以看成是Git+Hub
啦。所以先理解了Git
的思想,你才会更会地学习后面的内容。
5. 推荐学习资料
除另有声明外,本博客文章均采用 知识共享(Creative Commons) 署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议 进行许可。