Git系列:Git 引用
在这篇文章中主要讲述 Git 引用(Branch)及标签(Tag) 对象。
Git 引用
如果你对仓库中从一个提交(比如 1a410e)开始往前的历史感兴趣,那么可以运行 git log 1a410e 这样的命令来显示历史,不过你需要记得 1a410e 是你查看历史的起点提交。 如果我们有一个文件来保存 SHA-1 值,而该文件有一个简单的名字, 然后用这个名字指针来替代原始的 SHA-1 值的话会更加简单。
在 Git 中,这种简单的名字被称为“引用(references,或简写为 refs)”。
你可以在 .git/refs 目录下找到这类含有 SHA-1 值的文件。
在刚新建的项目中,这个目录没有包含任何文件,但它包含了一个简单的目录结构:
1
2
3
4
5$ find .git/refs
.git/refs
.git/refs/heads
.git/refs/tags
$ find .git/refs -type f
若要创建一个新引用来帮助记忆最新提交所在的位置,从技术上讲我们只需简单地做如下操作:
1
$ echo 1a410efbd13591db07496601ebc7a059dd55cfe9 > .git/refs/heads/master
1
2
3
4$ git log --pretty=oneline master
1a410efbd13591db07496601ebc7a059dd55cfe9 third commit
cac0cab538b970a37ea1e769cbbde608743bc96d second commit
fdf4fc3344e67ab068f836878b6c4951e3b15f3d first commit1
$ git update-ref refs/heads/master 1a410efbd13591db07496601ebc7a059dd55cfe9
1
$ git update-ref refs/heads/test cac0ca
1
2
3$ git log --pretty=oneline test
cac0cab538b970a37ea1e769cbbde608743bc96d second commit
fdf4fc3344e67ab068f836878b6c4951e3b15f3d first commit
当运行类似于 git branch
HEAD 引用
现在的问题是,当你执行 git branch
HEAD 文件通常是一个符号引用(symbolic reference),指向目前所在的分支。 所谓符号引用,表示它是一个指向其他引用的指针。
然而在某些罕见的情况下,HEAD 文件可能会包含一个 git 对象的 SHA-1 值。 当你在检出一个标签、提交或远程分支,让你的仓库变成 “分离 HEAD”状态时,就会出现这种情况。
如果查看 HEAD 文件的内容,通常我们看到类似这样的内容: 1
2$ cat .git/HEAD
ref: refs/heads/master1
2$ cat .git/HEAD
ref: refs/heads/test
你也可以手动编辑该文件,然而同样存在一个更安全的命令来完成此事:git
symbolic-ref。 可以借助此命令来查看 HEAD 引用对应的值:
1
2$ git symbolic-ref HEAD
refs/heads/master1
2
3$ git symbolic-ref HEAD refs/heads/test
$ cat .git/HEAD
ref: refs/heads/test1
2$ git symbolic-ref HEAD test
fatal: Refusing to point HEAD outside of refs/
标签引用
前面讨论过 Git 的三种主要的对象类型(数据对象、树对象 和 提交对象 ),然而实际上还有第四种。 标签对象(tag object) 非常类似于一个提交对象,它包含一个标签创建者信息、一个日期、一段注释信息,以及一个指针。 主要的区别在于,标签对象通常指向一个提交对象,而不是一个树对象。 它像是一个永不移动的分支引用,永远指向同一个提交对象,只不过给这个提交对象加上一个更友好的名字罢了。
正如 Git 基础
中所讨论的那样,存在两种类型的标签:附注标签和轻量标签。
可以像这样创建一个轻量标签: 1
$ git update-ref refs/tags/v1.0 cac0cab538b970a37ea1e769cbbde608743bc96d
1
$ git tag -a v1.1 1a410efbd13591db07496601ebc7a059dd55cfe9 -m 'test tag'
1
2$ cat .git/refs/tags/v1.1
9585191f37f7b0fb9444f35a9bf50de191beadc21
2
3
4
5
6
7$ git cat-file -p 9585191f37f7b0fb9444f35a9bf50de191beadc2
object 1a410efbd13591db07496601ebc7a059dd55cfe9
type commit
tag v1.1
tagger Scott Chacon <schacon@gmail.com> Sat May 23 16:48:58 2009 -0700
test tag1
$ git cat-file blob junio-gpg-pub
远程引用
我们将看到的第三种引用类型是远程引用(remote
reference)。
如果你添加了一个远程版本库并对其执行过推送操作,Git
会记录下最近一次推送操作时每一个分支所对应的值,并保存在
refs/remotes 目录下。 例如,你可以添加一个叫做 origin
的远程版本库,然后把 master 分支推送上去: 1
2
3
4
5
6
7
8$ git remote add origin git@github.com:schacon/simplegit-progit.git
$ git push origin master
Counting objects: 11, done.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (7/7), 716 bytes, done.
Total 7 (delta 2), reused 4 (delta 1)
To git@github.com:schacon/simplegit-progit.git
a11bef0..ca82a6d master -> master
此时,如果查看 refs/remotes/origin/master
文件,可以发现 origin 远程版本库的 master 分支所对应的 SHA-1
值,就是最近一次与服务器通信时本地 master 分支所对应的 SHA-1 值:
1
2$ cat .git/refs/remotes/origin/master
ca82a6dff817ec66f44342007202690a93763949
参考: