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

news/2024/9/25 15:00:37

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.ryyt.cn/news/64585.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

Python计算傅里叶变换

本文介绍了离散傅里叶变换和快速傅里叶变换的基本原理及其对应的Python代码实现,并将计算结果与numpy所集成的fft函数进行对比。其实现在FFT计算的成熟工具已经有很多了,不论是CPU上scipy的fft模块还是GPU上的cufft动态链接库,都有非常好的性能。但还是得真正去了解计算背后…

9月24日课件之动手动脑

在本次课件中有多个动手动脑作业,再次我逐一学习分析。 一、首先是关于枚举的学习代码为, 运行结果为。 首先第一个运行结果显而易见的是false,第二个是因为枚举为类所以不是基本类型,在.isprimitive()中基本类型是返回true,类的话将会返回false。 第三个是.valueof()会返…

如何在低成本ARM平台部署LVGL免费图形库,基于全志T113-i

LVGL简介 LVGL(Littlev Graphics Library)是一个开源的图形库,主要用于嵌入式系统创建图形用户界面(GUI),采用C语言编写,具有高效性和可定制性,在各种微控制器平台和显示硬件上开发用户界面时备受欢迎。LVGL具社区免费开源、控件资源丰富、跨平台可移植等特点。 社区免费开…

一万字全面解析CRM的定义、分类与核心价值

1、CRM定义与分类 1.1CRM的定义 CRM,英文Customer Relationship Management的缩写,中文全称为客户关系管理。通常情况下,人们通常用CRM直接表达客户关系管理软件系统——一个以客户为中心的专门用于管理与客户关系的软件工具,以确保与客户在营销、销售、服务的每一环节上都…

串口属性中的BM延时计时器问题

天道酬勤 循序渐进 技压群雄

MUX VLAN

MUX VLAN 作用在二层,通过动态调整VLAN的划分和分配,实现了更高效的网络管理 主VLAN 扮演核心角色,负责承载主要的网络流量和服务 所有的从VLAN都与主VLAN相关联,通过主VLAN进行通信和数据传输 从VLAN 互通型从VLAN(Group VLAN) 这些VLAN内的设备可以相互通信 隔离型从VL…

module collections has no attribute Hashable PyDocx 库报错

### 项目背景在测试PyDocx代码时```python from pydocx import PyDocXhtml = PyDocX.to_html("test.docx") with项目背景 在测试PyDocx代码时 ```python from pydocx import PyDocX html = PyDocX.to_html("test.docx") with open("test.html", …

SimpleAIAgent:使用免费的glm-4-flash即可开始构建简单的AI Agent应用FI

合集 - C#(80)1.使用C#将几个Excel文件合并去重分类2023-11-152.C#使用SqlSugar操作MySQL数据库实现简单的增删改查2023-11-163.C#中的类和继承2023-11-174.C#中的virtual和override关键字2023-11-175.C#中的属性2023-11-206.C#winform中使用SQLite数据库2023-11-237.C#简化工作…