当前位置: 首页 > news >正文

超详细 Git 教程:二十篇博客,三万字干货

Git 是最流行的版本管理工具,可以说是任何程序员都应该掌握的工具。

当然,其他人也可以学习它用来进行版本控制

为此,我将之前学习 Git 时的笔记整理了下(预计有二十篇),作为博客发出来,希望能帮到你。


本文简单介绍下什么是版本控制,以及常见的版本控制工具

在学习之前,希望读者有一点点编程经验,并且对一些常见的 Linux 命令有所了解,这样能更好理解。

本系列主要是参考廖雪峰老师的 Git 教程 和书籍《Git 权威指南》,以及自己的使用经验来撰写。

在版本管理工具出现之前……

举个笔者的例子。笔者在写毕业论文的时候,由于篇幅非常多,经常需要修改;但有时候可能会用到之前的版本,因此笔者会先备份之前的 Word 文档,然后再修改。这就造成了文档非常非常多……

写过毕设或其他长篇大论的文案的人应该都遇到过这种场景。

此时,我们是手工管理版本的。对于每个文件,你可能几天内都记得每个版本的区别;但如果过了一周、过了一个月呢?除非有特别记录,相信大家都记不清了,只能一个个文件打开来,认真比对,非常麻烦。

如果是多个人共同编写一个文档,更麻烦。例如,笔者所在的公司是内网,没有腾讯文档或者石墨文档之类的在线工具,如果要填表(并且是经常需要填表),都是各自填好后,发邮件交由专门的人来合并…… 特别麻烦。

为此,我们需要这样一个软件:

  1. 能帮我们记录每次文件的改动
  2. 能够方便的查看之前的改动
  3. 让同事或朋友协作编辑,而不是手工传来传去,手工合并

这样的软件就叫版本控制工具,有了它,我们就脱离了手工管理版本的“史前时代”,进入到了版本控制的 20 世纪。作为程序猿,我们主要是需要版本控制工具来管理我们的一个项目的代码(当然,你也可以用它来管理其他文件的版本),并且一个大型项目经常是需要多人协作的,纯靠手工来管理代码版本不太实际。

常见的版本控制工具

我们依次来简单介绍以下几个工具(大部分笔者都曾在工作中用过):

  1. diff 和 patch 命令
  2. CVS:全称 Concurrent Versions System,第一个被广泛使用的版本管理工具
  3. SVN:修正了 CVS 的一些稳定性问题,是目前用得最多的集中式版本库控制系统
  4. Git:目前世界上最先进的分布式版本控制系统(没有之一),必学
  5. 其他版本控制工具(了解即可)

版本库的概念

存储版本的地方(存放各个版本之间差异的地方),通常称为版本库。通常版本库是以文件(夹)的形式存放在磁盘上:

  • Git 是用一个目录来存储各个版本和差异的文件,目录名字为 .git​;
  • SVN 同理,用 .svn​ 目录来存储的
  • CVS 同理,用 .csv​ 目录来存储的

一般情况下这几个目录是隐藏的(防止被随意的删除和修改等),在 Windows 上可以通过显示隐藏文件夹来查看,Linux 下可以用 ls -ah​ 命令查看

集中式和分布式的概念

在介绍版本控制工具之前,我们还有必要介绍一下集中式版本控制系统,和分布式版本控制系统的概念。

集中式:版本库是放在一个中央服务器上的,干活的时候,需要联网才能从服务器下载最新版本到自己电脑上(因为大多数时候我们都是在自己电脑上开发),开发完后再上传到服务器上。如果网速慢……那就有的等了。好比一个图书馆,要看书得先从图书馆里借书,用完了后要还回去,需要来来回回跑图书馆。

而且集中式容易出现单点故障的问题。万一服务器坏了,那么就完了…… 因此得额外对服务器进行备份。

集中式

图片来自 集中式 vs 分布式 - 廖雪峰的官方网站


分布式:每个人自己的电脑上就有一个完整的版本库,获取版本的时候不需要联网。等需要合并文件的时候,再将各自的修改上传到中央服务器上。就好比每个人都有一个完整的图书馆,如果要合并文件,每个人都将自己的修改放到中央图书馆里,相当于只用去一次图书馆;合并完后,每个人再从中央图书馆里更新。

图片来自 集中式 vs 分布式 - 廖雪峰的官方网站


一句话,集中式和分布式的区别是:你的本地是否有完整的版本库历史。每个人都是本地版本库的主人,对版本库的操作,包括查看提交日志、提交、创建里程碑和分支、合并分支、回退等所有操作都直接在本地完成而不需要网络连接。

假设 SVN 服务器没了,那就丢掉了所有历史信息,因为你的本地只有当前版本以及部分历史信息。

假设 Git 的中央服务器没了,你不会丢掉任何 git 历史信息,因为你的本地有完整的版本库信息。你可以把本地的 git 库重新上传到另外的 git 服务器,重新搭建一个「图书馆」。

廖雪峰老师的比喻:

比特币的区块链设计就类似 git,人手一份全账本,只是用 p2p 全网同步,而 git 通常搞个中心化服务来同步。

svn 像银行,完整账本只有银行有,作为终端节点可以向银行查询账本,但如果某一天银行没了,整个完整账本就没了。

分布式的核心设计是同步,而不是主从。

软件架构,核心思想其实是非常简单的。

diff 命令

diff 意指 difference。diff 是命令行工具,可以通过他们来比较两个文件的差异,后续我们学习 Git 的时候,也经常用 diff 命令来查看文件的差异,diff 可以说是版本控制的基础工具。

我们来看个例子(推荐读者一起来实践),在 Linux 下实践下该命令。

PS:如果没有 Linux 环境,读者可以先参考下一篇博客安装好 Git 后,然后在 Git Bash 里运行。

先创建两个文件,并写入不同内容(Windows 用户可以用右键-新建文本文件后,打开并输入内容):

$echo "This is hello file" > hello.txt
$echo "This is world file" > world.txt
$echo "Welcome to diff" >> hello.txt 
$echo "Welcome to diff" >> world.txt -- 此时文件内容分别如下
$cat hello.txt 
This is hello file
Welcome to diff$cat world.txt 
This is world file
Welcome to diff

然后我们就可以用 diff 命令,来比较两个文件的差异了。我们将差异结果输出到一个文件:

$diff -u hello.txt world.txt > diff.txt

-u 参数很重要,它使得差异带有上下文。

我们查看下 diff.txt 的内容:

$cat diff.txt 
--- hello.txt	2023-01-10 21:56:47.050201742 +0800
+++ world.txt	2023-01-10 22:08:41.473521836 +0800
@@ -1,2 +1,2 @@
-This is hello file
+This is world fileWelcome to diff

我们来说明下这个文件的内容:

  • 文件的第 1 行和第 2 行分别记录了原始文件和目标文件的文件名及时间戳。以三个减号(—)开始的行标识的是原始文件,以三个加号(+++)开始的行标识的是目标文件。
  • 文件的第 5,6,7 行,以减号(-)开始的行是只出现在原始文件中的行,以加号(+)开始的行是只出现在目标文件中的行,以空格开始的行,是在原始文件和目标文件中都出现的行,

第 4~7 行,是一个差异小节(就是两个文件之间的一个差异):

@@ -1,2 +1,2 @@
-This is hello file
+This is world file

每个差异小节以一行差异定位语句开始,其前后分别用两个 @ 进行标识。其中:

  • -1,2 的含义:本差异小节的内容相当于是原始文件从第 1 行开始的 2 行
  • +1,2 的含义:本差异小节的内容相当于是目标文件从第 1 行开始的 2 行

因为命令 diff ​是用于行比较的,所以即使一个字不同,也显示为一整行的修改(Git 对 diff​ 进行了扩展,并且还提供一种逐词比较的差异比较方法)。

除了-u​ 参数,diff​ 还有以下选项,就不一一演示了:

  • -b​:忽略空格
  • -B​:忽略空行
  • -i​:忽略大小写
  • -c​:显示文件所有内容并标识不同
  • -r​:对比目录

patch 命令

patch 相当于 diff 的反向操作。有了原始文件和 diff 文件,就可以还原出目标文件(patch 一词有“打补丁”的意思)。

我们来实践下,首先,用 hello.txt 的内容,将 world.txt 覆盖,这样两个文件的内容都是原始文件的内容:

$cp hello.txt world.txt 
$cat world.txt 
This is hello file
Welcome to diff

然后用 patch 命令来还原目标文件:

$patch world.txt < diff.txt 
patching file world.txt$cat world.txt 
This is world file
Welcome to diff

可以看到 world 文件回来了。

注意:经测试,如果 diff 和 patch 的文件中的换行符不是 Linux 环境下的 LF 换行符,那么 patch 就会失败(笔者推测是这两个命令没有考虑其他换行符的情况),报错如下:

$ patch world2.txt < diff.txt
patching file world2.txt
Hunk #1 FAILED at 1 (different line endings).
1 out of 1 hunk FAILED -- saving rejects to file world2.txt.rej

diff 和 patch 小结

严格来说 diff 和 patch 命令不是版本控制工具,而是比较差异的工具。

diff 和 patch 命令存在一个局限,就是不能对二进制文件进行处理。对二进制文件的修改或添加会在差异文件中缺失,进而丢失对二进制文件的改动或添加。

实际上,大部分版本控制工具都不能很好的管理二进制文件,虽然也能由版本控制工具来管理 ,但是不能比较两者有什么差异,一堆 0 和 1 的比较,是看不出来改了什么内容的。

Git 对差异文件格式提供了扩展支持,支持二进制文件的比较,解决了这个问题。

在没有版本控制系统的情况下,可以用这 diff 和 patch 记录并保存改动前后的差异,还可以将差异文件注入版本控制系统(如果有)。

Linus 在 1991~2002 年,就是用 diff 和 patch 维护 Linux 不同版本间差异的。感兴趣的读者可以看看 Linus Torvalds 于 2007 年 5 月 3 日在 Google 的演讲:Tech Talk: Linus Torvalds on git - YouTube。

在当时,已经有一些版本控制工具了(CVS 和 SVN),但不好用(是集中式版本控制系统);而一些商用软件,比起 CVS 和 SVN 好用一点,但那是收费的,与 Linux 的开源精神不符合…… 因此后面 Linus 开发了 Git。

CVS

CVS 的历史:CVS(Concurrent Versions System)诞生于 1985 年,是由荷兰阿姆斯特丹 VU 大学的 Dick Grune 教授实现的。当时 Dick Grune 和两个学生共同开发一个项目,但是三个人的工作时间无法协调到一起,迫切需要一个记录和协同开发的工具软件。于是 Dick Grune 开发出有史以来第一个被大规模使用的版本控制工具。

可以看到,CVS 是被逼出来的,用人工管理版本太麻烦了,没办法才开发出来。

CVS 的特点:

  • 最早被广泛使用,到现在也有不少人用;
  • 开源且免费
  • 集中式版本控制系统

使用 CVS 管理版本的时候,每个目录下面都有一个目录叫做 CVS(这样实现起来简单),单独拿一个目录出来就可以当作版本库。但 CVS 也有缺点:

  • 不能对重命名进行版本控制
  • 缺乏对原子提交的支持,如果有网络中断或其他不可控因素,会导致客户端向服务器端提交不完整的数据(这设计就很不合理了,最基本的功能有这样的缺陷)
  • 随着文件的变多,效率会越来越慢

CVS 的成功导致了版本控制系统的大爆发,各式各样的版本控制系统如雨后春笋般诞生了,并且 CVS 的不少理念都成为了后续版本控制的标准。

新的版本控制系统或多或少地解决了 CVS 版本控制系统存在的问题,在这些版本控制系统中,最典型的就是 Subversion。

SVN

Subversion,由于其命令行工具名为 svn,因此通常被简称为 SVN。SVN 由 CollabNet 公司于 2000 年资助并开发,目的是创建一个更好用的版本控制系统以取代 CVS。

SVN 的前期开发使用 CVS 做版本控制,到了 2001 年,SVN 已经可以用于自己的版本控制了

SVN 实现了原子提交的功能,不会像 CVS 那样出现文件的部分内容被提交而其余的内容没有被提交的情况。

SVN 还有一个创举,就是在工作区跟踪目录下(.svn 目录)为当前目录中的每一个文件都保存一份冗余的原始拷贝。这样做的好处是部分命令不再需要网络连接,例如文件修改的差异比较,以及错误更改的回退等。

SVN 还有不少闪亮的功能特性,使得 SVN 在 CVS 之后诞生的诸多版本控制系统中脱颖而出,成为开源社区一时的新宠,也成为当时各个企业进行版本控制的最佳选择之一。

但是,SVN 在本质上并没有突破,都属于集中式版本控制系统,在查看日志和提交的时候,如果网速慢,就很让人抓狂。

对于 CVS 和 SVN 来说,笔者在公司内的局域网内用过,网速还是可以的。但是论起好用,还得是 Git😁。

Git

书接上文,我们来继续介绍 Git。

在 Git 出现之前,Linux 之父 Linus 坚决反对使用集中式版本控制工具,在 1991-2002 这十余年间,Linus 宁可以手工修补文件的方式维护 Linux 的代码。

经过十余年的发展,Linux 的代码库已经变的非常大了,还用手工维护非常不方便,Linux 社区意见也很大。因此在 2002~2005 年期间,Linus 选择了一个商业版本控制系统 BitKeeper 作为 Linux 内核的代码管理工具,BitKeeper 的东家 BitMover 公司出于人道主义精神,授权 Linux 社区免费使用这个版本控制系统。

2005 年发生的一件事最终导致了 Git 的诞生。在 2005 年 4 月,Andrew Tridgell(即大名鼎鼎的 Samba 的作者)试图对 BitKeeper 进行反向工程(类似通过反编译等方式获得 BitKeeper 的源码),以开发一个能与 BitKeeper 交互的开源工具。这激怒了 BitKeeper 软件的所有者 BitMover 公司,要求收回对 Linux 社区免费使用 BitKeeper 的授权。

Linus 可以向 BitMover 公司道个歉,保证以后严格管教弟兄们,但实际上 Linus 会受这气?直接花了两周时间自己用 C 写了一个分布式版本控制系统,这就是 Git!几个月之内,Linux 系统的源码已经由 Git 管理了!大家可以体会下什么叫 🐂🍺

以下是 Git 诞生过程中的大事记(来自维基百科):

  • 2005 年 4 月 3 日,开始开发 Git。
  • 2005 年 4 月 6 日,项目发布。
  • 2005 年 4 月 7 日,Git 就可以作为自身的版本控制工具了。
  • 2005 年 4 月 18 日,发生第一个多分支合并。
  • 2005 年 4 月 29 日,Git 的性能就已经达到了 Linus 的预期。
  • 2005 年 6 月 16 日,Linux 内核 2.6.12 发布,那时 Git 已经在维护 Linux 核心的源代码了。

其他版本控制工具

分布式版本控制系统除了 Git 以及促使 Git 诞生的 BitKeeper 外,还有类似 Git 的 Mercurial 和 Bazaar 等。这些分布式版本控制系统各有特点,但最快、最简单也最流行的依然是 Git!

除了之前介绍的版本控制工具,还有不少商用版本控制系统,占了一部分市场份额。但商用的一般有如下缺陷:

  • 采用黑盒子式的版本库设计。大部分商用产品,是不会给使用者源码的(给了谁还买啊),因此让人捉摸不透其内部是怎么实现的,也加大了将代码迁移到其他版本库的成本,使得企业只能一直用这个产品。
  • 商业版本控制工具很难定制化需求,因为公司需要赚钱,总不能免费帮忙开发需求。
  • 商业版本控制工具注定是小众软件,专门提供给企业使用,培训新员工也很麻烦。

接下来简单说说笔者知道的一些商用工具。

ClearCase

Rational 公司(该公司后面被 IBM 收购了)出品过 ClearCase 版本控制工具,但据说很难用,搜索到的评价如下:

  • 为什么有些大公司技术弱爆了? - 知乎:毕业第一年在腾讯工作,做 QQ 游戏大厅,当时用的 IDE 是 VC2006,用的版本控制工具,叫 ClearCase(估计用过的人不多),IBM 开发的。特点是极其严谨、非常强大,但流程极为繁琐,用起来简直让人抓狂,这还是腾讯花了 3000 万找 IBM 买的。
  • 廖雪峰老师点评:安装包比 Windows 还大,运行比蜗牛还慢,能用 ClearCase 的一般是世界 500 强,他们有个共同的特点是财大气粗,或者人傻钱多。

VSS

微软公司出品的,搜索到的相关平均如下:

  • 廖雪峰老师点评:微软自己也有一个集中式版本控制系统叫 VSS,集成在 Visual Studio 中。由于其反人类的设计,连微软自己都不好意思用了。

  • 维基百科:Microsoft Visual SourceSafe 是美国微软公司出品的版本控制系统,简称 VSS。

    软件支持 Windows 系统所支持的所有文件格式,兼容 Check out-Modify-Check in(独占工作模式)与 Copy-Modify-Merge(并行工作模式)。VSS 通常与微软公司的 Visual Studio 产品同时发布,并且高度集成。VSS 使用文件系统作为存储方式,每次版本变更时就需要大量地读写硬盘。这也是 VSS 最广受垢弊的缺点。

    VSS 虽然是微软公司的产品,但微软内部却很少使用它。微软内部使用一个名为 SLM 的版本控制系统,直至 1999 年。之后,微软内部改以使用修改自 Perforce 的 SourceDepot。

小结

本文主要介绍了如下内容:

  1. 为什么我们需要版本控制
  2. 集中式和分布式的概念
  3. 常见的版本控制工具介绍
  4. 简单演示了下 diff 和 patch 命令
  5. 简单介绍了版本控制工具的历史

在可以选择的情况下,强烈推荐使用 Git 作为版本控制管理工具。


http://www.mrgr.cn/news/36073.html

相关文章:

  • LabVIEW大数据处理
  • sql速度优化多条合并为一条语句
  • 面向对象编程的优势
  • Linux笔记-对Linux环境变量的进一步认识(2024-08-09)
  • 面试问答:什么是滑动窗口
  • 让redis一直开启服务/自动启动
  • 蜘蛛爬虫的ip来自机房,用户的爬虫来自于哪里
  • 2024低代码大赛火热进行,豪礼抢先看~
  • 【Linux实践】实验五:用户和组群账户管理
  • 网络原理3-应用层(HTTP/HTTPS)
  • C# 面向对象基础,简单的银行存钱取钱程序
  • 精密矫平机如何推动工业自动化?
  • 素数判断-C语言
  • 硬刚小米15,又一小屏旗舰加入战场了
  • 深入理解同步和异步与reactor和proactor模式
  • MySQL | group by 用法
  • C++ vector容器迭代器失效
  • 音乐服务器测试报告
  • Python如何保存py文件
  • 植物大战僵尸杂交版v2.5.1最新版本(附下载链接)
  • 【linux】regulartor-fixed
  • c语言实现:链表创建、插入、删除、翻转
  • p2p、分布式,区块链笔记(OrbitDB.ControlCenter 003) :数据库接口 src\database\index.js
  • 设备程序驱动框架
  • 【Linux】解锁文件描述符奥秘,高效缓存区的实战技巧
  • MySQL: 数据类型介绍