Git内部原理剖析

正文共:13110字 ,预计阅读时间:33分钟

1. 导读

1.1. 为什么写这篇文章

写这篇文章的本意有二:

  1. 工作安排原因,常有同事询问我一些关于 Git 的问题,总觉得自己解释的不够透彻,因此觉得有必要深入了解一下。

  2. 目前中文的 Git 教程往往本末倒置, 一味从版本管理工具的角度去堆砌命令 ,而没有把握住Git的本质,导致读者知道的命令愈多,愈觉得 Git 复杂不友好。

本文中,笔者会通过实例演示+原理解释的方式进行剖析,并提出一些平时我们不易察觉的问题。

1.2. Git产生的背景

Git 诞生于2005年,当时 Linux 内核开发者可以免费使用 BitKeeper 作为源码管理工具,但是其作者认为部分开发者对 BitKeeper 进行逆向工程有悖原则,因而收回了使用权限,在这种危机时刻, Linus 再一次将个人英雄主义发挥到了极致,以主导设计开发了 Git 。根据这段背景我们需要意识到这么几个问题:

  1. Git 最早用来解决 Linux 内核的开发,因而其功能特点都是面向这种 参与者庞大且分散的协作开发模式设计的,企业的小团队可能体会不到 Git 的真正强大之处 。

  2. Git 的设计者和最早的使用者都是 Linux 内核开发者,比起 GUI 界面, 他们更喜欢命令行,更认同 Unix 的设计哲学 ,因而对于习惯了 GUI 界面的开发者(前端、移动端等)Git会显得十分“笨拙”。

理解这些背景对于我们认识 Git 十分重要,举一个例子,我们希望看到所有代码分支的最后提交时间和提交者,这种功能是高度定制的,如果 GUI 工具没有提供,那我们便无能为力,但是 Git 可以,通过 灵活的参数和 Linux 强大的工具集( grep 、 awk ) ,我们可以自动封装出这个命令并使用:

gs_branch_last_commit() {
    git fetch --prune
    git for-each-ref --sort='-committerdate' --format="%(refname:short) %09 %(authorname) %09 %(committerdate:relative)"  \
        | grep  --line-buffered "origin" \
        | awk '{printf "%-50s%-25s%s %s %s\n",$1,$2,$3,$4,$5}'
}

最后需要强调的是, Git本意不是做一个版本管理工具,而是文件管理系统(Git is a content-addressable filesystem) ,正如Linux在早期的邮件中所述:

In many ways you can just see git as a filesystem - it’s content- addressable, and it has a notion of versioning, but I really really designed it coming at the problem from the viewpoint of a filesystemperson (hey, kernels is what I do), and I actually have absolutely zero interest in creating a traditional SCM system.


—Linus Torvalds

在读完本文后,相信读者能更深刻地理解这段话。

SCM(即 Software configuration management)是一种更广义的版本管理, Linus 更愿意直接将其解释为 Source Code Management。


1.3. SCM的三个问题

The Architecture of Open Source Applications (Volume 2) 中提到任何一个SCM软件都需要解决三个问题, 以保证软件在开发过程中任一时间的内容都可以被追溯,并使得不同开发者可以协作开发 。这三个问题是:

  1. 存储内容(Storing content)

  2. 追踪内容的变更(Tracking changes to the content (history including merge metadata))

  3. 向其他开发者分发内容及其变更(Distributing the content and history with collaborators)

Git也不例外,接下来本文将围绕这三个问题,并结合Git自身的一些特点,进行剖析。

2. 术语

由于读者可能对于Git的内部原理不甚熟悉,所以这里把专业词汇先列出来:

  • .git Directory & Working Directory: .git 目录是 Git 存储信息和操作信息的目录, Working Directory 是我们实际操作的目录。

  • Git Object: Git 对象,我们的文件、目录和提交记录都会以 Git Object 的格式存储在 .git 目录中。

  • Git Reference: Git 引用,我们的分支、远程分支、tag的索引都是已 Git Reference 的形式存储,本质是一个包含 SHA1 值的40个字符的16进制字符串。

  • SHA1: 所有的文件的内容都会通过该算法计算出其(其实还有一个header) SHA1值作为Git 对象的文件名(其实就是数据库中的Key)。

  • plumbing & porcelain: Git的

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值