【Git教程】(一)基本概念 ——工作流、分布式版本控制、版本库 ~

Git教程 · 基本概念

  • 1️⃣ 为什么要用 Git
  • 2️⃣ 为什么要用工作流
  • 3️⃣ 分布式版本控制
  • 4️⃣ 版本库
  • 5️⃣ 简单的分支创建与合并
  • 🌾 总结

在本章中,将介绍一个分布式版本控制系统的设计思路,以及它与集中式版本控制系统的不同之处。除此之外,还将带你了解分布式版本库的具体工作方式,以及为什么我们会说,在Git 中创建分支和合并分支不是个大不了的问题。

在这里插入图片描述


1️⃣ 为什么要用 Git

Git的背后有着一个非常精彩的成功故事。2005年4月,Linus Torvalds 因不满当时任何
一个可用的开源版本控制系统,就亲自着手实现了Git。
时至今日,如果我们在 Google 中搜索 “git version control” 这几个关键词,都会看到数以百万计的返回结果。Git已经俨然成为了新型开源项目的一个标准。许多大型的开源项目都已经或正在计划迁移到Git 上来。

下面,我们来看一下这么多人之所以会选择 Git 的原因。

  • Git 允许我们利用分支来开展工作:在一个由多个开发者并行协作的项目中,开发者各自会有很多不同的开发路线。Git 的优势在于,它提供了一整套针对开发链的重新整合工具,以便我们对其进行合并、变基和捡取等操作。
  • 工作流上的灵活性:Git 非常灵活。不但单一开发者可以用它,敏捷团队也可以找到使用它工作的合适方法,甚至一个由众多开发者在不同的工作地点参与的大型国际项目也可以用它开发出一个很好的工作流。
  • 适合奉献合作:大多数开源项目所依靠的都是开发者的无私奉献。因此,让这种无私 奉献的方式尽可能地简单化是一件非常重要的事。而这在一个集中式的版本控制系统中通常是很难做到的,因为我们不可能让所有人都有权限去写版本库。但如果我们使用 Git, 那么每个人都先可以克隆一个独立的工作版本库,然后再对其进行后续的改动。
  • 高性能:Git在处理拥有许多文件且历史悠久的项目时速度也依然是非常快的。例如,使用 Git 将 Linux 内核源码的当前版本切换到6年前的旧版本时,在一台 MacBook Air上所需的时间不到1分钟。考虑这两个版本之间有着超过200000次的提交和40000个更改文件,这已经足以让人印象深刻了。
  • 强大的抗故障和抗攻击能力:由于项目历史被分散存储在多个分布式版本库中,因此 数据严重流失的可能性不大。再加上版本库中有着巧妙简单的数据结构,这确保了其中的数据即使在遥远的未来也仍然会被正确地解释。而且,它还使用了统一的加密校验,这使得攻击者难以对版本库进行篡改。
  • 离线开发与多点开发:分布式的体系结构可以使得离线开发或者边旅行边开发的方式变得非常容易。而且该结构在多点开发模式下,我们既不需要设置中央服务器,也不需要固定的网络连接。
  • 强大的开源社区:除官方提供的详细文档外,你还可以在该社区找到无数相关的手册、 论坛、维基网站等,另外还有各种工具生态系统、托管平台、出版物、服务以及针对各个开发环境的插件,整个社区都正在茁壮成长。
  • 可扩展性:Git 为用户提供了许多实用命令,其中包括了能使我们更便于直接访问其远程版本库的命令。这可以让Git 变得非常灵活,这种灵活性将允许其各种独立应用提供比默认的Git 版本更为强大的功能。

2️⃣ 为什么要用工作流

Git 非常灵活。可为多种不同的角色所用,从偶尔需要版本化少量 shell 脚本的单一系统 管理员,到 Linux 内核项目中的上百个开发人员,一切皆有可能。当然,这种灵活性不是没有代价的。在开始用Git来开展工作之前,你还必须要做一组决定。例如以下几种。

  • Git 中固然已经是分布式版本库。但你是真的打算只在本地工作,还是更愿意建立一个中央版本库?
  • Git 支持 push 和 pull 两种数据传输类型,但我们需要同时使用它们吗? 如果让你选, 你会选哪一个? 为什么不是另一个?
  • 分支与合并是 Git中两个强大的功能。但是,我们应该开多少个分支呢? 是根据每个软件功能来开? 还是针对每个发行版来开?还是只该有一个分支?

为了便于入门,下面我们来总结一下工作流及其作用。

  • 工作流指的是相关项目的日常操作规程。
  • 工作流会给出具体的步骤。
  • 工作流会显示必要的命令和选项。
  • 工作流非常适用于密切的团队合作,而目前的这些现代软件项目通常就出自这样的合作。
  • 一些工作流可能并不是目标问题唯一正确的解决方案,但它们是一个很好的起点,我们 可以从中为自己的项目开发出高效的工作流。

我们之所以会重点介绍商业项目中敏捷开发团队的工作,是因为我们相信目前许多专业 开发者(包括作者)都处于这样的工作环境中。当然,这里并不包括那些具有特殊要求的大 型项目,因为这些项目通常有着很夸张的工作流,而且我们相信这些也不是大多数开发者会 感兴趣的项目。另外,这里也不包括那些开源项目的开发,虽然这些项目也可以用 Git 规划出一个很有意思的工作流。


3️⃣ 分布式版本控制

在具体探讨分布式版本控制的概念之前,让我们先来快速回顾一下传统的集中式版本控制架构。
下图中所显示的就是一个集中式版本控制系统(例如 CVS 或 Subversion) 的典型布局。 每个开发者都在他或她自己的计算机上有一个包含所有项目文件的工作目录(即工作区)。当该开发者在本地做了修改之后,他或她就会定期将修改提交给某台中央服务器。然后,开发者在执行更新操作的同时也会从该服务器上捡取出其他开发者所做的修改。这台中央服务器上存储着这些文件(即版本库)的当前版本和历史版本。因此,这些被并行开发的分支,以及各种被命名(标记)的版本都将会被集中管理。


在这里插入图片描述

而在分布式版本控制系统(见上图)中,开发者环境与服务器环境之间是没有分隔的。 每一个开发者都同时拥有一个用于当前文件操作的工作区与一个用于存储该项目所有版本、 分支以及标签的本地版本库(我们称其为一份克隆)。每个开发者的修改都会被载入成一次次 的新版本提交(commit), 首先提交到其本地版本库中。然后,其他开发者就会立即看到新的版本。通过推送 (push) 和拉回 (pull) 命令,我们可以将这些修改从一个版本库传送到另一个 版本库中。这样一来,从技术上来看,这里所有的版本库在分布式架构上的地位是同等的。 因此从理论上来讲,我们不再需要借助服务器,就可以将某一台开发工作机上所做的所有修改直接传送给另一开发工作机。当然在具体实践中,Git 中的服务器版本库也扮演了重要的角色,例如以下这些特型版本库。

  • 项目版本库(blessed repository): 该版本库主要用于存储由“官方”创建并发行的版本。
  • 共享版本库(shared repository): 该版本库主要用于开发团队内人员之间的文件交换。 在小型项目中,项目版本库本身就可以胜任这一角色了。但在多点开发的条件下,我 们可能就会需要几个这样的专用版本库。
  • 工作流版本库(workflow repository): 工作流版本库通常只用于填充那些代表工作流 中某种特定进展状态的修改,例如审核通过后的状态等。
  • 派生版本库 ( fork repository):该版本库主要用于从开发主线分离出某部分内容(例如,分离出那些开发耗时较长,不适合在一个普通发布周期中完成的内容),或者隔离出可能永远不会被包含在主线中的、用于实验的那部分开发进展。

下面,我们再来看看分布式系统相对于集中式的优点有哪些。

  • 高性能:几乎所有的操作都无需进行网络访问,均可直接在本地执行。
  • 高效的工作方式:开发者可通过多个本地分支在不同任务之间进行快速切换。
  • 离线功能:开发者可以在没有服务器连接的情况下执行提交、创建分支、版本标签等 操作。之后再将其上传服务器。
  • 灵活的开发进程:我们可以在团队和公司中为其他部门建立专用的版本库,例如为方 便与测试人员交流而建的版本库。这样相关修改就很容易发布,因为只是特定版本库 上的一次推送。
  • 备份作用:由于每个开发者都持有一份拥有完整历史版本的版本库副本,所以因服务器故障而导致数据丢失的可能性是微乎其微的。
  • 可维护性:对于那些难以对付的重构工作,我们可以在将成功传送给其原始版本库之前,先在该版本库的副本上尝试一下。

4️⃣ 版本库

其实,版本库本质上就是一个高效的数据存储结构而已,由以下部分组成。

  • 文件(即 blob): 这里既包含了文本也包含了二进制数据,这些数据将不以文件名的 形式被保存。
  • 目录(即 Tree): 目录中保存的是与文件名相关联的内容,其中也会包含其他目录。
  • 版本(即 commit): 每一个版本所定义的都是相应目录的某个可恢复的状态。每当我们创建一个新的版本时,其作者、时间、注释以及其之前的版本都将会被保存下来。

对于所有的数据,它们都会被计算成一个十六进制散列值(例如像1632acb65b01c6b621d6e1105205773931bbla41 这样的值)。这个散列值将会被用作相关对象的引用,以及日后恢复数据时所需的键值(见下图)。


在这里插入图片描述

也就是说, 一个提交对象的散列值实际上就是它的“版本号”,如果我们持有某一提交的 散列值,就可以用它来检查对应版本是否存在于某一版本库中。如果存在,我们就可以将其 恢复到当前工作区相应的目录中。如果该版本不存在,我们也可以从其他版本库中单独导入(拉回)该提交所引用的全部对象。

接下来,我们来看看采用这种散列值和这种既定的版本库结构究竟有哪些优势。

  • 高性能:通过散列值来访问数据是非常快的。
  • 冗余度——释放存储空间:相同的文件内容只需存储一次即可。
  • 分布式版本号:由于相关散列值是根据文件,作者和日期来计算的,所以版本也可以 “离线”产生,不用担心将来会因此而发生版本冲突。
  • 版本库间的高效同步:当我们将某一提交从一个版本库传递给另一个版本库时,只需要传送那些目标版本库中不存在的对象即可。而正是因为有了散列值的帮助,我们才能很快地判断相关对象是否已经存在。
  • 数据完整性:由于散列值是根据数据的内容来计算的,所以我们可以随时通过Git 来查看某一散列值是否与相关数据匹配。以检测该数据上可能的意外变化或恶意操作。
  • 自动重命名检测: 被重命名的文件可以被自动检测到,因为根据该文件内容计算出的 散列值并没有发生变化。也正因为如此, Git 中并没有专用的重命名命令,只需移动命令即可。

5️⃣ 简单的分支创建与合并

对于大多数版本控制系统来说,分支的创建与合并通常会因其特殊性而被认为是高级拓展操作。但由于Git 最初就是为了方便那些散落在世界各地的Linux 内核开发者而创建的,合并多方努力的结果一直都是其面临的最大挑战之一 ,所以 Git 的设计目标之一就是要让分支的创建与合并操作变得尽可能地简单且安全。

在下面的图中,展示了开发者是如何通过创建分支的方式来进行并行开发 的。图中的每一个点都代表了该项目的一个版本(即commit) 。 而由于在Git 中,我们只能对整个项目进行版本化,所以每个点同时也代表了属于同一版本的各个文件。


在这里插入图片描述
如上所示,图中两位开发者的起点是同一个版本。之后两人各自做了修改,并提交了修 改。这时候,对于这两位开发者各自的版本库来说,该项目已经有了两个不同的版本。也就 是说,他们在这里创建了两个分支。接下来,如果其中一个开发者想要导入另一个人的修改, 他/她就可以用Git 来进行版本合并。如果合并成功了,Git 就会创建一个合并提交,其中会包含两位开发者所做的修改。这时如果另一位开发者也取回了这一提交,两位开发者的项目就又回到了同一个版本。

在上面的例子中,分支的创建是非计划性的,其原因仅仅是两个开发者在并行开发同一个软件罢了。在 Git 中,我们当然也可以开启有针对性的分支,即显式地创建一个分支(见下图)。显式分支通常主要用于协调某一种功能性的并行开发。


在这里插入图片描述

版本库在执行拉回和推送操作时,可以具体指定其针对的是哪一些分支。当然,除了这些简单的分支创建和合并处理外,我们也可以对分支执行以下动作。

  • 移植分支:我们可以直接将某一分支中的提交转移到另一个版本库中。
  • 只传送特定修改:我们可以将某一分支中的某一次或某几次提交直接复制到另一个分 支中。这就是所谓的捡取处理。
  • 清理历史:我们可以对分支历史进行改造、排序和删除。这有利于为该项目建立更好 的历史文档。我们称这种处理为交互式重订 (interactive rebasing)。

🌾 总结

在阅读完本文之后,你现在基本上熟悉了 Git 中的这些基本概念。也就是说, 即使你现在放下了这本书, 你也可以参加与分布式版本控制系统有关的讨论,阐述其中使用散列值的必要性和实用性,介绍 Git中的分支创建与合并操作了。

当然,你可能还会有以下疑问。

  • 我们应该如何利用这些基本概念来管理项目呢?
  • 我们应该如何协调多个版本库呢?
  • 我们究竟需要多少分支呢?
  • 我们应该如何整合自己的构建服务器呢?

对于第一个问题,可以继续阅读下一章内容。在下一章中,你将会看到那些具体用于创建版本库、版本以及版本库之间更替提交的命令。另外,如果你是一个繁忙的项目管理者,还在犹豫不决是否要采用Git 。建议再看看关于Git的局限性的的讨论,参见后续文章。



继续阅读下一篇(点击跳转)《》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/672075.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

区块链大解码:深入了解Web3的核心技术

随着技术的迅速发展,Web3正逐渐崭露头角,成为数字时代的引领者。其中,区块链技术作为Web3的核心,扮演着至关重要的角色。本文将深入解码区块链技术,探讨其在Web3时代的关键作用以及未来发展趋势。 1. 区块链基础原理 …

Windows 10 配置 FFmpeg 使用环境

Windows 10 配置 FFmpeg 使用环境 1.下载FFmpeg 的windows办2. 配置环境变量:3.查看是否配置正确 cmd 或者 PowerShell 执行以下命令 1.下载FFmpeg 的windows办 GitHub 地址 :https://github.com/BtbN/FFmpeg-Builds/releases 解压后得到如图: 2. 配置环境变量: 复制路径:…

java SpringBoot2.7整合Elasticsearch(ES)7 进行文档增删查改

首先 我们在 ES中加一个 books 索引 且带有IK分词器的索引 首先 pom.xml导入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency>applicatio…

基于A-Star搜索算法的迷宫小游戏的设计

这篇文章是作者人工智能导论课的大作业&#xff0c;发出来供大家学习参考&#xff08;有完整代码&#xff09;。想要论文WORD文件的可以在本文资源处下载&#xff08;可能还在审核&#xff09;。 摘要&#xff1a; 本文章聚焦于基于A-Star搜索算法的迷宫小游戏设计&#xff0c;…

AR特效自研AI算法技术解决方案

在当今这个高速发展的数字化时代&#xff0c;增强现实&#xff08;AR&#xff09;技术已经成为企业创新和市场竞争的重要手段。美摄科技凭借对AI技术的深厚积累&#xff0c;为企业提供了一套创新的AR特效自研AI算法技术解决方案&#xff0c;旨在满足企业在AR领域的多元化需求。…

选择大语言模型:2024 年开源 LLM 入门指南

作者&#xff1a;来自 Elastic Aditya Tripathi 如果说人工智能在 2023 年起飞&#xff0c;这绝对是轻描淡写的说法。数千种新的人工智能工具被推出&#xff0c;人工智能功能被添加到现有的应用程序中&#xff0c;好莱坞因对这项技术的担忧而戛然而止。 甚至还有一个人工智能工…

代码随想录 Leetcode46. 全排列

题目&#xff1a; 代码&#xff08;首刷自解 2024年2月6日&#xff09;&#xff1a; class Solution { private:vector<vector<int>> res;vector<int> path; public:void backtracking(vector<int>& nums, int depth, vector<bool>& us…

数据结构第十天(排序算法总结)

目录 前言 常数时间复杂度&#xff1a;O(1) 线性时间复杂度&#xff1a;O(n) 线性对数时间复杂度&#xff1a;O(n log n) 平方时间复杂度&#xff1a;O(n^2) 对数时间复杂度&#xff1a;O(log n) 前言 排序算法的学习可以告一段落了。但算法的学习永不停止。 今天&…

redis:七、集群方案(主从复制、哨兵模式、分片集群)和面试模板

redis集群方案 在Redis中提供的集群方案总共有三种&#xff08;一般一个redis节点不超过10G内存&#xff09; 主从复制哨兵模式分片集群 主从复制&#xff08;主从数据同步&#xff09; replid和offset Replication Id&#xff1a;简称replid&#xff0c;是数据集的标记&a…

C++集群聊天服务器 数据模块+业务模块+CMake构建项目 笔记 (上)

跟着施磊老师做C项目&#xff0c;施磊老师_腾讯课堂 (qq.com) 本文在此篇博客的基础上继续实现数据模块和业务模块代码&#xff1a; C集群聊天服务器 网络模块业务模块CMake构建项目 笔记 &#xff08;上&#xff09;-CSDN博客https://blog.csdn.net/weixin_41987016/article…

显示器校准软件:BetterDisplay Pro for Mac v2.0.11激活版下载

BetterDisplay Pro是一款由waydabber开发的Mac平台上的显示器校准软件&#xff0c;可以帮助用户调整显示器的颜色和亮度&#xff0c;以获得更加真实、清晰和舒适的视觉体验。 软件下载&#xff1a; BetterDisplay Pro for Mac v2.0.11激活版下载 以下是BetterDisplay Pro的主要…

【Linux取经路】探寻shell的实现原理

文章目录 一、打印命令行提示符二、读取键盘输入的指令三、指令切割四、普通命令的执行五、内建指令执行5.1 cd指令5.2 export指令5.3 echo指令 六、结语 一、打印命令行提示符 const char* getusername() // 获取用户名 {return getenv("USER"); }const char* geth…

LeetCode-第171题-Excel表的序列号

1.题目描述 给你一个字符串 columnTitle &#xff0c;表示 Excel 表格中的列名称。返回 该列名称对应的列序号 。 例如&#xff1a; A -> 1 B -> 2 C -> 3 ... Z -> 26 AA -> 27 AB -> 28 ... 2.样例描述 3.思路描述 遍历时将每个字母与 A 做减法&…

抖音创作服务平台的自适应,从2560到1024,做的真是棒呀。

不得不服&#xff0c;抖音创作服务平台的电脑页面&#xff0c;自适应效果做的非常好&#xff0c;从2560到1024这个跨度的分辨率都做了很好地处理。 2560 4K屏 1920 2K屏幕 1600 宽屏 1440 中宽屏 1366 笔记本屏 1280 窄屏 1024 超窄屏 768 pad端 这个出现横向滚动条了。 算是用…

虚拟飞控计算机:飞行控制系统验证与优化的利器

01.背景介绍 随着航空技术的飞速发展&#xff0c;飞行控制系统作为飞机的心脏&#xff0c;全面负责监测、调整和维持飞行器的姿态、航向、高度等参数&#xff0c;用以确保飞行的安全和稳定。为了满足这些要求&#xff0c;现代飞控系统通常采用先进的处理器和外设来确保其高效、…

一文简介Maven初级使用

一.概述 Maven是专门用于管理和构建Java项目的工具&#xff0c;它的主要功能有&#xff1a; 提供了一套标准化的项目结构提供了一套标准化的项目构建流程&#xff08;编译&#xff0c;测试&#xff0c;打包&#xff0c;发布&#xff09;提供了一套依赖管理机制 一方面&…

【Java EE】----Bean的作用域和生命周期

1.Bean的作用域 定义&#xff1a;Bean 的作⽤域是指 Bean 在 Spring 整个框架中的某种⾏为模式&#xff0c;⽐如 singleton 单例作⽤域&#xff0c;就 表示 Bean 在整个 Spring 中只有⼀份 &#xff08;产生的原因&#xff0c;Bean 默认情况下是单例状态&#xff08;singleton&…

隧道穿透:端口转发、socket隧道代理

目录 端口转发 lcx工具 Lcx工具正向连接 Lcx工具反向连接 SOCKET隧道代理 socks常见利用场景 Proxifier SocksCap64 Proxychains 端口转发 本篇会和搭建介绍一下端口转发和socket隧道代理的概念和简单演示 lcx工具 lcx工具是一个红队人员在内网渗透测试中最典型的端…

俩种方法解决 VScode中 NPM 脚本消失,NPM 脚本未显示在资源管理器侧栏中

npm脚本是npm包管理器的一个功能&#xff0c;允许开发者在package.json文件中定义一系列命令脚本&#xff0c;用于执行各种开发任务。 今天打开准备运行的时候发现找不到NPM脚本了&#xff0c;左侧的一栏完全没有显示&#xff0c;在网上查阅了很多资料后总结出俩个方法可以用来…

存算一体:架构创新,打破算力极限

1 需求背景 在全球数据量呈指数级暴涨&#xff0c;算力相对于AI运算供不应求的现状下&#xff0c;存算一体技术主要解决了高算力带来的高能耗成本矛盾问题&#xff0c;有望实现降低一个数量级的单位算力能耗&#xff0c;在功耗敏感的百亿级AIoT设备上、高能耗的数据中心、自动驾…