GitLab CI/CD pipeline和DevOps之道系列文章(一)
GitLab CI/CD pipeline和DevOps之道系列文章(二)
GitLab CI/CD pipeline和DevOps之道系列文章(三)
GitLab产品是围绕一个名为Git的独立工具构建的。GitLab使Git更易于使用,并为您提供一个中央存储所有由Git管理的文件的位置,除此之外还提供许多与Git无关的其他功能。我们认为GitLab是Git的包装器,使其更易于使用和更强大。
尽管GitLab和Git是不同的工具,但GitLab借用了Git的许多概念。这意味着要理解GitLab,您需要理解Git。幸运的是,您只需要掌握Git的基础知识。我们说"幸运"是因为Git是一个庞大而复杂的工具,学习其所有的细节需要付出巨大的努力。但请相信我们:如果您理解了Git的前10%,您就可以有效地使用GitLab。这本书将向您介绍这个前10%的内容。
首先,我们将向您展示为什么像Git这样的版本控制系统是软件开发中如此有用的一部分。然后,我们将解释如何将代码存储在Git中,包括您或团队成员对该代码所做的任何编辑。我们还将向您展示如何在一个叫做分支的安全位置开发您的代码,该分支与其他团队成员隔离。这确保您不会踩到其他人的脚趾并覆盖他们的代码。您将学习如何标记代码的特定版本,以便稍后可以轻松地引用它或将其发布给客户。最后,您将了解如何在远程位置存储代码。您将学习如何同步本地和远程文件副本,并理解这种架构如何使整个团队能够同时在单个代码库上工作。
在本章中,我们将介绍以下主要内容:
- 为什么使用Git?
- 提交代码以保证其安全性
- 对提交进行标记以标识代码的版本
- 在隔离空间中开发代码分支
- 同步本地和远程存储库的副本
- 学习Git的其他资源
技术要求
在本章中,您需要在本地计算机上安装Git。Git可以在Linux、macOS和Windows以及许多Unix变体上工作。在git-scm.com/downloads 上有详细的安装Git的指南,适用于这些操作系统中的任何一个。如果在安装过程中被要求设置配置选项,请安全接受所有默认值。
在Linux或macOS上,使用您喜欢的终端应用程序来输入本章中将看到的Git命令。如果您是Windows用户,可以在命令行窗口、PowerShell或Git Bash中输入这些命令。在安装Git时,Windows的默认配置选项应该可以使Git在任何这些类型的Windows终端上可用,并且它们在运行Git命令时应该会产生相同的结果。
本书中的Git示例是与操作系统无关的:无论在何处运行Git,它都能够正常工作。
为了检查是否已安装Git,或验证您是否正确安装了Git,请打开适用于您操作系统的终端,并运行以下命令。如果输出显示一个版本号而不是错误信息,则说明Git已经正确地安装在您的计算机上:
$ git --version
git version 2.25.1
不必担心看到特定的版本号;在本书中使用的简单命令中,几乎任何版本的Git都会表现一致。
在使用Git之前,您必须告诉它您的姓名和电子邮件地址。这些信息将被添加到您在Git中存储的每个编辑中,以便其他团队成员知道您负责的编辑。
首先,检查Git是否已经配置了这些信息:
$ git config --list
如果输出中包含user.email和user.name的条目,说明已经设置好了,可以跳过接下来的两个命令。否则,请运行以下两个一次性的命令,将电子邮件地址和姓名替换为您自己的信息,让Git知道您是谁:
$ git config --global user.email "qaseven[@example.com](mailto:george.spelvin@example.com)"
$ git config --global [user.name](http://user.name/) "qaseven"
一项可选但建议的步骤是将Git配置为在新项目中使用"main"而不是"master"作为默认分支的名称。我们还没有讨论分支是什么,所以这可能听起来有些费解。现在,您只需要知道许多软件公司正在将"main"作为项目稳定代码存放的地方的名称。您会在实际使用中看到这两个术语(甚至在本书中也会看到),但如果您想配置您的计算机以便新项目使用"main",请运行以下命令一次:
$ git config --global init.defaultBranch main
完成所有步骤后,让我们进入正题! 为什么使用Git?
就像在自动化工具如GitLab CI/CD流水线出现之前了解我们是如何构建软件一样(如第1章所讨论的),了解在Git或类似工具出现之前,团队是如何协调进行对同一文件的编辑这个复杂过程是有帮助的。
这些工具旨在解决开发人员面临的许多问题,但我们只讨论其中一个。想象一下,你和你的队友peppa正在共同开发一个代码库,并且你们两个都想编辑同一些文件。此外,想象一下,这是在Git或任何其他版本控制系统(VCS)出现之前的时代。在这个没有Git的年代,编写软件的唯一方式是你编辑一个文件,然后通过电子邮件、将其放在共享网络驱动器上或复制到便携式磁盘上来传递它。然后,您必须告诉Elizabeth她可以开始编辑它了。她以某种方式检出它(也许通过向电子表格中添加一条记录表示她控制着该文件,或者通过其他某种机制),并且她随时可以保留对该文件的控制权。如果您有新的想法并且想再次编辑该文件,您需要要求她停止编辑并将其交还给您。当她交还后,您需要扫描整个文件以查看她所做的更改,希望它们与您想要进行的更改不冲突。然后,每当您或Elizabeth想要编辑这些文件中的任何一个时,都需要重复这个过程。您可以想象这个过程是多么缓慢和繁琐,并且在所有所有权转移的过程中会出现多少问题!
通过理解事情在以前那些糟糕的日子里是如何工作的,我们可以看看什么是版本控制系统(VCS),它是如何解决这个问题的,以及它如何以其他方式简化了开发人员的生活。
什么是版本控制系统?
版本控制系统(VCS)是一种工具,旨在帮助一个或多个开发人员处理一组文件。它通过在特定时间点对项目中的所有文件进行快照,并允许您在不同的快照中查看、比较和恢复文件来实现这一目的。
每个版本控制系统(VCS)的功能略有不同,但以下是大多数VCS提供的一些功能:
- 在当前版本丢失或意外覆盖时提供文件的备份。
- 显示文件内容随时间的变化。
- 显示谁对哪些文件做了哪些更改,以及何时进行了更改。
- 为将来的参考标记某些文件快照。
- 提供对每组更改的人类可读描述,以便团队成员可以理解更改的原因。
- 允许开发人员以与其他同时编辑相同文件的开发人员兼容的方式进行文件编辑。
多年来,一直有许多竞争的VCS,包括开源和专有的。一些最著名的例子是Microsoft Visual SourceSafe、CVS、Apache Subversion,现在是Git。出于我们将很快解释的原因,Git主导了VCS领域,并且现在是没有使用Git的竞争对手之一的公司默认VCS。换句话说,Git赢得了VCS竞争,至少在这样的竞争中是可能的。
VCS可以与任何计算机语言一起使用。例如,您可以使用相同的VCS来管理Java、Python和Ruby项目中的文件。虽然我们通常认为VCS帮助您处理计算机语言中的源代码文件,但它们可以与软件项目中的任何文件一起使用,包括(但不限于)以下内容:
- 文档,如Markdown或PDF文件
- 配置,如JSON或YAML文件
- 测试代码和数据
- 集成开发环境(IDE)的元数据或配置信息
- 其他项目资产,如图片、视频或声音文件
不需要将VCS限制在仅适用于软件项目!您可以使用Git或任何VCS来管理文集中的诗歌、烹饪书中的食谱或小说中的章节。VCS对于任何涉及计算机上文件的项目都是有用的。
VCS解决了哪些问题?
既然您了解了像Git这样的VCS提供的功能,您可能会意识到它可以解决软件开发人员日常面临的各种问题。以下只是一些情景,您肯定还可以想出更多的应用场景。
为什么这段代码被改变了?有一天早上,您可能会在文本编辑器中打开一些源代码,发现一个您熟悉的方法现在使用了完全不同的算法。为什么会改变它?旧的算法有问题吗?新的算法更快吗?实现它的代码更短或更易读吗?通过查看VCS的提交消息,您可以阅读关于为何进行更改的描述。这些消息的完整性因提交更改的开发人员是否有责任心而异,但通常您可以大致了解到是什么激发了这个改变。
这段代码是何时改变的?想象一下,您重新查看了一个几个月前没有看过的Java类,然后注意到它添加了一些功能并删除了其他功能。这些更改是什么时候发生的?更重要的是,它们是在最后一次部署到生产环境之前还是之后进行的?您的VCS的提交日志将告诉您每次对该类进行了修改的时间,甚至告诉您每次编辑时修改了哪些行。这样,您就可以确定每个更改是何时进行的,以便您知道客户今天使用的类的哪个版本。
谁添加了这个有bug的代码?Git有一个称为blame的功能,可以告诉您哪个开发人员编辑了文件的哪些行。当您发现一些新添加的代码有错误或运行缓慢时,这非常有帮助,因为您确切地知道应该向谁寻求修复!但是它也有一个积极的用例:如果您发现了一段特别聪明的代码,您的VCS可以告诉您应该赞扬和学习的人。因此,blame功能提供了改善开发人员之间的专业关系和增强团队士气的绝佳途径。
我需要恢复我的Foo.java副本我相信您从未在工作了一整天后意外删除了文件,但我们确实有过这种情况。我相信您对于制作备份非常谨慎,以防发生这种情况,但我们确实没有。但由于我们始终使用VCS,恢复丢失的文件很容易:每个VCS都提供了一种简单的方式来查看和恢复其管理的任何文件的最后一个版本。
我想恢复到今天早上测试目录中的所有文件的版本您不仅限于恢复文件的最后一个版本;您可以恢复任何版本的文件,无论它们有多久,只要您添加了包含该版本的快照。例如,假设您花费数小时重写自动化测试以使其运行更快,只发现您的新测试要么更慢,要么根本不起作用。您的VCS将允许您替换一个文件、一个目录中的所有文件或一个项目中的所有文件,以使用这些文件的任何旧版本。随时编辑您想要编辑的文件,无论多少次。只要定期将更改检入您的VCS,您就不必担心丢失工作或恢复到旧代码,如果新代码不起作用的话。
我和一位同事想同时编辑Foo.java文件版本控制系统(VCS)最常用的功能之一是它们能够安全地将您在文件中所做的编辑分割开,以防止覆盖其他人在同一个文件中进行的工作。每个开发人员都有自己的代码分支,在这个分支上他们可以编辑任何文件,即使其他人也在他们的分支上编辑同样的文件。当每个开发人员完成工作时,他们将自己的分支合并到项目的稳定代码库中。通过这种方式,多个开发人员可以同时编辑同一个文件,而无需担心丢失任何工作或协调文件的所有权。
我需要将上周五的代码版本部署到生产环境中版本控制系统允许您对特定版本的文件进行标记,以便轻松查看或恢复这些版本。例如,您可以在进行重大重构项目之前为整个代码库打标记,以便在重构不成功时可以轻松回退到已知的良好状态。更常见的是,开发团队经常为代码的特定版本打标记,以便他们准确地知道哪个代码与特定发布一起部署。例如,您可以为部署为您产品的6.1.0版本的代码添加一个version-6-1-0的标记。当有人报告该产品版本的错误时,您就会知道要排查哪个版本的产品文件。
我希望所有的同事都能访问我的编辑代码当您编辑一个文件时,您的团队成员必须知道您已经编辑了它,并能够看到您的编辑内容。版本控制系统使您可以轻松地将您的编辑推送到一个集中的位置。然后其他团队成员可以将这些更改拉取到他们的本地计算机上,保持整个团队同步。
为什么Git如此受欢迎我们已经提到Git已成为主流的版本控制系统。为什么会这样?不同的Git用户可能会对其崛起给出不同的解释,但以下是一些可能有助于其崛起的特点。
渊源Git是Linus Torvalds为存储和管理Linux内核的源代码而发明的工具。事实上,Git最初被用来存储高知名度、成功并广泛采用的代码,如Linux内核,这无疑为其赢得了即时可信度和声望:如果对Linus和Linux来说足够健壮和可靠,那对您来说也是足够好的。
顺便一提,一个程序员负责启动两个重大软件项目——Linux和Git,这实在令人惊叹。这就像莎士比亚发明了铅笔,只是为了更容易地写他的剧本一样。
简单的分支管理正如您很快将了解到的,分支是任何版本控制系统中最重要的组成部分之一。Git从一开始就被设计成简单创建、使用和合并分支。开发人员可以轻松使用分支,鼓励他们使用大量的分支,这促进了安全和快速的开发工作流程。
速度Git非常快速。添加新文件、提交更改、恢复旧代码以及同步文件以合并协作者的编辑——这些操作都能在几秒钟内完成,即使是在大型项目中也是如此。特别是创建、使用和合并分支都是极快的操作,这也是开发人员喜欢使用Git的主要原因之一。
可靠性你可能认为可靠性对于任何版本控制系统来说都是基本的要求:如果版本控制系统丢失了你的文件或编辑,那它在其功能上就毫无用处。但是多年来,许多版本控制系统的可靠性都不到100%。我们其中一个人在2000年代初在一个由100人组成的开发团队工作时,使用的是当时具有主导地位的专有版本控制系统,尽管它被视为同类工具中最好的,但经常会丢失或混乱我们的编辑。
Git因其可靠性而闻名。这是一个复杂的工具,如果你不完全理解如何使用其命令,你可能会因为人为错误而意外丢失数据。但是几乎没有听说过Git因技术故障而导致数据丢失的情况。它受到全球无数怀疑论的软件工程师团队的信任,这种信任是完全值得的。
分布式架构在Git之前,许多版本控制系统使用的是集中式架构。这意味着要在文件上工作,你需要从中央服务器获取其最新版本,进行编辑,然后将该文件重新提交给中央服务器,以便其他团队成员可以访问它。
集中式架构存在一些问题。首先,一些(但并非全部)集中式版本控制系统会锁定你已经签出的文件,因此在你编辑这些文件时,其他人无法更改这些文件。这导致工作场所出现了很多“嘿,你完成了Foo.java吗?”的对话,这种工作流程令人尴尬、不便且烦人。
使用具有集中式架构的版本控制系统的第二个问题是,每当你需要签出文件或提交编辑时,你都需要连接到中央服务器。没有网络连接,你就无法有效地工作。虽然这个问题比以前少了,但还是有时候你在热点之间,仍然想要继续工作。
集中式架构还会产生单点故障。如果服务器崩溃,所有开发人员都无法工作。如果服务器丢失数据或被物理破坏,恢复数据或重新建立硬件可能需要几天时间。
最后,随着团队规模的增长,集中式架构并不总是能良好扩展。依赖性能不足的版本控制系统服务器,并且团队迅速增长的团队可能会发现他们的工作被阻塞,因为他们需要排队访问该服务器。
幸运的是,Git构建的分布式架构解决了所有这些问题。当你在不同的计算机上有项目文件的许多副本时,这些问题就会消失。使用分布式版本控制系统时,每个开发人员在本地计算机上都有整个项目的副本。这包括所有的文件、编辑历史、标签、提交信息和其他元数据,使他们可以在没有与中央服务器连接的情况下对文件进行工作。
这种策略如何解决集中式版本控制系统所面临的问题呢?首先,如果每个开发人员都有项目中所有文件的本地副本,那么不存在锁定正在编辑的文件的概念:任何人都可以随时编辑他们本地的任何文件副本。其次,无需联系中央服务器即可签出文件,也无需联系服务器即可提交你的编辑。你可以在本地工作任意长的时间。确实,你最终需要将你的编辑同步到服务器上,以便你的同事可以看到你的编辑(你也可以看到他们的),但是你可以根据团队的需要决定频率高低。第三,由于每个开发人员的计算机上都有整个项目文件的副本,不再存在单点故障。如果用于同步更改的中央服务器崩溃,你可以将任何开发人员的计算机指定为临时中央服务器,同时重建原始服务器。最后,因为使用分布式版本控制系统的开发人员比使用集中式版本控制系统从中央服务器签入和签出文件的开发人员要少得多,所以分布式版本控制系统比集中式竞争对手具有更好的可扩展性。大多数使用Git的团队在新增成员时没有与版本控制系统相关的扩展问题。
Git的缺点还记得我们提到过Git之所以获得信任是因为它是由Linus Torvalds发明的吗?不幸的是,这也有一个缺点:它是根据Linus的思维而设计的,而不是你的。这意味着它的命令可能不一致、令人困惑和违反直觉。举个例子,让我们看看一个命令如何使用三种不同的方式来修改其行为:• git branch 列出所有可用的分支。• git branch foo 创建一个名为foo的新分支。• git branch --delete foo 删除名为foo的分支。
你可能会期望这些命令应该是以下方式:• git branch --list (这样也能实现但并非必需,没有人用它)• git branch --create foo• git branch --delete foo
但事实并非如此,你必须记住不同的选项语法。而且这只是一个命令而已。
Git的另一个大问题是它非常庞大。它有很多功能、选项和可配置的设置,这可能会让人感到不知所措。官方参考文档《Pro Git》有511页长!当你刚开始使用这个工具时,很容易产生这样的感觉:永远都无法对Git的概念和命令有足够的了解,以便能够高效地使用它,你可能会想知道其他人是如何理解和应对如此复杂的东西的。
幸运的是,你不需要了解Git的所有细节、不一致性和语法复杂性,也不需要了解Git提供的所有功能。你只需要了解少数常用命令及其变体,就可以完成你需要的95%的与Git相关的任务。大多数Git用户会随着时间的推移记住约20个常用操作,并在需要时查找其他Git操作的细节。所以,请不要恐慌,也不要试图学习和记忆Git的所有内容。如果你对本章描述的简单命令和概念感到舒适,那么你已经具备使用Git进行实际工作的能力。也许这就是你从这个工具中所需要的全部。
关于Git的介绍就到这里。现在,是时候来看一些实际的命令了。