Git 提交是差异、快照还是历史记录?

Git入门看这一篇就够了 Git起步入门篇 阅读详情

大家好!我一直在慢慢摸索如何解释 Git 中的各个核心理念(提交、分支、远程、暂存区),而提交这个概念却出奇地棘手。

要明白 Git 提交是如何实现的对我来说相当简单(这些都是确定的!我可以直接查看!),但是要弄清楚别人是怎么看待提交的却相当困难。所以,就像我最近一直在做的那样,我在 Mastodon 上问了一些问题。

大家是怎么看待 Git 提交的?

我进行了一个非常不科学的调查,询问大家是怎么看待 Git 提交的:是快照、差异,还是所有之前提交的列表?(当然,把它看作这三者都是合理的,但我很好奇人们的 主要 观点)。这是调查结果:

图片

结果是:

◈ 51% 差异

◈ 42% 快照

◈ 4% 所有之前的提交的历史记录

◈ 3% “其他”

我很惊讶差异和快照两个选项的比例如此接近。人们还提出了一些有趣但相互矛盾的观点,比如 “在我看来,提交是一个差异,但我认为它实际上是以快照的形式实现的” 和 “在我看来,提交是一个快照,但我认为它实际上是以差异的形式实现的”。关于提交的实际实现方式,我们稍后再详谈。

在我们进一步讨论之前:我们的说 “一个差异” 或 “一个快照” 都是什么意思?

什么是差异?

我说的“差异”可能相当明显:差异就是你在运行 git show COMMIT_ID 时得到的东西。例如,这是一个 rbspy 项目中的拼写错误修复:

  1. diff --git a/src/ui/summary.rs b/src/ui/summary.rs

  2. index 5c4ff9c..3ce9b3b 100644

  3. --- a/src/ui/summary.rs

  4. +++ b/src/ui/summary.rs

  5. @@ -160,7 +160,7 @@ mod tests {

  6. ";

  7. let mut buf: Vec<u8> = Vec::new();

  8. - stats.write(&mut buf).expect("Callgrind write failed");

  9. + stats.write(&mut buf).expect("summary write failed");

  10. let actual = String::from_utf8(buf).expect("summary output not utf8");

  11. assert_eq!(actual, expected, "Unexpected summary output");

  12. }

你可以在 GitHub 上看到它:项目地址

什么是快照?

我说的 “快照” 是指 “当你运行 git checkout COMMIT_ID 时得到的所有文件”。

Git 通常将提交的文件列表称为 “树”(如“目录树”),你可以在 GitHub 上看到上述提交的所有文件:

https://github.com/rbspy/rbspy/tree/24ad81d2439f9e63dd91cc1126ca1bb5d3a4da5b


(它是 /tree/ 而不是 /commit/)

“Git 是如何实现的”真的是正确的解释方式吗?

我最常听到的关于学习 Git 的建议大概是 “只要学会 Git 在内部是如何表示事物的,一切都会变得清晰明了”。我显然非常喜欢这种观点(如果你花了一些时间阅读这个博客,你就会知道我 喜欢 思考事物在内部是如何实现的)。

但是作为一个学习 Git 的方法,它并没有我希望的那么成功!通常我会兴奋地开始解释 “好的,所以 Git 提交是一个快照,它有一个指向它的父提交的指针,然后一个分支是一个指向提交的指针,然后……”,但是我试图帮助的人会告诉我,他们并没有真正发现这个解释有多有用,他们仍然不明白。所以我一直在考虑其他方案。

但是让我们还是先谈谈内部实现吧。

Git 是如何在内部表示提交的 —— 快照

在内部,Git 将提交表示为快照(它存储每个文件当前版本的 “树”)。下面是一个非常快速的内部格式概述。

这是一个提交的表示方式:

  1. $ git cat-file -p 24ad81d2439f9e63dd91cc1126ca1bb5d3a4da5b

  2. tree e197a79bef523842c91ee06fa19a51446975ec35

  3. parent 26707359cdf0c2db66eb1216bf7ff00eac782f65

  4. author Adam Jensen <adam@acj.sh> 1672104452 -0500

  5. committer Adam Jensen <adam@acj.sh> 1672104890 -0500

  6. Fix typo in expectation message

以及,当我们查看这个树对象时,我们会看到这个提交中仓库根目录下每个文件/子目录的列表:

  1. $ git cat-file -p e197a79bef523842c91ee06fa19a51446975ec35

  2. 040000 tree 2fcc102acd27df8f24ddc3867b6756ac554b33ef .cargo

  3. 040000 tree 7714769e97c483edb052ea14e7500735c04713eb .github

  4. 100644 blob ebb410eb8266a8d6fbde8a9ffaf5db54a5fc979a .gitignore

  5. 100644 blob fa1edfb73ce93054fe32d4eb35a5c4bee68c5bf5 ARCHITECTURE.md

  6. 100644 blob 9c1883ee31f4fa8b6546a7226754cfc84ada5726 CODE_OF_CONDUCT.md

  7. 100644 blob 9fac1017cb65883554f821914fac3fb713008a34 CONTRIBUTORS.md

  8. 100644 blob b009175dbcbc186fb8066344c0e899c3104f43e5 Cargo.lock

  9. 100644 blob 94b87cd2940697288e4f18530c5933f3110b405b Cargo.toml

这意味着检出一个 Git 提交总是很快的:对 Git 来说,检出昨天的提交和检出 100 万个提交之前的提交一样容易。Git 永远不需要重新应用 10000 个差异来确定当前状态,因为提交根本就不是以差异的形式存储的。

快照使用 packfile 进行压缩

我刚刚提到了 Git 提交是一个快照,但是,当有人说 “在我看来,提交是一个快照,但我认为它在实现上是一个差异” 时,这其实也是对的!Git 提交并不是以你可能习惯的差异的形式表示的(它们不是以与上一个提交的差异的形式存储在磁盘上的),但基本的直觉是,如果你要对一个 10,000 行的文件编辑 500 次,那么存储 500 份文件的效率会很低。

Git 有一个将文件以差异的形式存储的方法。这被称为 “packfile”,Git 会定期进行垃圾回收,将你的数据压缩成 packfile 以节省磁盘空间。当你 git clone 一个仓库时,Git 也会压缩数据。

这里,我没有足够的篇幅来完整地解释 packfile 是如何工作的(Aditya Mukerjee 的 《 解压 Git packfile》是我最喜欢的解释它们是如何工作的文章)。不过,我可以在这里简单总结一下我对 deltas 工作原理的理解,以及它们与 diff 的区别:

◈ 对象存储为 “原始文件” 和一个 “变化量(delta)” 的引用

◈ 变化量是一系列例如 “读取第 0 到 100 字节,然后插入字节 ‘hello there’,然后读取第 120 到 200 字节” 的指令。它从原始文件中拼凑出新的文本。所以没有 “删除” 的概念,只有复制和添加。

◈ 我认为变化量的层次较少:我不知道如何检查 Git 究竟要经过多少层变化量才能得到一个给定的对象,但我的印象是通常不会很多。可能少于 10 层?不过,我很想知道如何才能真正查出来。

◈ 原始文件不一定来自上一个提交,它可以是任何东西。也许它甚至可以来自一个更晚的提交?我不确定。

◈ 没有一个 “正确的” 算法来计算变化量,Git 只是有一些近似的启发式算法

当你查看差异时,实际上发生了一些奇怪的事情

当我们运行 git show SOME_COMMIT 来查看某个提交的差异时,实际上发生的事情有点反直觉。我的理解是:

1. Git 会在 packfile 中查找并应用变化量来重建该提交和其父提交的树。

2. Git 会对两个目录树(当前提交的目录树和父提交的目录树)进行差异比较。通常这很快,因为几乎所有的文件都是完全一样的,所以 git 只需比较相同文件的哈希值就可以了,几乎所有时候都不用做什么。

3. 最后 Git 会展示差异

所以,Git 会将变化量转换为快照,然后计算差异。它感觉有点奇怪,因为它从一个类似差异的东西开始,最终得到另一个类似差异的东西,但是变化量和差异实际上是完全不同的,所以这是说得通的。

也就是说,我认为 Git 将提交存储为快照,而 packfile 只是一个实现细节,目的是节省磁盘空间并加快克隆速度。我其实从来没必要知道 packfile 是如何工作的,但它确实能帮助我理解 Git 是如何在不占用太多磁盘空间的情况下将提交快照化的。

一个 “错误的” Git 理解:提交是差异

我认为一个相当常见的,对 Git 的 “错误” 的理解是:

◈ 提交是以基于上一个提交的差异的形式存储的(加上指向父提交的指针和作者和消息)。

◈ 要获取提交的当前状态,Git 需要从头开始重新应用所有之前的提交。

这个理解当然是错误的(在现实中,提交是以快照的形式存储的,差异是从这些快照计算出来的),但是对我来说它似乎非常有用而且有意义!在考虑合并提交时会有一点奇怪,但是或许我们可以说这只是基于合并提交的第一个父提交的差异。

我认为这个错误的理解有的时候非常有用,而且对于日常 Git 使用来说它似乎并没有什么问题。我真的很喜欢它将我们最常使用的东西(差异)作为最基本的元素——它对我来说非常直观。

我也一直在思考一些其他有用但 “错误” 的 Git 理解,比如:

◈ 提交信息可以被编辑(实际上不能,你只是复制了一个相同的提交然后给了它一个新的信息,旧的提交仍然存在)

◈ 提交可以被移动到一个不同的基础上(类似地,它们是被复制了)

我认为有一系列非常有意义的、 “错误” 的对 Git 的理解,它们在很大程度上都受到 Git 用户界面的支持,并且在大多数情况下都不会产生什么问题。但是当你想要撤销一个更改或者出现问题时,它可能会变得混乱。

将提交视为差异的一些优势

就算我知道在 Git 中提交是快照,我可能大部分时间也都将它们视为差异,因为:

◈ 大多时候我都在关注我正在做的 更改 —— 如果我只是改变了一行代码,显然我主要是在考虑那一行代码而不是整个代码库的当前状态

◈ 点击 GitHub 上的 Git 提交或者使用 git show 时,你会看到差异,所以这只是我习惯看到的东西

◈ 我经常使用变基,它就是关于重新应用差异的

将提交视为快照的一些优势

但是我有时也会将提交视为快照,因为:

◈ Git 经常对文件的移动感到困惑:有时我移动了一个文件并编辑了它,Git 无法识别它是否被移动过,而是显示为 “删除了 old.py,添加了 new.py”。这是因为 Git 只存储快照,所以当它显示 “移动 old.py -> new.py” 时,只是猜测,因为 old.py 和 new.py 的内容相似。

◈ 这种方式更容易理解 git checkout COMMIT_ID 在做什么(重新应用 10000 个提交的想法让我感到很有压力)

◈ 合并提交在我看来更像是快照,因为合并的提交实际上可以是任何东西(它只是一个新的快照!)。它帮助我理解为什么在解决合并冲突时可以进行任意更改,以及为什么在解决冲突时要小心。

其他一些关于提交的理解

Mastodon 的一些回复中还提到了:

◈ 有关提交的 “额外的” 带外信息,比如电子邮件、GitHub 拉取请求或者你和同事的对话

◈ 将“差异”视为一个“之前的状态 + 之后的状态”

◈ 以及,当然,很多人根据情况的不同以不同的方式看待提交

人们在谈论提交时使用的其他一些词可能不那么含糊:

◈ “修订”(似乎更像是快照)

◈ “补丁”(看起来更像是差异)

就到这里吧!

我很难了解人们对 Git 有哪些不同的理解。尤其棘手的是,尽管 “错误” 的理解往往非常有用,但人们却非常热衷于警惕 “错误” 的心智模式,所以人们不愿意分享他们 “错误” 的想法,生怕有什么 Git 解释者会站出来向他们解释为什么他们是错的。(这些 Git 解释者通常是出于善意的,但是无论如何它都会产生一种负面影响)

但是我学到了很多!我仍然不完全清楚该如何谈论提交,但是我们最终会弄清楚的。

感谢 Marco Rogers、Marie Flanagan 以及 Mastodon 上的所有人和我讨论 Git 提交。

(题图:DA/cc0cada9-4945-4248-8635-3f89dcebd6ef)

本文来自: Linux中国

在Unity中为Sentis部署的YOLOv8模型集成NMS层并实现移动端性能优化 本文详细讲解了在Unity中利用Sentis部署YOLOv8模型时,如何通过代码动态集成NMS层以解决移动端性能瓶颈。文章核心在于避免导出时绑定NMS,转而使用Sentis原生API在运行时高效构建NMS处理流程,并分享了关键的GPU数据操作与移动端性能优化技巧,确保模型在移动设备上流畅运行。 阅读详情

相关推荐

CSP-J 复试考点

可以用来训练思维,对于学习时间短的同学,动态规划可以帮助你迅速进入编程状态,也有助于帮你发现题目背后可能隐藏的更简便的算法。动态规划、贪心都是和子问题相关的,动态规划的基本思想是将一个大的问题划分成子问题,接着分别求解,而且能够将一些重复的计算记忆化,大大提高效率。难度加大,会涉及到二分、动态规划之类的算法,容易遗漏考虑点,不易得全分,考试的时候要注意全面性。一般是压轴题,算法不明显,剪枝的搜索、动态规划、状压 DP、树形 DP 、树、图等。枚举算法是指,列举出所有可能的取值,从中找出最优解。

GuanHeTian的博客 2214

git笔记

Git基础 每次提交Git都会创建所有文件的快照 ,并创建一个commit对象,commit对象中有指向文件快照的指针。 Git 有三种状态,你的文件可能处于其中之一: 已提交(committed)、已修改(modified) 和 已暂存(staged)。 已修改表示修改了文件,但还没保存到数据库中。 已暂存表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中。 已提交表示数据已经安全地保存在本地数据库中。 这会让我们的 Git 项目拥有三个阶段:工作区、暂存区以及 Git 目录。 基本

Warms的博客 420

kubeadm init 运行时kebelet启动失败问题

解决k8s kubeadm init时遇到的kubelet问题

ZDPZN的博客 6074

Git通讲-第二章(1):快照和不可变对象模型

上一篇文章主要介绍些Git起源背后的一些故事背景,从这篇开始将逐渐讲解Git的设计理念,包括分布式控制、快照管理、不可变对象模型和分支模型。其实上述概念都不是孤立的,在讲解中会发现它们是相辅相成的有机整体,实现1+1大于2的效果。接下来预计会按照快照模型与不可变对象模型分支模型分布式控制这样的顺序讲解,其用意到后面自会明了。本人总是从中能看到区块链的影子,之后会引入区块链的相关知识进行补充,也当是拓展了🫠。

2301_80272161的博客 1310

Unity中实现HLS视频加密与流式播放的完整方案

本文详细介绍了在Unity中实现HLS视频加密与流式播放的完整方案。针对Unity原生VideoPlayer无法直接支持实时解密的问题,提出了基于HLS协议与AES-128加密的成熟解决方案,并重点阐述了如何利用AVPro Video插件进行集成。文章涵盖了从密钥生成、使用FFmpeg进行视频加密切片,到在Unity中动态加载密钥并播放加密流的全流程,为保护付费课程、独家动画等视频内容提供了安全且高效的实践路径。

weixin_29290963的博客 393

2024.6.10丨基于DIAMOND与VFDB数据库的致病菌毒力因子高效注释指南

本文详细介绍了基于DIAMOND与VFDB数据库的致病菌毒力因子高效注释方法,涵盖工具安装、参数优化、数据库选择及实战案例解析。通过DIAMOND的快速比对和VFDB的全面毒力因子数据,显著提升微生物基因组研究效率,适用于临床检测、食品安全监测等多个场景。

weixin_33712987的博客 376

Git版本控制管理——提交

在Git中,提交是用来记录版本库的变更的。当提交时,Git会记录索引的快照并将快照放进对象库,该快照不包含该索引中任何文件或记录中的副本。Git会将当前索引的状态与之前的快照做一个比较,并派生出一个受影响的文件和目录列表,并会为任何有变化的文件创建新blob对象,对有变化的目录创建新的树对象,对于未改动的文件和目录则会沿用之前的blob与树对象。提交的快照是串联到一起的,每张新的快照指向其前驱,随着时间的推移,一系列变更就表示为一系列提交。版本库中的变更和提交时一一对应的关系,提交则是将变更引入版本库的唯一

止步听风的博客 2001

Supervisor 安装与使用

一、Supervisor 介绍 Supervisor 是一个用 Python 编写的进程管理工具,它可以用于监控和控制类 UNIX 操作系统上的多个进程。它是一个客户端/服务器系统,其中 Supervisor 的服务器端称为 supervisord,负责启动管理的子进程、响应客户端命令、重启崩溃或退出的子进程、记录子进程的 stdout 和 stderr 输出,以及处理子进程生命周期中的事件。客...

疯子丶pony的博客 3863

【git】-git的特点

【前言】 相信大家用SVN(Subversion)这款版本控制系统已经非常熟练了,检出代码、上传文件感觉小菜一碟,下面小编来给大家介绍另外一款脱颖而出的版本控制工具,它就是Git ,免费、开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。

全力奔跑,梦在彼岸 3745

AI产品经理必备:Agent评测维度、指标与工程化落地指南

随着大模型从单轮问答走向复杂的Agent应用,如何科学地评测一个Agent是否真正“办成了事”,成为AI产品经理必须掌握的核心能力。与传统大模型评测关注回答质量不同,Agent评测需要综合评估任务规划、工具调用、多轮对话一致性以及失败自愈等行为。任务完成率与工具调用成功率是最关键的两个量化指标,同时还需关注延迟与Token成本等工程约束。在实际落地中,评测集的设计要覆盖业务主流程与边界场景,并通过批量回归测试与版本对比,为产品选型、算法迭代和上线决策提供数据支持。本文系统拆解了Agent评测的完整流程,帮助

weixin_29057163的博客 341

piamon实战-- 如何使用 Paimon 的 Java API 实现数据的点查

点查(Point Lookup)是指通过 ​​唯一键(Primary Key)​​ 快速定位并返回单条或少量数据的查询模式。例如:根据用户 ID 查询用户信息、根据订单号查询订单详情等。点查的核心诉求是 ​​低延迟​​ 和 ​​高吞吐​​,适用于实时风控、在线分析等场景。​​定义主键表结构​​,优化数据分布。​​构建过滤条件​​,使用指定查询键。​​执行查询并处理结果​​,结合流式更新实现实时查询。

阿华田的博客 530

【Python练习】097. 编写一个函数,实现简单的版本控制工具

这篇文章介绍了一个简单的版本控制工具实现,包含初始化、文件添加、提交更改、历史查看和回滚功能。通过Python类封装核心逻辑,使用.versions目录存储文件版本,.history.txt记录变更历史。主要方法包括:__init__初始化版本库,add_file添加文件,commit提交更改,log查看历史,checkout回滚版本。工具通过计算文件MD5哈希值进行版本标识,适合理解版本控制基本原理。示例演示了从创建版本库到文件管理的完整流程,可作为轻量级版本控制系统的教学示例。

视睿 1099

[QMT量化交易小白入门]-四十九、中小盘策略是否还有未来,市值再平衡策略,年化收益率124%

该策略旨在通过定期再平衡持仓,保持投资组合中股票数量恒定(),并优先持有市值较小的股票。具体来说,策略每两天(period = 2)进行一次再平衡,根据当前市值对持仓进行调整,以实现微盘股的投资目标。中小市值策略对资金量要求有限制,资金量太大由于流动性不足,滑点可能较大,资金量太小,可能不能达到10-20只持仓,来分散风险,10-100w可能是比较理想的,后续可以根据波动率动态调仓,或波动率大于一定值时触发再平衡加入ROE或其他财务指标,或者研发投入强度大的专精特新企业,进行组合优化。

木头大左的博客 1184

Git之(四)分支管理

http://blog.youkuaiyun.com/u012152619/article/details/51964997 当我们初始化Git仓库的时候,Git会默认创建一个名为master的主分支。在实际工作中,主分支要求是一个稳定、健壮、安全的主线,一般不允许在主分支上直接进行开发,而是拉取一个新的分支,开发、测试完成后,再将分支合并到主分支上。 使用分支意味着你可以从开发主线上分离开来,然

bblo 294

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

git 命令里的存档和检出的区别

Git存档与检出是两种不同的源码操作方式。存档(git archive)生成不含Git历史记录的代码快照压缩包,适合分发部署;检出(git checkout/switch)则切换工作目录状态并保留完整Git仓库,用于日常开发。关键区别:存档是静态分发包,检出是动态开发环境。前者如汽车照片,后者如可驾驶的实车。

u010863983的博客 514

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

git的基本操作

设置全局: git config –global user.name “用户名”; git config –global user.email “邮箱名”; git config –list

qq_27219335的博客 132

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

git tag怎么使用_这才是真正的Git——Git内部原理揭秘!

本文以一个具体例子结合动图介绍了Git的内部原理,包括Git是什么储存我们的代码和变更历史的、更改一个文件时,Git内部是怎么变化的、Git这样实现的有什么好处等等。通过例子解释清楚上面这张动图,让大家了解Git的内部原理。如果你已经能够看懂这张图了,下面的内容可能对你来说会比较基础。视频链接:https://www.bilibili.com/video/av77252063PPT 链接:http...

weixin_39967938的博客 162

GIT Basics Notes

What's GIT? What is Git in a nutshell?This is an important section to absorb,because if you understand what Git is and the fundamentals of how it works,then using Git effectively will probably be muc...

weixin_30678349的博客 540

Git三个树

git三个树

qq_53318060的博客 176

Git:基础要点

直接快照,而非比较差异。 近乎所有操作都可本地执行。 在Git 中的绝大多数操作都只需要访问本地文件和资源,不用连网。但如果用CVCS 的话,差不多所有操作都需要连接网络。因为Git 在本地磁盘上就保存着所有有关当前项目的历史更新,所以处理起来速度飞快。 时刻保持数据完整性。在保存到Git 之前,所有数据都要进行内容的校验和(checksum)计算,并将此结果作为数据的唯一标识和...

weixin_30822451的博客 60

Git篇(一): 读懂 Git:从 Linux 安装到底层目录、版本回退完整拆解

反复修改代码、迭代功能、修复 bug记录每一次代码变更,随时回溯任意版本解决代码冲突、同步迭代进度。

2502_94387000的博客 974

Git回退实战:reset三种模式与reflog恢复指南

版本控制是软件开发的基础设施,而Git凭借其强大的历史记录能力,成为最流行的分布式版本管理工具。Git的核心并非保存文件差异,而是通过commit对象构建不可变的快照链,配合HEAD与分支指针实现高效切换。理解“指针移动而非内容删除”这一本质,是掌握回退操作的关键。git reset提供soft、mixed、hard三种模式,分别对应HEAD、暂存区、工作区的不同对齐策略,适用于撤销提交、重组暂存、彻底重置等场景。当误操作发生后,reflog作为本地仓库的“后悔药”,能帮助找回被reset丢弃的commit

weixin_42523670的博客 280

Git常用命令的使用情景

原文地址:http://shanewfx.github.io/blog/2012/04/28/git-command-note/ 本文尽量指出在不同情景下如何选择合适的Git命令来达到自己的目的,当然,由于Git太过强大、灵活,有时同一问题可以有多种不同的解决方案,这里不太可能全部列出,只会选择一些自己测试可用的方法。 文中会稍微谈一些Git内部实现的细节,但不会太具体,同时这些内

nowlf_android的专栏 603

Git初入门笔记 2020.6.23

Git使用的理论基础 git 通过维护三棵树来进行版本维护 工作区域 Working Directory 暂存区域 Stage(Index) Git仓库 Repository(HEAD) 工作流程 在工作目录中添加 修改文件 将需要进行版本管理的文件放入暂存区域 将暂存区域的文件提交到Git仓库 文件状态 已修改 modified 已暂存 staged 已提交 committed 使用Git 创建工作目录 在命令提示符中, 切换到对应目录, 输入 git init 此时对应文件夹中会出现 .g

xyyandxyy的博客 211

Git结合GitHub常用命令

简介 GIT 学习手册简介 这是 Git 学习参考手册。目的是为学习与记忆 Git 使用中最重要、最普遍的命令提供快速翻阅。 这些命令以你可能需要的操作类型划分,并且将提供日常使用中需要的一些常用的命令以及参数。 本手册将从入门到精通指导大家。 首先,我们要从如何以 Git 的思维方式管理源代码开始。 如何以 GIT 的方式思考(这节可以不用看懂,接着看下面的内容,看完就全懂了。)...

ClareYu的博客 578

git

git版本控制系统1 关于版本控制一个或者一些文件,长期去要写操作,对于每个有意义的阶段往往我们会将之管理起来。原始的管理方式无非就是拷贝改名的方式,最好再备注好日期。但是版本过多你也会晕死。因此迫切需要一个专业的版本控制软件来帮助我们。我们可以通过版本控制在不容的版本之间切换,你对工作目录的增删改操作都可以恢复过来。这只是针对一个人的操作。如果一份源代码,两个人以上在不同的地方需要对这份代码进行...

java老乌龟的博客 210
上一篇: 裁员靠随机?谷歌资深工程师爆大料
下一篇: 推荐 3 个最近很火的 AI 开源项目
IT界那些事儿
博客等级 码龄6年 2万+粉丝 22原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值