Git中的引用(reference)
引用(reference)是间接指向commit的方式
◼ 直接指向commit的方式是commit对象的sha1 hash码
◼ reference也可被认为是commit hash的别名,对用户来说更友好
◼ git版本库上的各reference以文本文件的形式存储于.git/refs/目录中下的子目录中
◆head目录:HEAD引用,内部的文件名为其指向的分支的名称,内容为相应分支最新一次提交的hash码
◆tags目录:标签引用,内部的文件名为创建的各Tag的名称
◆remotes/<remoteRepoName>目录: remoteRepoName为远程仓库的名称
◼ 带有引用的commit,也可以直接使用“ref/X/Y”路径的形式引用,例如“ref/heads/main”
几个特殊的引用
◼ HEAD:当前签出的提交/分支
◼ FETCH_HEAD:最近从远程仓库中获取的分支
◼ MERGE_HEAD:在git merge操作中,要合并到当分支的那个分支的HEAD
示例
查看当前分支
[root@ubuntu2004 deploy-demoapp]#git branch -l
devel
* master
进入当前分支的.git目录,列出refs/目录的树状图
[root@ubuntu2004 .git]#tree refs/
refs/
├── heads
│ ├── devel
│ └── master
├── remotes
│ └── origin
│ └── master
└── tags
└── v1.1
1、其中head目录:HEAD引用,内部的文件名为其指向的分支的名称,内容为相应分支最新一次提交的hash码
如:
[root@ubuntu2004 .git]#cat refs/heads/master
2e23ef42c80b9168f8e94e5609cfc05cd9a4d924
[root@ubuntu2004 .git]#cat refs/heads/devel
2e23ef42c80b9168f8e94e5609cfc05cd9a4d924
查看历史提交,其hash码与最新一次的提交历史的hash是一致的
[root@ubuntu2004 .git]#git log --pretty=oneline
2e23ef42c80b9168f8e94e5609cfc05cd9a4d924 (HEAD -> master, devel) commit-7
fe76f3df06225ee4855a86b8c13e9fcbee21bc1a merge branch devel commit-5.6
2、tags目录:标签引用,内部的文件名为创建的各Tag的名称
[root@ubuntu2004 .git]#cat refs/tags/v1.1
651f48740c89c82fcabe684016bb16a541d3004d
[root@ubuntu2004 .git]#git cat-file tag 651f48740c89c82fcabe684016bb16a541d3004d
object 0f5b8bcb27477e3f9e9364e85975e970b524cf4c
type commit
tag v1.1
tagger fanchao <1153454651@qq.com> 1675065917 +0800
Released
引用规范(refspec)
refspec
◼ 全称为Reference Specification,即引用规范
◼ git通过这种格式来表示本地分支与远程分支的映射关系
◼ 引用规范的格式“+<src>:<dst> ”,其中的+可选
◆<src> 是一个模式(pattern),代表远程版本库中的引用,即远程分支
◆<dst> 是本地跟踪的远程引用的位置,即本地远程分支
◆+ 号告诉 Git 即使在不能快进的情况下也要(强制)更新引用
◼ 本地远程分支就像是远程分支的一个本地镜像,在本地版本库与远程版本库之间起到一个桥梁的作用
◼ 例如本地远程分支:git branch -r
◼ 查看分支间的关联关系:git branch -vv
Git项目团队协作的工作流模型
团队内部共享远程仓库的工作流模型
◼ 常见小型的私有团队成员间的协作
◼ 所有成员被授权push代码到一个共同的远程仓库
◼ 彼此间基于各自专用的feature(或topic)分支进行隔离
工作流程:
1项目维护者在远程仓库上启动master分支
2所有开发人员克隆远程master分支至本地仓库
3每个开发人员创建一个本地feature分支(例如feature/user1-x)进行特性开发
4某位开发人员的特性开发完成后,创建一个pull request请求通知其它人review他的代码,所有人都可以提出反
馈和建议
5一旦被接受,其分支将由项目维护者合并至远程仓库的master分支
6一旦合并,feature分支即可被删除
基于Fork的工作流模型
◼ 该模型无须共享的远程版本库,每位开发人员将会fork协作时使用的远程仓库至自己的个人账户下,生成一
个个人专有的远程仓库
◼ 开发人员克隆自有的远程仓库至本地,并基于一个feature分支完成feature开发
工作流程:
1项目维护者将本地仓库推送至远程主机,并授权各贡献者有权读取该仓库
2各代码贡献人员fork项目至同一远程主机上的个人账户下
3某开发人员克隆自己账户下基于fork生成的仓库至本地
⚫ 本地远程分支将指向自己账户下的远程分支,而非上游(fork的项目)仓库中的远程分支
4在本地仓库上添加名为upstream的上游仓库,以跟踪原始仓库,并拉取原始仓库中的所有变更至本地
5在本地仓库创建一个新的feature分支进行feature开发,并日常推送变更至自己的远程仓库
⚫ 启动编码日常的“编辑、暂存、提交和推送”循环
6feature开发完成后,通过pull request通过项目维护者review代码
⚫ 创建pull request时,需要明确指定自己的仓库名和分支名,以及上游的仓库名和分支名
7项目维护者审核代码
⚫ 打回并要求原作者更正时,开发人员启动开发任务修正代码并再次创建PR请求
⚫ 接受代码时,项目维护者可通过merge操作完成分支合并
8所有的代码贡献者需要拉取上游仓库中的变更至本地版本库
Git分支模型:长期分支、短期分支
master: 承载发布历史,变更历史
master/develop:
master:承载发布历史
develop:变更历史
master/develop/feature
feature:短期分支,保存研发人员研发过程;
master/develop/feature/release
release:短期分支,承载发布过程
打tag:在master分支给相应的每个commit打个tag
master/develop/feature/release/hotfix
hotfix: 从master拉出来的分支,短期分支;
总结
协作模型:
共享远程库
每个研发人员有自己的本地库
隔离分支:每个使用一个独立feature/<name>
通过创建PR请求通知相关人员审核自己代码
审核通过后,项目维护人员将feature合并到master/develop
非共享远程库:上游库
每个开发人员fork上游库为自己的远程库
克隆自己远程库至本地
在本地库再创建一个远程库(upstream)指向,
所有开发变更推送自己的远程库中
通过创建PR请求通知相关人员审核自己代码