Git学习笔记--基础知识

虽然用了很久的git,但是也没有很好地总结下git,都是零零散散的,git其实就是用来代码管理的工具,代码管理主要完成两个功能,一个是备份,一个是代码的合并和分离。
其次android的所有源码都是一个一个git仓库,不过他是用repo来管理的,之后也把repo系统学习下。这里正好有时间可以把这个补上去,还是进入正题吧


1 git历史

  • 不管怎样都要从历史开始说起,摘抄一段来自维基百科的内容:
  • 自2002年开始,Linus Torvalds决定使用BitKeeper作为Linux内核主要的版本控制系统用以维护代码。因为BitKeeper为专有软件,这个决定在社区中长期遭受质疑。在Linux社区中,特别是Richard Matthew Stallman自由软件基金会的成员,主张应该使用开放源代码的软件来作为Linux核心的版本控制系统。Linus Torvalds曾考虑过采用现成软件作为版本控制系统(例如Monotone),但这些软件都存在一些问题,特别是性能不佳。现成的方案,如CVS的架构,受到Linus Torvalds的批评。
  • 2005年,Andrew Tridgell写了一个简单程序,可以连接BitKeeper的存储库,BitKeeper著作权拥有者Larry McVoy认为Andrew Tridgell对BitKeeper内部使用的协议进行逆向工程,决定收回无偿使用BitKeeper的授权。Linux内核开发团队与BitMover公司进行蹉商,但无法解决他们之间的歧见。Linus Torvalds决定自行开发版本控制系统替代BitKeeper,以十天的时间,编写出第一个git版本。

2 库目录

当我们clone一份代码的时候在当前目录下会有一个.git文件夹,其实几乎所有 Git 存储和操作的内容都位于该目录下,只要删除这个文件夹,就没有git仓库了。
关于这个文件夹下的内容主要如下:

  • hooks: 存储钩子的文件夹,主要是客户端或服务端钩子脚本,这个后面有机会再讲
  • logs: 存储日志的文件夹
  • refs: 存储指向数据 (分支) 的提交对象的指针
  • objects: 存储所有数据内容
  • config: 包含了项目特有的配置选项
  • HEAD: 指向当前所在分支的指针文件路径,一般指向refs下的某文件
  • info: 保存了一份不希望在 .gitignore 文件中管理的忽略模式 (ignored patterns) 的全局可执行文件
  • index: 保存了暂存区域信息

3 Git的4种对象

先认识下SHA-1:
在Git系统中,每个Git对象都有一个特殊的ID来代表这个对象,这个特殊的ID就是我们所说的SHA-1哈希值。SHA-1哈希值是通过SHA-1算法计算出来的哈希值,对于内容不同的对象,会有不同的SHA-1哈希值。

3.1 blob

这种对象用来保存文件的内容。比如c代码或者java代码就是其源代码本身。
在Git 数据库里存储一些文本:

$ echo 'test content' | git hash-object -w --stdin
d670460b4b4aece5915caf5c68d12f560a9fe3e4

执行后得到输出长度为40个字符的校验和。这是个SHA-1哈希值──其值为要存储的数据加上一种头信息的校验和,先看下这个校验和的数据。

$ find .git/objects -type f
.git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4

创建以该校验和前两个字符为名称的子目录,并以 (校验和) 剩下 38 个字符为文件命名 (保存至子目录下)
可以通过cat-file命令取出数据内容:

$ git cat-file -p d670460b4b4aece5915caf5c68d12f560a9fe3e4
test content

创建一个新文件,并把文件内容存储到数据库中

$ echo 'version 1' > test.txt
$ git hash-object -w test.txt
83baae61804e65cc73a7201a7252750c76066a30

再向文件中写入数据:

$ echo 'version 2' > test.txt
$ git hash-object -w test.txt
1f7a7a472abf3dd9643fd615f6da379c4acb3e3a

数据库中已经将这几次的改动都保存了下来了

$ find .git/objects -type f
.git/objects/1f/7a7a472abf3dd9643fd615f6da379c4acb3e3a
.git/objects/83/baae61804e65cc73a7201a7252750c76066a30
.git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4

可以看下type类型为:blob

$ git cat-file -t 83baae61804e65cc73a7201a7252750c76066a30
blob

3.2 tree

可以理解成一个对象关系树,它管理一些tree和blob对象。
新建仓库,建立如下文件和文件夹:

$ tree
.
├── lib
│   └── simplegit.rb
├── Makefile
└── README

查看tree对象如下所示:

$ git cat-file -p master^{tree}
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391    Makefile
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391    README
040000 tree 8ede28eed8c7a5113ba5a8aa9704fa6017a996c7    lib

由上可知lib是tree不是blob,看下lib目录下的内容:

$ git cat-file -p 8ede28eed8c7a5113ba5a8aa9704fa6017a996c7
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391    simplegit.rb

从概念上来讲,Git 保存的数据如下所示:
这里写图片描述

3.3 commit

指向一个tree,它用来标记项目某一个特定时间点的状态。它包括以下关于时间点的元数据,如时间戳、最近一次提交的作者、指向上次提交.
这里写图片描述
commit 对象有格式很简单:指明了该时间点项目快照的顶层树对象、作者/提交者信息(从 Git 设置的 user.name 和 user.email中获得)以及当前时间戳、一个空行,以及提交注释信息。

3.4 tag

给某个提交增添一个标记。tag对象指向一个commit而不是一个 tree。它就像是一个分支引用,但是不会变化——永远指向同一个 commit,仅仅是提供一个更加友好的名字。后续命令操作中可以回味回味。


4 Git References

对于SHA-1值,在Git中,我们称之为“引用”(references 或者 refs)。你可以在 .git/refs 目录下面找到这些包含 SHA-1 值的文件。在这个项目里,这个目录还没不包含任何文件,但是包含这样一个简单的结构

$ find .git/refs
.git/refs
.git/refs/heads
.git/refs/tags

可以看下图所示,差不多就明白了refs的意思了。
这里写图片描述


5 HEAD 标记

HEAD文件是一个指向你当前所在分支的引用标识符。这样的引用标识符——它看起来并不像一个普通的引用——其实并不包含 SHA-1 值,而是一个指向另外一个引用的指针。如果你看一下这个文件,通常你将会看到这样的内容:

$ cat .git/HEAD
ref: refs/heads/master

如果你执行git checkout test,Git就会更新这个文件,看起来像这样:

$ cat .git/HEAD
ref: refs/heads/test

基本上原理差不多了解了,当然还有很多没有细细道来,留着以后再悟好了。
之后可以看看git的一些常用命令来实际操作下吧。

参考:
git内部原理

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值