Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >牛逼的Git!!!!!!!

牛逼的Git!!!!!!!

作者头像
沉默王二
发布于 2021-03-31 16:05:23
发布于 2021-03-31 16:05:23
67700
代码可运行
举报
文章被收录于专栏:沉默王二沉默王二
运行总次数:0
代码可运行

大家好,我是沉默王二。

顾名思义,版本控制系统(Version Control System)是一类用于追踪源代码改动的工具,这些工具可以帮助我们管理代码的历史记录,不仅如此,还可以让协作编码变得轻而易举。

VCS 通过一系列的快照(Snapshots)将某个文件夹以及内容保存起来,每个快照都包含了文件夹的完整状态。同时,VCS 还维护者快照的创建者信息以及其他相关信息。

大家都知道,版本控制系统非常重要!!!!!!即便你只是一个人在编码,它也可以帮助你创建项目的快照、记录每个改动、创建不同的分支等等。如果你参与的是多人协作,它更是一个无价之宝,你不仅可以看到别人对代码的修改,还可以同时解决由于并行开发带来的冲突。

版本控制系统可以轻松地帮助我们解决这些棘手的问题:

  • 当前模块是谁编写的?
  • 这个文件的这一行代码是什么时候被修改的?是谁做出的修改?修改的原因是什么?
  • 最近的 100 个版本中,哪个版本导致单元测试失败了?

版本控制系统有很多,其中最突出的代表就是 Git——关于它诞生的历史,可以参照我之前分享的一篇内容:一次改变世界的代码提交

如果我们从命令行接口开始学习 Git 的话,会感到非常的困惑,很多时候只能死记硬背一些命令行,然后像变魔法一样使用它们,一旦出现问题,就只能先保存一个分支,然后删掉当前项目,重新下载一份新的拷贝。

尽管 Git 的接口有些难懂,但它底层的设计和思想却非常的优雅。难懂的接口只能靠死记硬背,但优雅的底层设计则非常容易理解。我们可以通过一种自底向上的方式来学习 Git,先了解底层的数据模型,再学习它的接口。可以这么说,一旦搞懂了 Git 的数据模型,再学习它的接口并理解这些接口是如何操作数据模型的就非常容易了。

进行版本控制的方法很多,Git 拥有一个精心设计的模型,这使其能够支持版本控制所需的所有特性,比如维护历史记录、支持分支和团队协作。

Git 将顶级目录中的文件和文件夹称作集合,并通过一系列快照来管理历史记录。在 Git 的术语中,文件被称为 blob 对象(数据对象),也就是一组数据。目录则被称为 tree(树),目录中可以包含文件和子目录。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<root> (tree)
|
+- foo (tree)
|  |
|  + bar.txt (blob, contents = "hello world")
|
+- baz.txt (blob, contents = "git is wonderful")

顶层的树(也就是 root) 包含了两个元素,一个名为 foo 的子树(包含了一个 blob 对象“bar.txt”),和一个 blob 对象“baz.txt”。

版本控制系统是如何和快照进行关联的呢?线性历史记录是一种最简单的模型,它包含了一组按照时间顺序线性排列的快照。不过,出于种种原因,Git 没有采用这种模型。

在 Git 中,历史记录是一个由快照组成的有向无环图。“有向无环图”,听起来很高大上,但其实并不难理解。我们只需要知道这代表 Git 中的每个快照都有一系列的父辈,也就是之前的一系列快照。这些快照通常被称为“commit”,看起来好像是下面这样:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
o <-- o <-- o <-- o
            ^  
             \
              --- o <-- o

o 表示一次 commit,也就是一次快照。箭头指向了当前 commit 的父辈。在第三次 commit 之后,历史记录分叉成了两条独立的分支,这可能是因为要同时开发两个不同的特性,它们之间是相互独立的。开发完成后,这些分支可能会被合并为一个新的 commit,这个新的 commit 会同时包含这些特性,看起来好像是下面这样:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
o <-- o <-- o <-- o <---- o
            ^            /
             \          v
              --- o <-- o

Git 中的 commit 是不可改变的。当然了,这并不意味着不能被修改,只不过这种“修改”实际上是创建了一个全新的提交记录。

以伪代码的形式来学习 Git 的数据模型,可能更加通俗易懂。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 文件是一组数据
type blob = array<byte>

// 一个包含了文件和子目录的目录
type tree = map<string, tree | file>

// 每个 commit 都包含了一个父辈,元数据和顶层树
type commit = struct {
    parent: array<commit> // 父辈
    author: string // 作者
    message: string // 信息
    snapshot: tree // 快照
}

Git 中的对象可以是 blob、tree 或者 commit:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
type object = blob | tree | commit

Git 在存储数据的时候,所有的对象都会基于它们的安全散列算法进行寻址。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
objects = map<string, object>

def store(object):
    id = sha1(object)
    objects[id] = object

def load(id):
    return objects[id]

blob、tree 和 commit 一样,都是对象。当它们引用其他对象时,并没有真正在硬盘上保存这些对象,而是仅仅保存了它们的哈希值作为引用。

还记得之前的例子吗?

root 引用的 foo 和 baz.txt 就像下面这样:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
100644 blob 4448adbf7ecd394f42ae135bbeed9676e894af85    baz.txt
040000 tree c68d233a33c5c06e0340e4c224f0afca87c8ce87    foo

所有的快照都可以通过它们的哈希值来标记,但 40 位的十六进制字符实在是太难记了,很不方便。针对这个问题,Git 的解决办法是给这些哈希值赋予一个可读的名字,也就是引用(reference),引用是指向 commit 的指针,与对象不同,它是可变的,可以被更新,指向新的 commit。通常,master 引用通常会指向主分支的最新一次 commit。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
references = map<string, string>

def update_reference(name, id):
    references[name] = id

def read_reference(name):
    return references[name]

def load_reference(name_or_id):
    if name_or_id in references:
        return load(references[name_or_id])
    else:
        return load(name_or_id)

这样,Git 就可以使用“master”这样容易被记住的名称来表示历史记录中特定的 commit,而不需要再使用一长串的十六进制字符了。

在 Git 中,当前的位置有一个特殊的索引,它就是“HEAD”。

在硬盘上,Git 仅存储对象和引用,因为其数据模型仅包含这些东西。所有的 git 命令都对应着对 commit 树的操作。

Git 中还包含了一个和数据模型完全不行管的概念,叫做“暂存区”,它运行我们指定下次快照中要包含哪些改动。

下面,我们来看一下常用的 git 命令行接口,包含基础、分支与合并、远端操作、撤销和高级操作。

1)基础

  • git help <command>: 获取 git 命令的帮助信息
  • git init: 创建一个新的 git 仓库,其数据会存放在一个名为 .git 的目录下
  • git status: 显示当前的仓库状态
  • git add <filename>: 添加文件到暂存区
  • git commit: 创建一个新的提交
  • git log: 显示历史日志
  • git log --all --graph --decorate: 可视化历史记录(有向无环图)
  • git diff <filename>: 显示与上一次提交之间的差异
  • git diff <revision> <filename>: 显示某个文件两个版本之间的差异
  • git checkout <revision>: 更新 HEAD 和目前的分支

2)分支与合并

  • git branch: 显示分支
  • git branch <name>: 创建分支
  • git checkout -b <name>: 创建分支并切换到该分支
  • git merge <revision>: 合并到当前分支
  • git mergetool: 使用工具来处理合并冲突

3)远端操作

  • git remote: 列出远端
  • git remote add <name> <url>: 添加一个远端
  • git push <remote> <local branch>:<remote branch>: 将对象传送至远端并更新远端引用
  • git branch --set-upstream-to=<remote>/<remote branch>: 创建本地和远端分支的关联关系
  • git fetch: 从远端获取对象/索引
  • git pull: 相当于 git fetch; git merge
  • git clone: 从远端下载仓库

4)撤销

  • git commit --amend: 编辑提交的内容或信息
  • git reset HEAD <file>: 恢复暂存的文件
  • git checkout -- <file>: 丢弃修改

5)高级操作

  • git config: 定制化
  • git clone --shallow: 克隆仓库,但是不包括版本历史信息
  • git add -p: 交互式暂存
  • git blame: 查看最后修改某行的人
  • git stash: 暂时移除工作目录下的修改内容
  • git bisect: 通过二分查找搜索历史记录
  • .gitignore: 指定不追踪的文件

怎么样?这样学 Git 是不是就容易多了?先从跟上理解了 Git 的数据模型,然后在执行命令的时候去思考这些命令是如何操作数目模型的,就会不那么枯燥了。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-03-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 沉默王二 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
终于有人把 Git 的数据模型讲清楚了!
上一篇,我们讲了 Git 的前世今生,神——Linus在 10 天内就创造了 Git 的第一版,这一篇,我们来探究一下 Git 的数据模型。
沉默王二
2021/12/23
8100
Git简介与工作原理:了解Git的基本概念、版本控制系统和分布式版本控制的工作原理
本篇博客将带您了解Git版本控制系统的基本概念和工作原理。Git在现代软件开发中扮演着重要的角色,通过本文的介绍,您将了解Git的历史背景、核心概念、工作原理以及与分布式版本控制系统的优势比较。同时,我们还会介绍Git的基本操作、远程仓库与协作、解决代码冲突的方法和技巧,并提供Git常用命令的速查表供您参考。
猫头虎
2024/04/08
2.3K0
Git简介与工作原理:了解Git的基本概念、版本控制系统和分布式版本控制的工作原理
The Missing Semester of Your CS Education
主要是想起来自己vim还不太会用,所以说记得这个课程的vim教学不错,干脆就花时间看看整套课程,重点看一下vim的使用,我看的版本是社区的中文翻译版的文档,这些工具大多我都已经能够熟练使用了,所以就没去看英文的视频感觉有点浪费时间。
ek1ng
2022/08/10
2.1K0
The Missing Semester of Your CS Education
Git 看这一篇就够了
今天简单讲下 Git 的实现原理,知其所以然才能知其然;并且梳理了日常最常用的 12 个命令,分为三大类分享给你。
AI科技大本营
2020/06/28
7490
Git 看这一篇就够了
Git的核心概念
文章内容来自自己的理解 和 https://git-scm.com/book/en/v2 。
Java后端技术
2018/08/09
5100
Git的核心概念
通俗易懂的 Git 教程:核心概念
Git 是目前世界上最优秀的分布式版本控制系统。版本控制系统是能够随着时间的推进记录一系列文件的变化以便于你以后想要的退回到某个版本的系统。版本控制系统分为三大类:本地版本控制系统,集中式版本控制系统和分布式版本控制系统
用户4962466
2019/10/17
5980
【Git|GitHub|SSH|Sourcetree 上篇】Git环境搭建及核心概念学习
版本控制系统提供了能够满足以上需求的工具。Git 是版本控制系统的典范,而 GitHub 是一个为个人或团队操作 Git 储存库 ( Git Repositories) 提供了 Git 服务器和一系列非常实用的工具的网站 + 基础设施。它提供了报告代码错误、检查工具以及分配任务和任务状态等项目管理工具等等。
好吃懒洋洋
2022/11/15
1.7K0
【Git|GitHub|SSH|Sourcetree 上篇】Git环境搭建及核心概念学习
老曹眼中的Git
Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。大神就是大神,在开发了Linux之后,Git 是又一抗鼎之作。这是唯一的理由么?
半吊子全栈工匠
2018/08/22
6120
老曹眼中的Git
彻底掌握 Git:从零基础到高级实战的全方位教程
在现代软件开发中,版本控制系统(VCS)是不可或缺的工具,它帮助开发者管理代码的变更,协作开发,并保持项目的历史记录。Git 是目前最流行的分布式版本控制系统之一,广泛应用于开源和企业项目中。本文将带你从零开始,深入了解Git,掌握从基本操作到高级功能的使用方法。
屿小夏
2025/05/24
3130
跟着小程一起聊聊GIT那点事
同生活中的许多伟大事件一样,Git 诞生于一个极富纷争大举创新的年代。Linux 内核开源项目有着为数众广的参与者。绝大多数的 Linux 内核维护工作都花在了提交补丁和保存归档的繁琐事务上(1991-2002年间)。到 2002 年,整个项目组开始启用分布式版本控制系统 BitKeeper 来管理和维护代码。
小程故事多
2018/08/22
6000
跟着小程一起聊聊GIT那点事
《书生大模型实战营第3期》入门岛 学习笔记与作业:Git 基础知识
Git 是一种开源的分布式版本控制系统,广泛应用于软件开发领域,尤其是在协同工作环境中。
流川疯
2024/07/26
2600
《书生大模型实战营第3期》入门岛 学习笔记与作业:Git 基础知识
Git - 使用git不知道内部实现机制怎么行
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
洋仔聊编程
2019/09/25
4760
Git - 使用git不知道内部实现机制怎么行
Git工作/面试必知必会
一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。开发中,我们仅对保存着软件源代码的文本文件作版本控制管理,但实际可对任何类型的文件进行版本控制。
JavaEdge
2020/03/12
5140
Git工作/面试必知必会
深入了解Git:介绍及常用命令指南
当今软件开发领域中,版本控制是一个至关重要的概念,而Git作为最流行的分布式版本控制系统,发挥着不可替代的作用。本文将介绍Git的基本概念以及常用命令,帮助你更好地理解和使用这一强大的工具。
修己xj
2023/08/25
2700
深入了解Git:介绍及常用命令指南
告别Git恐惧症!一套课程搞定Win/Mac/Linux三端配置与核心原理
Git 配置级别:本地、全局、系统 ,本地优先级大于全局 ,全局大于系统 (local > global > system) 。
stark张宇
2025/10/09
450
Git工作/面试必知必会操作-命令行篇
一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。开发中,我们仅对保存着软件源代码的文本文件作版本控制管理,但实际可对任何类型的文件进行版本控制。
JavaEdge
2021/02/22
3190
Git工作/面试必知必会操作-命令行篇
【干货】教你打通Git的任督二脉
分布式版本控制系统( Distributed Version Control System,简称 DVCS )。
狼王编程
2021/06/01
4920
【干货】教你打通Git的任督二脉
Missing Semester
为什么说版本控制系统非常有用?即使您只是一个人进行编程工作,它也可以帮您创建项目的快照,记录每个改动的目的、基于多分支并行开发等等。和别人协作开发时,它更是一个无价之宝,您可以看到别人对代码进行的修改,同时解决由于并行开发引起的冲突。
用户7267083
2022/12/08
3.1K0
Git|仓库管理的知识要点与细节
简单说就是用于管理多人协同开发项目的技术。 没有进行版本控制或者版本控制本身缺乏正确的流程管理,在软件开发过程中将会引入很多问题,如软件代码的一致性、软件内容的冗余、软件过程的事物性、软件开发过程中的并发性、软件源代码的安全性,以及软件的整合等问题。 无论是工作还是学习,或者是自己做笔记,都经历过这样一个阶段!
DioxideCN
2022/08/05
4220
Git原理入门简析
Git 是当前流行的分布式版本控制管理工具,最初由 Linux Torvalds (Linux 之父) 创造,于 2005 年发布。
我没有三颗心脏
2019/08/19
4920
推荐阅读
相关推荐
终于有人把 Git 的数据模型讲清楚了!
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验