原文: https://www.daolf.com/posts/g...
做者:Pierre de Wulf
译者:明明如月,责编:郭芮
来源:CSDN(ID:CSDNnews)
Git 是一个强大的工具,可是使用起来却不是很友好。若是程序员们可以真正花时间去理解 Git 的构成,将会避免不少没必要要的麻烦。java
如下为译文:git
初学 Git 就像一个不懂当地语言的人来到一个陌生的国家——若是你知道本身在哪,该去哪里,那还好。一旦你迷路了,那麻烦就大了。程序员
网上有不少学习 Git 基本命令的文章,可是本文并不属于这一类文章。我在此处将尝试提供一个不一样的学习思路。github
初学者通常都很惧怕 Git,很难不怕。毫无疑问,Git 是一个强大的工具,可是使用起来却不是很友好。使用 Git 要理解不少新的概念,将文件做为命令参数和不做为参数二者的含义截然不同。web
我认为要想克服这些困难,不只要学习 Git 的 commit 和 push 的用法。若是咱们可以真正花时间去理解 Git 的构成,将会避免不少没必要要的麻烦。面试
1、研究 .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
后面再讲。
该文件包含你的仓库配置,好比远程的 url ,你的邮箱和用户名等。每次你在控制台使用 git config...
都会对这里产生影响。
供 gitweb ( github 的一种前身) 使用,显示仓库的描述。
这是一个有趣的特性。Git 提供了一套脚本,能够在每一个有意义的 Git 阶段自动运行。这些被称为钩子的脚本能够在提交 (commit)、变基 (rebase)、拉取 ( pull ) 操做的先后运行。脚本命预示着它的执行时机。如咱们能够编写 pre-push 的做为钩子,进行推送代码前的检查。
你能够将不想被 git 管理的文件记录到 .gitignore 文件中。排除文件的意思是不想共享这个文件。例如你不想共享你的 IDE 自定义配置,将其添加到 .gitignore 文件中便可。
2、一次提交包含哪些内容?
每次你建立一个文件,并追踪它,git 都将把文件进行压缩并存储在本身的数据结构中。被压缩的对象将具备惟一的名称和 hash 值,并将存储到对象 (object) 目录中。
在研究对象目录以前,咱们必须明白一次提交的含义是什么。你可能会说,一次提交就是当前工做目录的一个快照,但事实远不止如此。
实际上,当你提交时,git 经过下面两个步骤对你的工做目录建立快照:
这里给出一个简化的过程,实际上整个过程有点复杂,将在之后的文章中给出详细的介绍。关注微信公众号:Java技术栈,在后台回复:git,能够获取我整理的 N 篇最新 Git 教程,都是干货。
一旦快照被建立出来,它将会被压缩,以哈希值命名。那么这些压缩的对象存在哪里呢?他们被存在 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 个部分:
若是咱们解压提交的文件:
// 经过查看提交历史,你能够轻松地查询到提交的哈希值 // 你都不须要复制完整的哈希值字符串, // 复制可以保证哈希值的惟一性的前面一段便可。 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 -0500 commit A
正如预想的同样,咱们看到了快照的哈希值、做者信息和提交的注释。
有两个很是重要的事项:
那么,在快照中存的是啥呢?
git cat-file -p 86550c31847e518e1927f95991c949fc14efc711 100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 file_1.txt
咱们找到以前存储的最后一个对象,也是咱们快照中的惟一的一个对象。它是一个 blob 对象,这是另外的知识点,不在这里讨论。
关注微信公众号:Java技术栈,在后台回复:git,能够获取我整理的 N 篇最新 Git 教程,都是干货。
3、分支, 标签, HEAD 都同样
你如今已经了解到,git 中的全部内容均可以经过正确的哈希值来获取到。如今让咱们聚焦于 HEAD。那么什么是 HEAD?
cat HEAD ref: refs/heads/master
HEAD 不是一个哈希,HEAD 能够理解为指向你正在使用的分支的顶端的指针。咱们接下来看下 refs/heads/master:
cat refs/heads/master 4cf44f1e3fe4fb7f8aa42138c324f63f5ac85828
看起来眼熟吗?这和咱们第一次提交的哈希值相同。这代表分支 ( branch) 和标签 (tag) 只不过是一个指向提交的指针。这就意味着,即便你删掉了你要删除的分支和标签,他们指向的提交依然还在那里,只不过删除后难获取这些提交更困难一些。若是你想了解更详细的内容,能够经过 git book 来学习。
4、写在最后
因此学到这里,你应该明白 git 提交就是把你当前工做目录的文件“压缩”,而后将其和其余信息一块儿存储到对象文件夹中。若是你对 git 足够熟悉,你就会知道哪些文件会包含在提交中,哪些文件不会被提交。
我这里说的提交,并非指你的工做目录快照,而是指你要提交的文件快照。在实际执行以前,git 会在哪里存储你要提交的文件?它将他们存储到索引文件中。不过,咱们暂时不打算深刻研究它。若是你真的感兴趣,能够经过这里(https://github.com/git/git/bl...)深刻学习。
感谢阅读!但愿经过阅读本文,你可以学到有价值的内容。但愿本文可以帮你更轻松地使用 git。
推荐去个人博客阅读更多:
2.Spring MVC、Spring Boot、Spring Cloud 系列教程
3.Maven、Git、Eclipse、Intellij IDEA 系列工具教程
生活很美好,明天见~