前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >10.5 Git 内部原理 - 引用规范

10.5 Git 内部原理 - 引用规范

作者头像
AlphaHinex
发布2024-07-15 15:40:09
900
发布2024-07-15 15:40:09
举报
文章被收录于专栏:周拱壹卒
  • 原文地址:https://git-scm.com/book/zh/v2/Git-内部原理-引用规范
  • 源码:https://github.com/progit/progit2-zh/blob/master/book/10-git-internals/sections/refspec.asc

引用规范

纵观全书,我们已经使用过一些诸如远程分支到本地引用的简单映射方式,但这种映射可以更复杂。假设你已经跟着前几节在本地创建了一个小的 Git 仓库,现在想要添加一个远程仓库:

代码语言:javascript
复制
$ git remote add origin https://github.com/schacon/simplegit-progit

运行上述命令会在你仓库中的 .git/config 文件中添加一个小节,并在其中指定远程版本库的名称(origin)、URL 和一个用于获取操作的 引用规范(refspec)

代码语言:javascript
复制
[remote "origin"]
	url = https://github.com/schacon/simplegit-progit
	fetch = +refs/heads/*:refs/remotes/origin/*

引用规范的格式由一个可选的 + 号和紧随其后的 <src>:<dst> 组成,其中 <src> 是一个模式(pattern),代表远程版本库中的引用;<dst> 是本地跟踪的远程引用的位置。+ 号告诉 Git 即使在不能快进的情况下也要(强制)更新引用。

默认情况下,引用规范由 git remote add origin 命令自动生成,Git 获取服务器中 refs/heads/ 下面的所有引用,并将它写入到本地的 refs/remotes/origin/ 中。所以,如果服务器上有一个 master 分支,你可以在本地通过下面任意一种方式来访问该分支上的提交记录:

代码语言:javascript
复制
$ git log origin/master
$ git log remotes/origin/master
$ git log refs/remotes/origin/master

上面的三个命令作用相同,因为 Git 会把它们都扩展成 refs/remotes/origin/master

如果想让 Git 每次只拉取远程的 master 分支,而不是所有分支, 可以把(引用规范的)获取那一行修改为只引用该分支:

代码语言:javascript
复制
fetch = +refs/heads/master:refs/remotes/origin/master

这仅是针对该远程版本库的 git fetch 操作的默认引用规范。如果有某些只希望被执行一次的操作,我们也可以在命令行指定引用规范。若要将远程的 master 分支拉到本地的 origin/mymaster 分支,可以运行:

代码语言:javascript
复制
$ git fetch origin master:refs/remotes/origin/mymaster

你也可以指定多个引用规范。在命令行中,你可以按照如下的方式拉取多个分支:

代码语言:javascript
复制
$ git fetch origin master:refs/remotes/origin/mymaster \
  topic:refs/remotes/origin/topic
From git@github.com:schacon/simplegit
 ! [rejected]        master     -> origin/mymaster  (non fast forward)
 * [new branch]      topic      -> origin/topic

在这个例子中,对 master 分支的拉取操作被拒绝,因为它不是一个可以快进的引用。我们可以通过在引用规范之前指定 + 号来覆盖该规则。

你也可以在配置文件中指定多个用于获取操作的引用规范。如果想在每次从 origin 远程仓库获取时都包括 masterexperiment 分支,添加如下两行:

代码语言:javascript
复制
[remote "origin"]
	url = https://github.com/schacon/simplegit-progit
	fetch = +refs/heads/master:refs/remotes/origin/master
	fetch = +refs/heads/experiment:refs/remotes/origin/experiment

自 Git 2.6.0 起可以在模式中使用部分通配符以匹配多个分支,所以这样是可以工作的:

代码语言:javascript
复制
fetch = +refs/heads/qa*:refs/remotes/origin/qa*

更棒的是,我们可以使用命名空间(或目录)来实现相同的目标,并且更具结构性。假设你有一个 QA 团队,他们推送了一系列分支,同时你只想要获取 master 和 QA 团队的所有分支而不关心其他任何分支,那么可以使用如下配置:

代码语言:javascript
复制
[remote "origin"]
	url = https://github.com/schacon/simplegit-progit
	fetch = +refs/heads/master:refs/remotes/origin/master
	fetch = +refs/heads/qa/*:refs/remotes/origin/qa/*

如果项目的工作流很复杂,有 QA 团队推送分支、开发人员推送分支、集成团队推送并且在远程分支上展开协作,你就可以像这样(在本地)为这些分支创建各自的命名空间,非常方便。

引用规范推送

像上面这样从远程版本库获取已在命名空间中的引用当然很棒,但 QA 团队最初应该如何将他们的分支放入远程的 qa/ 命名空间呢?我们可以通过引用规范推送来完成这个任务。

如果 QA 团队想把他们的 master 分支推送到远程服务器的 qa/master 分支上,可以运行:

代码语言:javascript
复制
$ git push origin master:refs/heads/qa/master

如果他们希望 Git 每次运行 git push origin 时都像上面这样推送,可以在他们的配置文件中添加一条 push 值:

代码语言:javascript
复制
[remote "origin"]
	url = https://github.com/schacon/simplegit-progit
	fetch = +refs/heads/*:refs/remotes/origin/*
	push = refs/heads/master:refs/heads/qa/master

正如刚才所指出的,这会让 git push origin 默认把本地 master 分支推送到远程 qa/master 分支。

你无法通过引用规范从一个仓库获取并推送到另一个仓库。这样做的示例见 让你的 GitHub 公共仓库保持更新[1]

删除引用

你还可以借助类似下面的命令通过引用规范从远程服务器上删除引用:

代码语言:javascript
复制
$ git push origin :topic

因为引用规范(的格式)是 <src>:<dst>,所以上述命令把 <src> 留空,意味着把远程版本库的 topic 分支定义为空值,也就是删除它。

或者你可以使用更新的语法(自 Git v1.7.0 以后可用):

代码语言:javascript
复制
$ git push origin --delete topic

参考资料

[1]

让你的 GitHub 公共仓库保持更新: https://git-scm.com/book/zh/v2/ch00/_fetch_and_push_on_different_repositories

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-07-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 周拱壹卒 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引用规范
    • 引用规范推送
      • 删除引用
      相关产品与服务
      云服务器
      云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档