在没有 refspec 参数的情况下运行 git push、pull 和 fetch

2023-12-04

来自 Loeliger 2ed 的 Git 版本控制,

如果您根本不指定 refspec 会怎样?git push命令?如何 Git 知道要做什么或将数据发送到哪里吗?

首先,如果没有给命令明确的远程,Git 会假设 你想使用原点。

没有参考规范, git 推送将把你的提交发送到远程你们之间共有的所有分支 存储库和上游存储库。任何非本地分行 已经存在于上游存储库中的将不会被发送到上游; 分支必须已经存在并且名称匹配。

  • 都是 您的存储库和上游存储库之间通用的分支”与本地存储库中的所有远程跟踪分支以及远程存储库中相应的跟踪分支相同吗?

  • 报价是为了git push。 它(特别是没有参考规格的情况下的部分)是否适用于git fetch and to git pull?


(恐怕这个答案再次相当长,因为这些问题做出的假设至少在今天是不正确的。跳到粗体部分以获取实际答案,但之前的所有内容也很重要。)

您引用的书籍文本已经过时,并且(现在)完全是错误的(这是不断发展的软件的危险,书籍已经过时):

首先,如果没有为命令提供显式远程,Git 会假设您想要使用 origin。

在相对快速地浏览 git 自己的 git 历史记录时,我还没有准确地找到behavior改变了,但是文档在 git 1.8.2.1 中进行了更改,并且now says:

当命令行没有指定推送到哪里时<repository>争论,branch.*.remote配置为 咨询当前分支以确定推送到哪里。如果 缺少配置,默认为origin.

(此行为符合git fetch也不足为奇,因为他们使用相同的源代码来获得该结果。)这没有提到可选的branch.$branch.pushremote设置,它会覆盖branch.$branch.remote。在所有情况下都在这里$branch代表您当前的分支,如输出所示git symbolic-ref --short HEAD。 (如果您处于“分离头”模式,那么git symbolic-ref fails, git push通常会给你一个“致命的:你当前不在分支上”错误,我认为从 2.0 版本开始,默认值发生了变化。)

This is still不是故事的全部;git-config 文档又增加了一个怪癖:

remote.pushDefault
默认情况下要推送到的遥控器。覆盖branch.<name>.remote对于所有分支,并且被覆盖branch.<name>.pushRemote为了 具体分支机构。

(幸运的是,从今天开始,我think这涵盖了一切。也就是说,git 首先寻找pushremote当前分支的设置。如果没有这样的设置,它接下来会寻找remote.pushdefault。如果也没有设置,它将依赖于remote当前分支的设置。旧版本 git 中的行为可能有所不同。另请注意,配置项不区分大小写:pushremote and pushRemote是相同的配置名称[这让我想知道分支名称部分是否也不区分大小写;我得找个时间测试一下]。)

关于 refspecs 的下一部分甚至更加错误,因为 git 随着时间的推移已经发生了一些变化,其中一些甚至在 git 的内置文档中也没有很好的记录。你的引述如下:

如果没有 refspec,git Push 会将您的提交发送到远程,以获取您的存储库和上游存储库之间常见的所有分支。

The 新文档 says:

当命令行没有指定要推送的内容时<refspec>...论据或--all, --mirror, --tags选项,该命令发现 默认值<refspec>通过咨询remote.*.push配置, 如果没有找到,荣誉push.default配置来决定 要推送什么(参见git 配置的意义push.default).

The push.default设置是在 git 1.8 版本左右添加的,但它是默认的valuegit 2.0 中发生了变化。如果您还没有配置push.default你会收到这个警告:

warning: push.default is unset; ...

自从配置项可用以来。咨询git-config 文档,你现在会发现这个:

push.default
定义动作git push如果没有明确给出参考规范,则应采用。不同的值非常适合特定的工作流程......

有五个选项,我将在这里简单列出(有关详细信息,请参阅链接文档):nothing, current, simple, upstream, and matching。您引用的书本文字描述了matching,这是 git 2.0 版本之前的默认行为。新的默认值是simple.

On git push,如果您配置“匹配”行为

“您的存储库和上游存储库之间共有的所有分支”是否与本地存储库中的所有远程跟踪分支以及远程存储库中相应的跟踪分支相同?

No.

我建议你尝试跑步git ls-remote origin(或替换origin与任何其他遥控器的名称):

$ git ls-remote origin
28274d02c489f4c7e68153056e9061a46f62d7a0        HEAD
1ff88560c8d22bcdb528a6629239d638f927cb96        refs/heads/maint
28274d02c489f4c7e68153056e9061a46f62d7a0        refs/heads/master
0ac5344e619fec2068de9ab2afdb99d1af8854be        refs/heads/next
5467631257c047b16d95929559dd1887d27b0ddc        refs/heads/pu
68a0f56b615b61afdbd86be01a3ca63dca70edc0        refs/heads/todo
d5aef6e4d58cfe1549adef5b436f3ace984e8c86        refs/tags/gitgui-0.10.0
3d654be48f65545c4d3e35f5d3bbed5489820930        refs/tags/gitgui-0.10.0^{}
[snip -- lots more omitted]

然后,尝试git for-each-ref refs/heads:

$ git for-each-ref refs/heads

您将看到类似的输出,但具有不同的 SHA-1,以及单词commit夹在中间。

这里的要点是列出的每个“头”refs/heads- 在两个输出中,从ls-remote和来自for-each-ref—代表(本地)分支机构git push做“匹配”时要考虑。匹配的头被添加到推送列表中,给出一组 refspec(以内部形式,但很容易表示为name:name或者,如果您使用--force flag, +name:name).

有时候是这样的即使没有为这些本地分支配置上游。因此,如果他们(遥控器)有refs/heads/bob这是供鲍勃·罗伯茨使用的,你有一个refs/heads/bob你用来获取有关你的管道浮子或钓鱼浮子或其他什么的信息,git 会尝试将它们匹配,即使你的bob并不意味着要逆流而上。

On push vs fetch

报价是为了git push。它(特别是没有参考规格的情况下的部分)是否适用于git fetch and to git pull?

No.

The behavior of git fetch is easier to explain, because it doesn't do all the weird stuff on you that git pull does. The git pull command is supposed to be convenient, but git pull is trying to mash a fundamentally repository-wide "fetch" operation together with a fundamentally branch-constrained "merge" operation. These two do not play well together.1 (At best, I think git pull could at some point be modified to do a simpler, repository-wide "fetch all, then check out and merge, pairwise, some branch(es) based on tracking configs and arguments" sequence. I think this would make it behave the way most people seem to expect it to. It would also be mostly backwards-incompatible, and behave the way it does now only for the simplest—but default—case: fetch all, then merge current branch only. But that's all speculation anyway.)

如果省略所有参考规范,git fetch读你的remote.$remote.fetch配置线。(请注意,这个“省略所有引用规范”子句意味着您还必须避免旧的“命名文件$GIT_DIR/branches“例如方法。)

远程名称的默认配置行(单数)origin通常看起来像这样(查看本地存储库配置文件以查看它):

[remote "origin"]
    +refs/heads/*:refs/remotes/origin/*

这就是“远程跟踪分支”产生的实际机制。

The fetch过程同样开始git ls-remote origin步骤,它从远程获取每个引用的列表——分支、标签或你拥有的东西。这fetch代码继续将它们与每个fetch =下的行[remote "origin"]。参考规范左侧的星号具有明显的含义;右侧的星号将替换为左侧星号匹配的内容。 (在当前版本的 git 中*必须匹配“整个部分”,松散地定义为“斜杠之间的东西”,但在即将到来的 git 中,这个约束将被放松——尽管我不确定有什么有用的结果。)

你可能有尽可能多的fetch =线条如你所愿。每个原始引用都会遍历每一行以获得新的(替换)引用:如果左侧匹配,则右侧提供替换。 (如果右侧缺失或为空,由于历史原因,行为会变得有点奇怪,部分是为了保持git pull工作正常,部分原因是所需的行为在 git 1.8 左右发生了变化。)

所有这些替换的结果形成重命名的引用,并确定复制哪些引用;但每个原始引用最多只能有一个结果:您无法将“他们的”refs/heads/foo 映射到“您的”refs/remotes/origin/barand例如,您的 refs/remotes/origin/zoink。

要使存储库充当镜像,您可以使用+refs/*:refs/*带来所有引用而不重命名(但这会破坏每个引用上的本地分支fetch所以这只有在以下情况下才有意义--bare).

(“修剪”——根据对方在获取或推送的启动协商期间发送的内容删除“死”引用——是单独完成的,并且仅当您设置--prune flag.)


1It didn't start out this way. In fact, the original pull script predated remotes and remote-tracking branches entirely. Commit 7ef76925d9c19ef74874e1735e2436e56d0c4897 split pull into pull and fetch and then the two evolved in different directions over time; once "remotes" and "remote-tracking branches" came into existence, they'd evolved to the point that trying to mix them was, I think, just a bad idea, and now it's even worse. :-)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在没有 refspec 参数的情况下运行 git push、pull 和 fetch 的相关文章

  • 分支明显不同,但提交历史是相同的

    git status告诉我我的分支和我在另一个存储库上开始的分支已经分歧 On branch master Your branch and origin master have diverged and have 13 and 13 dif
  • 如何解决 VSTS 中拉取请求中的合并冲突?

    我已经创建了拉取请求 我进入了这个 批准 按钮不执行任何操作 并且 完成 被禁用 如何解决拉取请求中的冲突 Update 微软刚刚添加了基于浏览器的合并 这可能会让你摆脱小冲突的困境 并提供自 Sprint 150 起改进了不同场景的可视化
  • 远程测试时如何搭建git开发环境

    这似乎是一个愚蠢的问题 但我觉得我对 GIT 相当了解 但我似乎无法按照我的意愿设置我的开发环境 我要么错过了一些非常简单的东西 要么我做错了 我在我的服务器上初始化了一个裸 git 存储库 将其克隆到我的本地计算机 提交我的文件并推送到原
  • Git:显示分支之间的差异,忽略合并的提交

    我的存储库历史记录看起来像这样 x y z branch a b c d e master 我想获得 branch 完整历史记录的单个差异 即 像 git diff 输出 我不想要像 git log p 产生的一大堆差异 而不包括任何从 m
  • 在 github 上的 fork 中跟踪上游的最佳实践

    摘要 对于要维护一组本地更改的上游存储库 处理长期运行跟踪的最佳实践是什么 我想让 github 上的 fork 与上游保持同步 但仍然允许清晰跟踪 fork 特有的更改 对于本次讨论 假设upstream指向主项目存储库并且origin指
  • git 别名中的 AWK 语句

    我正在尝试创建一个 git 别名来以特定格式打印日志中的所有拉取请求 但是 我在使用 AWK 删除双空格时遇到问题 这是使用以下命令的 git log 的输出 git log merges grep pull request pretty
  • VS 2015 + Bower:在防火墙后面不起作用

    Problem 在 Visual Studio 2015 中 使用 Bower 我的包在防火墙后面时恢复失败 并出现类似以下内容的错误 ECMDERR 无法执行 git ls remote tags heads git github com
  • 在 Windows 7 上的 Sourcetree 中比较 Word docx 文件

    我一直在尝试获取在 Windows 7 上的 Sourcetree 中工作的 Word docx 文件的文本差异 我已按照此处的说明进行操作将 Microsoft Word 与 git 结合使用 http blog martinfenner
  • 在 Azure DevOps 项目之间移动存储库时保留拉取请求

    我在同一帐户内有两个 Azure DevOps 项目 我想将存储库从一个项目移动到另一个项目 这一页探索如何在具有完全保真历史记录的团队项目之间移动 git 存储库 https learn microsoft com en us azure
  • 使用终端时 Git 推送在总计后卡住了?

    我尝试将一些文件推送到Github 总大小只有22 2M 我不知道为什么它在总行之后卡住了 我读过推送到 Github 时 Git 推送挂起 https stackoverflow com questions 16906161 git pu
  • 如何在 macOS 上将 Git 升级到最新版本?

    我刚刚购买了一台装有 OS X Lion 的新 Mac 我在终端中检查了默认安装的 git 版本 我得到了答案 git version gt git version 1 7 5 4 我想将 git 升级到最新版本 1 7 8 3 因此我下载
  • Git 将一个分支合并到所有其他分支中

    我知道这个问题已经在这里被问过 https stackoverflow com questions 2329716 merging changes from master into all branches using git https
  • Git 提交失败:“请使用 -m 或 -F 选项提供消息。”

    当我键入 git commit 命令来提交文件时 我收到以下错误消息 Microsoft Visual Studio 微软 找不到命令 错误 核心编辑器 Microsoft Visual Studio 存在问题 请使用 m 或 F 选项提供
  • 将bitbucket发布到数字海洋

    我本质上是试图使用 bitbucket 来理解 git 的概念 我一直在通过修改本地帐户和 bitbucket 帐户之间的文件来练习版本控制 事实证明这很有帮助 现在我正在尝试弄清楚如何将文件从 bitbucket 或者我猜是 GitHub
  • 自定义 SSH 端口上的 Git

    我的 VPS 提供商建议我将 SSH 端口保留为他们默认分配的自定义端口号 不是 22 问题是 虽然我知道我可以在创建远程配置时提供端口号 但在进行 Git 克隆时似乎无法提供相同的操作 我在用gitolite https wiki arc
  • Git - 如何将整个目录恢复到特定提交(删除任何添加的文件)

    我想恢复 git 中的目录 恢复其中的所有文件 并删除自该提交以来添加的所有文件 进行结账似乎只能满足我的第一个要求 但不会删除任何文件 我想出了最简单的解决方案 git rm path to dir git checkout
  • git reflog 和 log 有什么区别?

    手册页说 log 显示提交日志 reflog 管理 reflog 信息 reflog 信息到底是什么 它有哪些日志没有的信息 日志看起来更详细 git log显示当前的 HEAD 及其祖先 也就是说 它打印提交 HEAD 指向的提交 然后打
  • Git 更改丢失 - 为什么?

    我们的开发团队正在使用 git 最近我们至少两次丢失了文件更改 我们正在使用私人 Github 存储库 在当前情况下 我们可以返回 Github 上的日志并查看我对文件所做的一些更新 后来 另一位团队成员更改了文件的不同部分 它似乎破坏了我
  • 仅使用 Git grep 的文件名

    我只想查看文本中包含特定单词的不同文件 current directory git grep word 显示文件中具有匹配单词的每一行 所以我尝试了这个 current directory git grep word files with
  • 显示 master 之前/之后有多少提交分支的别名

    新的 Bitbucket Branches 页面非常棒 它显示每个分支领先 落后于 master 的提交数量 是否有显示相同信息的 Git 别名 信息应显示 分店名称 上次更新是什么时候 其背后有多少提交 有多少提交领先于 master 看

随机推荐

  • catch (...) 在 throw 上起作用吗?没有对象?

    当堆栈上方没有正在处理的未决异常时 C 标准规定以下代码应该发生什么 try throw catch cerr lt lt Caught exception lt lt endl 没有物体的投掷会被接住吗 来自 2003 C 标准 15 1
  • 谷歌地图显示:没有问题

    我正在尝试设置一个 Google 地图 该地图将在单击链接时显示 然后在单击另一个链接时隐藏 一切工作正常 除了当我从 display none 显示地图时 它无法正常显示 我读到有关使用 google maps event trigger
  • 字符串中的多个引号

    在Python中我将如何编写字符串 BOS 我尝试输入 BOS 但这给出了输出 BOS 在前面添加反斜杠 您可以使用三引号 BOS 你做了什么 BOS 也很好 您在输出中得到反斜杠 但它们不是字符串的一部分 gt gt gt a BOS g
  • JavaScript 日期函数在 Firefox 浏览器中返回“Date {Invalid Date}”

    面临一个问题JavaScript Date功能 returns Date Invalid Date 在 Firefox 浏览器中 但在 Google Chrome 中工作正常 My Input is new Date Sat Jan 01
  • 将velocityInView与UIPanGestureRecognizer结合使用

    我有一个自定义滑块类型的对象 我希望使其更有用 目前我使用UIPanGestureRecognizer and translationInView使其发挥作用 它工作得很好 但我想要某种速度 让它感觉更有用 我已经尝试了一些方法 但不太清楚
  • 测量线程的上下文切换时间

    我想计算上下文切换时间 并且我正在考虑使用互斥体和条件变量在两个线程之间发出信号 以便一次只有一个线程运行 我可以用CLOCK MONOTONIC测量整个执行时间和CLOCK THREAD CPUTIME ID测量每个线程运行的时间 那么上
  • 如何在 IBM MQ JMS 接口上使用 JMS 属性?

    我正在使用带有 MQ 6 0 2 的 MQ JMS 接口 似乎只支持预定义的属性 而不支持任意的属性 例如 我可以正确地getJMSCorrelationID getJMSPriority 等等 但是 当我在发件人上设置任意属性时 mess
  • 如何查看Google Play服务版本?

    在我的应用程序中 我需要检查 Google Play 服务版本 安装在用户设备中 是否可以 如果是的话 我该怎么做 我找到了简单的解决方案 int v getPackageManager getPackageInfo GoogleApiAv
  • CMSIS 库是否应该包含在版本控制中? [复制]

    这个问题在这里已经有答案了 通常 我曾经在版本控制中包含芯片供应商 ST 提供的设备特定标头和源以及 CMSIS Core 标头 数量不多 也没有更新的习惯 我使用STM32微控制器 但我不使用立方体框架 or the 标准外设库 最近 我
  • jQuery 获取 XML 中的匹配节点

    一点背景知识 我使用 XSLT 在页面上呈现一些 XML 但我们决定使其更具交互性 所以现在我正在执行 jQuery ajax 调用来返回 XML 并在 JavaScript 中解析它 我已经能够使用类似的代码从中提取特定节点 var qp
  • 为什么不能使用 Q_OBJECT 宏进行编译(链接)?

    我用 PyQt 制作了一个项目的原型并使其在那里工作 现在我尝试将其转换为 C 但遇到了一些问题 如果我不放入 Q OBJECT 宏 它会编译并运行 但如果我将其注释掉 则会出现以下错误 Undefined symbols vtable f
  • 将一组数据行绑定到 datagridview

    我尝试了以下代码 但 datagridview 中没有显示任何内容 有什么建议么 string strFilterOption dtcolnPurchaseProductExpProductNo 270 dgvProductExp Data
  • 当视图样式设置为详细信息时,如何在 Winforms ListView 中显示图标和文本?

    我只想有两列 例如 Item Value icon Gold 10 icon Silver 2 icon Iron 1 这可能吗 或者我需要为图标添加另一列吗 查看文档以了解SmallImageList of the ListView控制和
  • C语言中删除文件中的一个字符

    如何使用C程序从文件中删除几个字符 我找不到它的任何预定义函数 为了理解目的 我试图通过套接字发送一个文件 如果成功发送 N 个字节 我想从文件中删除这些字节 最后 该文件将为空 还有其他方法可以有效地做到这一点吗 谢谢 普拉迪普 如果它们
  • d3 单击创建圆并单击删除

    我试图单击一个圆圈将其删除 但单击画布将创建一个圆圈 我确实想从数据中实际删除圆圈及其对象 而不是仅仅使其透明 单击圆圈时调用该函数 function removeElement d d3 select this remove 通过单击圆圈
  • 有什么方法可以获取 Firebase Auth 用户 UID 吗?

    我希望通过 Node JS 或 Javascript API 从 Firebase 获取身份验证用户 Auth Users UID 我附上了它的屏幕截图 以便您了解我在寻找什么 希望你们能帮我解决这个问题 Firebase 3 中的身份验证
  • 如何在 iPhone 上旋转 Quartz 绘制的文本

    I want to draw some texts using Quartz Now the app draws but I want it to show as 0123456789 Is there any way to show it
  • .NET TIFF 文件:无需第三方库即可将 RGB 转换为 CMYK?

    继续我之前的问题 是否以及如何可以基于 RGBTIFF文件并使用标准 NET 3 5 功能将其转换为 CMYK 这可能吗 实际上有一种方法使用 System Windows Media Imaging 命名空间 目前似乎只适用于 TIFF
  • 将“const wchar_t *”转换为“unsigned char *”

    在 C 中 是否可以将 const wchar t 转换为 unsigned char 我怎样才能做到这一点 wstring dirName unsigned char dirNameA unsigned char dirName c st
  • 在没有 refspec 参数的情况下运行 git push、pull 和 fetch

    来自 Loeliger 2ed 的 Git 版本控制 如果您根本不指定 refspec 会怎样 git push命令 如何 Git 知道要做什么或将数据发送到哪里吗 首先 如果没有给命令明确的远程 Git 会假设 你想使用原点 没有参考规范