Git 是一个强大的工具,但是使用起来却不是很友好。如果程序员们能够真正花时间去理解 Git 的构成,将会避免很多不必要的麻烦。

作者 | Pierre de Wulf

译者 | 明明如月,责编 | 郭芮

出品 | CSDN(ID:CSDNnews)

以下为译文:

初学 Git 就像一个不懂当地语言的人来到一个陌生的国家——如果你知道自己在哪,该去哪里,那还好。一旦你迷路了,那麻烦就大了。

网上有很多学习 Git 基本命令的文章,但是本文并不属于这一类文章。我在此处将尝试提供一个不同的学习思路。

初学者一般都很害怕 Git,很难不怕。毫无疑问,Git 是一个强大的工具,但是使用起来却不是很友好。使用 Git 要理解很多新的概念,将文件作为命令参数和不作为参数两者的含义大相径庭。

我认为要想克服这些困难,不仅要学习 Git 的 commit 和 push 的用法。如果我们能够真正花时间去理解 Git 的构成,将会避免很多不必要的麻烦。

研究 .git 目录

好的,我们现在开始吧。

当你通过 git init 创建 git 仓库时, git  就会创建 .git 目录。该目录包含让 git 能够正常工作所需的所有信息。直白点说,如果你不想在项目中继续使用 git ,直接将 .git 目录删除只保留项目文件即可。但是为什么这样做就可以呢?

下面是你第一次提交后 .git 文件夹的样子:

 ├── HEAD├── branches├── config├── description├── hooks│ ├── pre-commit.sample│ ├── pre-push.sample│ └── ...├── info│ └── exclude├── objects│ ├── info│ └── pack└── refs├── heads└── tags
  • HEAD

    后面再讲。

  • config (配置)

    该文件包含你的仓库配置,比如远程的 url ,你的邮箱和用户名等。每次你在控制台使用 git config... 都会对这里产生影响。

  • description(描述)

    供 gitweb ( github  的一种前身) 使用,显示仓库的描述。

  • hooks (钩子)

    这是一个有趣的特性。 Git 提供了一套脚本,可以在每个有意义的 Git 阶段自动运行。这些被称为钩子的脚本可以在提交 (commit)、变基 (rebase)、拉取 ( pull ) 操作的前后运行。脚本命预示着它的执行时机。如我们可以编写 pre-push 的作为钩子,进行推送代码前的检查。

  • info (信息)

    你可以将不想被 git 管理的文件记录到 .gitignore 文件中。排除文件的意思是不想共享这个文件。例如你不想共享你的 IDE 自定义配置,将其添加到 .gitignore 文件中即可。

一次提交包含哪些内容?

每次你创建一个文件,并追踪它,git 都将把文件进行压缩并存储在自己的数据结构中。被压缩的对象将具有唯一的名称和 hash 值,并将存储到对象 (object) 目录中。

在研究对象目录之前,我们必须明白一次提交的含义是什么。你可能会说,一次提交就是当前工作目录的一个快照,但事实远不止如此。

实际上,当你提交时,git 通过下面两个步骤对你的工作目录创建快照:

  • 如果文件没啥变化,git 只是将压缩的文件(哈希值)添加到快照中。

  • 如果文件发生了变化, git 将对其进行压缩并将其存储在 object 文件夹。最终,将这个压缩文件的名称(哈希值)添加到快照中。

这里给出一个简化的过程,实际上整个过程有点复杂,将在以后的文章中给出详细的介绍。

一旦快照被创建出来,它将会被压缩,以哈希值命名。那么这些压缩的对象存在哪里呢?他们被存在 object 文件夹中。

├── 4c
│ └── f44f1e3fe4fb7f8aa42138c324f63f5ac85828 // hash
├── 86
│ └── 550c31847e518e1927f95991c949fc14efc711 // hash
├── e6
│ └── 9de29bb2d1d6434b8b29ae775ad8c2e48c5391 // hash
├── info // let's ignore that
└── pack // let's ignore that too

这是我创建了一个空的文件  1.txt 并提交后 object 文件夹的样子。请注意,如果你的文件哈希值为 "4cf44f1e…",git 会将其存储到 "4c"子目录中,并将其命名为"f44f1…"。这个小技巧,将 /objects 目录的数量减少到 255 个以内。

你要记住的是,一次提交包含 4 个部分:

  1. 工作目录快照名称(一个哈希值)。

  2. 一条评论/注释。

  3. 提交者信息。

  4. 父提交的哈希值。

如果我们解压提交的文件:

// 通过查看提交历史,你可以轻松地查询到提交的哈希值
// 你都不需要复制完整的哈希值字符串,
// 复制能够保证哈希值的唯一性的前面一段即可。
git cat-file -p 4cf44f1e3fe4fb7f8aa42138c324f63f5ac85828

得到下面的内容:

tree 86550c31847e518e1927f95991c949fc14efc711
author Pierre De Wulf <test[@gmail.com](mailto:pierredewulf31@gmail.com)> 1455775173 -0500
committer Pierre De Wulf <[test@gmail.com](mailto:pierredewulf31@gmail.com)> 1455775173 -0500commit A

正如预想的一样,我们看到了快照的哈希值、作者信息和提交的注释。

有两个非常重要的事项:

  • 正如所预想的那样,快照的哈希 "86550…" 也是一个对象,你可以在对象文件夹中找到它。

  • 因为这是第一次提交,所以没有父提交的哈希值。

那么,在快照中存的是啥呢?

git cat-file -p 86550c31847e518e1927f95991c949fc14efc711100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 file_1.txt

我们找到之前存储的最后一个对象,也是我们快照中的唯一的一个对象。它是一个 blob 对象,这是另外的知识点,不在这里讨论。

分支, 标签, HEAD 都一样

你现在已经了解到,git 中的所有内容都可以通过正确的哈希值来获取到。现在让我们聚焦于 HEAD。那么什么是 HEAD?

cat HEAD
ref: refs/heads/master

HEAD 不是一个哈希,HEAD 可以理解为指向你正在使用的分支的顶端的指针。我们接下来看下 refs/heads/master:

cat refs/heads/master
4cf44f1e3fe4fb7f8aa42138c324f63f5ac85828

看起来眼熟吗?这和我们第一次提交的哈希值相同。这表明分支 ( branch) 和标签 (tag) 只不过是一个指向提交的指针。这就意味着,即使你删掉了你要删除的分支和标签,他们指向的提交依然还在那里,只不过删除后难获取这些提交更困难一些。如果你想了解更详细的内容,可以通过 git book 来学习。

写在最后

所以学到这里,你应该明白 git 提交就是把你当前工作目录的文件“压缩”,然后将其和其他信息一起存储到对象文件夹中。如果你对 git 足够熟悉,你就会知道哪些文件会包含在提交中,哪些文件不会被提交。

我这里说的提交,并不是指你的工作目录快照,而是指你要提交的文件快照。在实际执行之前,git 会在哪里存储你要提交的文件?它将他们存储到索引文件中。不过,我们暂时不打算深入研究它。如果你真的感兴趣,可以通过这里(https://github.com/git/git/blob/master/Documentation/technical/index-format.txt)深入学习。

感谢阅读!希望通过阅读本文,你能够学到有价值的内容。希望本文能够帮你更轻松地使用 git。

原文:https://www.daolf.com/posts/git-series-part-1/

译者:明明如月,知名互联网公司 Java 高级开发工程师,CSDN 博客专家。

本文为 CSDN 翻译,转载请注明来源出处。

推荐阅读 

☞钉钉跃居 App Store 榜首背后,全民云办公时代来临?

☞远程办公 4 大坑,坑坑“致命”!

☞连登 GitHub TOP 榜,中国开发者在行动!

☞揭秘阿里、腾讯、字节跳动在家办公的区别

☞深度好文!新浪微博架构师详析微博云原生技术的思考与实践

☞2020年区块链和分布式账本技术的5大趋势

你点的每一个在看,我认真当成了喜欢

通过 .git 目录深入理解 Git!相关推荐

  1. 一个 .git 目录,领悟 Git 的强大!

    Git 是一个强大的工具,但是使用起来却不是很友好.如果程序员们能够真正花时间去理解 Git 的构成,将会避免很多不必要的麻烦. 以下为译文: 初学 Git 就像一个不懂当地语言的人来到一个陌生的国家 ...

  2. 理解git结构与简单操作(四)合并分支的方法与策略

    接上节,此时的dev分支与master分支的进度就不一样了,所以需要将dev分支与master分支同步.这里需要的就是合并分支的操作,大家应该都知道用git merge或者git rebase. gi ...

  3. Git 之二 架构、工作流程、.git 目录文件

    写在前面   Git 的官网上有很详细的使用教程(当然有翻译版本),具体地址是 https://git-scm.com/book/zh/v2.唯一不足就是,很多讲解并没有实机演示.但是,毫无疑问,官网 ...

  4. 如何删除.git目录

    这篇文章主要介绍"如何删除.git目录"的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇"如何删除.git目录"文章能帮助大 ...

  5. Git清理过大的git目录objects文件

    Git清理过大的git目录objects文件 Git清理过大的git目录objects文件 1. git rev-list --objects --all | grep "$(git ver ...

  6. Git 经验总结及 Git GitHub 学习指南

    1. 前言 本文主要分为两部分,前一部分是本人学习和工作中使用 Git 的总结经验,后半部分是总结的 Git & GitHub 的学习指南.如果想直接体系学习,可以直接按照指南路线学习.如果你 ...

  7. 【代码管理】GitHub超详细图文攻略 - Git客户端下载安装 GitHub提交修改源码工作流程 Git分支 标签 过滤 Git版本工作流

    GitHub操作总结 : 总结看不明白就看下面的详细讲解. . 作者 :万境绝尘  转载请注明出处 : http://blog.csdn.net/shulianghan/article/details ...

  8. Git之深入解析Git的安装流程与初次运行Git前的环境配置

    一.版本控制 什么是"版本控制"? 版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统,对保存着软件源代码的文件作版本控制,但实际上,可以对任何类型的文件 ...

  9. php怎么像git那样做diff,Git 基本操作

    Git 的工作就是创建和保存你项目的快照及与之后的快照进行对比.本章将对有关创建与提交你的项目快照的命令作介绍. 获取与创建项目命令 git init 用 git init 在目录中创建新的 Git ...

最新文章

  1. Confluence 6 应该如何在我的空间中组织内容
  2. 最近在学OpenGL和英语
  3. php post收不到值,php 取不到POST 值
  4. DNS高级部署使用RSYNC部署搭建DNS view主从服务
  5. rust如何改睡袋_腐蚀rust怎么做睡袋 | 手游网游页游攻略大全
  6. 【渝粤题库】广东开放大学 C语言程序设计 形成性考核
  7. java的for循环取出数据只是拿到最后一个_新兴大数据分析榆中百合
  8. python复制sheet_python excel sheet复制
  9. 【华为云技术分享】使用keil5打开GD32F450i的MDK项目出现的问题以及J-Link无法烧录程序对应的解决方案
  10. 四川省盐业学校九五计算机,2020年四川省盐业学校招生录取分数线
  11. 架构篇:大型分布式Web系统的架构演进
  12. JQ 对于table的动态增减
  13. 虚拟服务器怎么搭建php,怎样搭建Apache+MySQL+PHP服务器
  14. 2019年,免费的检测僵尸粉软件《雪球微信小助手》,无打扰检测清理微信僵尸粉
  15. 串口485接法图_485通讯接线方式
  16. 非常详细的STM32 CAN通信的贴子,从总线细节到编程实现
  17. 细谈永恒之蓝,实现复现
  18. 2023年全国最新工会考试精选真题及答案10
  19. LD3320语音识别模块:LDV7模块使用详解
  20. PHP - strtotime()的慎用

热门文章

  1. java实现webservice
  2. golang 的time包之time
  3. js王者归来之正则表达式
  4. 【docker】【pycharm】pycharm配置docker远程连接
  5. leetcode python3 简单题121. Best Time to Buy and Sell Stock
  6. Golang并发编程组件
  7. 强化学习数学基础1---Policy Gradient
  8. Flutter基础—根据用户输入改变控件
  9. Serverless 崛起背后的五大挑战
  10. python中oserror捕获_Python assert异常处理(一看即懂)