如何将/ff分支提升到HEAD

2024-05-03

我有一个受保护的分支,只有在集成构建上的集成构建通过后,才应提升/快进该分支。

我目前尝试通过在集成分支的拉取请求上构建集成来解决这个问题,一旦成功,只需将发布分支快速转发到集成分支的尖端。

但是,当我在 TFS 构建系统上构建分支时,它将检出集成分支头部的提交,使构建服务器处于分离头状态。

这应该没问题,但由于某种原因,如果不使用多个语句,我就无法做到这一点。对我来说,直觉上应该有一个简单的命令来实现这一点。我只想将分支点快进到当前提交。

但就目前而言,我找到了两种方法:

使用脚本保存 HEAD 提交

  1. 将 HEAD 提交保存到当​​前 shell 脚本语言中的变量(此处保存到 %HEAD_commit_id%)
  2. git checkout release
  3. git merge %HEAD_commit_id%

使用一次性分支

  1. git branch current-head
  2. git checkout release
  3. git merge current-head
  4. git branch -d current-head

寻找更好的解决方案

上述是我能做的“最好的”来实现这一点,这是否正确?我认为有一条线可以做到这一点吗?解决方案 1 和 2 都有其注意事项,所以我宁愿都不选择,但最终我可能会使用数字 2。

重现场景的步骤

为了重现我所遇到的确切场景,您需要 2 个提交(C1 和 C2)和 2 个分支(发布和集成)。

点释放到C1,集成到C2,HEAD到C2(分离头状态)。

最终结果应该允许我推送发布分支,现在指向与集成相同的提交。


你有many选项;使用哪个取决于您对环境的保证。

你可以使用(帽子尖jthill https://stackoverflow.com/questions/48968509/how-to-promote-ff-branch-to-head/48969434?noredirect=1#comment84957959_48969434):

git checkout release && git merge --ff-only @{1}

(使用您的外壳所需的任何东西来保护支架免于膨胀)。这相当于你的第一个方法,但不需要临时变量,因为@{1}意思是“之前的值HEAD结账前”。

但是,您也可以使用以下任一相当棘手的操作:

git push . HEAD:refs/heads/release

or:

git fetch . HEAD:refs/heads/release

正如我们将在下面看到的。这在某些方面更有效。它的主要缺点是几乎没有人groks https://www.merriam-webster.com/dictionary/grok it.

背景

首先我们要注意的是,每个存储库都是独立的,我的意思是每个存储库都有自己的分支名称和自己的分支名称。HEAD以及索引和工作树。 (后三项——HEAD、索引和工作树——作为一个单元运行。如果您有 Git 版本 2.5 或更高版本,您可以使用git worktree add添加独立的工作树,每个工作树都有自己的HEAD和索引。)

git checkout name-or-ID假设一切顺利的话:

  1. Leave HEAD指向ID,通常通过name(一个“附加的头”),但如果有必要的话可以直接(当你给它一个ID,或者使用--detach以确保它将 HEAD 与name你给它)。
  2. 填写提交中的索引HEAD现在的名字。
  3. 从同一提交填充工作树。

现在,让我们考虑一下什么git merge当可以快进而不是实际合并时会这样做。出现这种情况时HEAD命名一个提交,它是目标提交的祖先,然后你告诉git merge与标识该目标提交的任何内容合并。您传递给的标识符git merge可以是原始哈希 ID(如您的%HEAD_commit_id%方法),或分支名称(如您的git merge current-head方法)。唯一需要的是git merge:

  1. 找到目标提交(例如,接收其哈希 ID 或将名称解析为其哈希 ID);
  2. 计算合并基数HEAD和目标提交;和
  3. 发现这个合并基础与HEAD识别。

在这些条件下可以进行快进合并。如果可以进行快进合并,and你没有明确禁止它(git merge --no-ff) 或隐含地 (git merge -s ours例如,或使用带注释的标签进行合并的某些情况),git merge在这种情况下将执行快进操作。您甚至可以添加--ff-only论据git merge告诉 Git:如果可能的话,进行快进,如果不可能,则给我一个错误,而不是进行真正的合并。

快进合并操作

现在让我们看看快进合并实际上做了什么。这有多个部分,因为git merge影响当前(HEAD附加)分支,或者如果HEAD是分离的,HEAD本身。请注意,如果中途出现问题,Git 会尝试取消整个操作,这样看起来要么一切都成功,要么快进根本不会开始。 (在某些特别严重的情况下,例如当计算机着火时,如果您的计算机在大火中幸存下来,则混乱的内部状态可能会显现出来。)

  • Git需要使索引和工作树与合并结果相匹配,这当然是目标提交。因此,实际上,Git 会检查目标提交。然而,HEAD保持与当前分支的连接(如果已附加)。目标提交的检出会更新索引和工作树。

  • If HEAD已附加,Git 现在更改分支name到哪个HEAD附加,以便该名称标识刚刚签出的提交 - 目标提交。也就是说,如果我们有一些东西,我们可能会这样画:

    ...--o--o   <-- branch (HEAD)
             \
              o--o--o   <-- target_commit
                     \
                      o--...
    

    我们现在有:

    ...--o--o
             \
              o--o--o   <-- branch (HEAD), target_commit
                     \
                      o--...
    

    当我们在给定的分支上时,这就是正在执行的快进操作。

    (If HEAD是超然的,简单地想象没有名字的相同动作branch在它前面。)

考虑git fetch and git push

当你使用git fetch从另一个 Git 获取新的提交,或者git push要将您自己的提交提供给另一个 Git,您需要让两个 Git 相互通信并传输任何新的提交。暂时假设这是一个git fetch手术:

...--o--o--X

becomes:

...--o--o--X--Y--Z

where Y--Z是与提示提交链接的新提交X我们分行的。很典型的是,X有两个名字指向它,例如master and origin/master,在start操作的:

...--o--o--X   <-- master (HEAD), origin/master

最后,相应的origin/master名称已移动,因此我们可以像这样绘制提交:

...--o--o--X   <-- master (HEAD)
            \
             Y--Z   <-- origin/master

考虑一下名字如何origin/master刚刚搬家,比较一下如何branch当我们进行快进合并时移动。这些是相同的动议:名字origin/master以快进的方式移动,这样就不用指向提交X,现在指向提交Z.

这也是在期间发生的情况git push,不同之处在于我们不是让我们的 Git 从他们的 Git 检索提交,而是让我们的提交向他们的 Git 提供提交。但一旦我们这样做了,我们就不想our需要记住的 GittheirGit的主人,我们要theirGit 要记住,如their master,我们的最终提交。因此,如果they had:

...--o--o--X   <-- master

我们给了他们--Y--Z连接到X,我们想要them使their master指向Z:

...--o--o--X--Y--Z   <-- master

这也是一个快进手术。

请注意,如果我们提出请求isn't快进,其他 Git 通常rejects我们的要求:

...--o--o--X--W   <-- master
            \
             Y--Z   <-- (we request that they set their master here)

在这种情况下,如果他们搬了名字master指向Z,他们会“忘记”承诺W。那是一个非快进操作,并且是当我们运行时的那种事情git merge,使我们获得真正的合并。正在接收的 Gitgit push won't run git merge, so it requires我们的请求是快进操作——嗯,需要这个,除非我们告诉它force改变。

只要我们不使用--force或同等的,这种git push不会进行任何非快进操作的更改。另一个 Git 会简单地说:不,我不会那样做,因为这不是快进。 https://stackoverflow.com/q/4684352/1256452

Note that unlike our fast-forward merge case, their Git—the other Git to which we are git pushing—doesn't run git checkout on any updated commit hashes. This is why we must either push to a --bare repository, which has no work-tree, or push to a branch that the other Git doesn't have checked out.1

这意味着我们可以(ab)使用 fetch 或 push

我们知道:

  1. git push只要分支尚未签出,就会快进,并且
  2. 我们处于“分离头”模式,所以我们没有分支release签出,所以
  3. 如果我们让 Git 调用我们自己的 Git 会怎么样?如果我们要求他们设置怎么办their release某个特定的提交哈希?

我们的 Git 会要求他们的 Git(实际上是我们的 Git,只是戴着不同的帽子)接受任何新的提交——没有任何提交;我们的 Git 拥有我们的 Git 的所有提交,然后更新它的(我们的)release以快进的方式,因为我们不要求它强制执行任何操作。因此我们可以快进我们自己的release到由HEAD如果我们只是说:嘿,其他 Git,设置你的refs/heads/release到我确定的提交HEAD!我们通过推动来做到这一点refspec形式:

HEAD:refs/heads/release

现在唯一的办法就是给我们自己打电话。通常我们可能需要一个 URL,但是 Git 允许路径名,包括相对路径名;和相对路径名. means 当前目录。所以如果我们:

git push . HEAD:refs/heads/release

我们将让我们的 Git 调用自己的 Git,不传输任何内容(没有新的提交),并要求我们的 Git 设置我们的refs/heads/release以快进的方式,以匹配我们当前的HEAD。自从我们的release未检出,当且仅当操作是快进时才允许这样做。

获取技巧完全相同:我们从自己那里获取(不传输任何提交),然后请求我们自己的 Git 设置我们自己的refs/heads/release到特定的提交哈希。由于没有领先+强制标志,这也验证了该操作仅快进。因为我们不使用--update-head-ok,这同样检查git push确实,当前HEAD没有命名分支release。奇怪的是,我们从other这次是 Git(但那是我们自己,所以无论如何它都是相同的哈希 ID)。


1This actually depends on the setting of receive.denyCurrentBranch. See also receive.denyNonFastForwards. Newer Gits also support updateInstead with which we can have the target Git run git checkout, but only in certain circumstances; this allows non-bare repositories to be used with git push even with a branch occupying their work-tree-and-index pair.

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

如何将/ff分支提升到HEAD 的相关文章

随机推荐

  • 内部没有图像的链接的 jQuery 选择器

    我绑定一个click链接功能 body on click a function do something 现在我正在寻找一个仅在链接不包含图像标签时才匹配的选择器 有点类似于a not img but img是子元素 我怎样才能做到这一点
  • 修复 Vanilla JS Accordion 以一次展开一个选项卡

    我有这个手风琴工作 但是 我试图弄清楚如何一次仅展开一个 单击另一个选项卡 另一个选项卡关闭 我尝试了不同的方法来删除该类 但没有得到预期的结果 我也一直在尝试重构for循环到 ES6 标准 但这不是一个问题 样式是 Sass 因此在 JS
  • 从文本文件加载数据然后将其存储到数据库的最快方法

    我有问题 我正在开发一个项目 但我陷入了这一部分 我想从文本文件加载数据并将其存储到数据库访问中 things 是每个文本文件内的数据 大约 12 000 行数据 每个文本文件大约需要 10 分钟来处理 注意 在存储数据之前 我将文本文件中
  • WSo2 EMM - 应用程序管理数据库错误

    运行 WSo2 EMM 1 1 0 除了一个大问题外 一切都工作正常 从我第一次单击 应用程序管理 选项卡中的应用程序那一刻起 只要服务器正在运行 WSO2EMM DB h2 db 文件就会开始稳定增长 即使完全没有任何更改 最终 它变得如
  • PL/pgSQL 中“$$”的用途是什么

    对于 PL pgSQL 来说是全新的 双美元符号的含义是什么这个功能 http postgres cz wiki PL pgSQL 28en 29 CREATE OR REPLACE FUNCTION check phone number
  • 何时对 xmlns 使用 URN

    对于 hello world 类型的 xml 文档
  • 如何在引导程序中将边框半径应用于?

    我需要一行应该是圆角的 并且行与行之间有间距 到目前为止 我尝试了如下所示的表格 曲线类 任何建议 修改都会有帮助 My CSS table curved border collapse separate table curved bord
  • 如何等待所有请求完成

    我用的是宁AsyncHttpClient从命令行程序 我需要等待所有请求结束 以便我可以安全地拨打电话close 在客户端上 挑战在于我从该计划的许多不同部分提出了许多请求 下面剥离了自己的代码 显示了我从以下位置执行嵌套 HTTP 请求的
  • 如何使PHP库松耦合? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • BasicNetwork.performRequest:意外响应代码 500

    我的 Android Studio 中有这个登录 Java 代码 private void loginUser pd ProgressDialog show LoginActivity this Loading StringRequest
  • 将 jQuery 与托管在 Github 页面上的 Jekyll 站点结合使用

    我有一个简单的 Jekyll 博客托管在 github 页面上 我已经包含了 jQuery 和 tablesorter 插件 但遇到了错误 据我所知 这个错误是由于没有以正确的顺序加载 jQuery 引起的 我的下图显示代码的顺序是正确的
  • 在数据库中存储多维数组:关系数组还是多维数组?

    我读过很多类似的帖子多维到单维 多维数据库等等 但没有一个答案有帮助 我确实在谷歌上找到了很多文档 但只提供了背景信息 并没有回答手头的问题 我有很多彼此相关的字符串 PHP 脚本中需要它们 结构是分层的 这是一个例子 A AA AAA A
  • 使用 React 组件内的 标签进行锚定导航

    我正在尝试在我的反应应用程序内的页面组件之一中设置锚点导航 我正在尝试模仿所看到的相同功能在 Draft js 上 https draftjs org docs getting started installation它使用子标题作为锚点
  • 子进程c的返回值

    我需要帮助将 状态代码 从子程序返回给父程序 它将检查状态代码 打印代码并退出父程序 这是一个班级项目 所以我会在这里放置一些相关代码 但出于明显的原因 我不会发布整个项目 我已经通过 exec 分叉并创建了子进程 父进程进行一些奇特的数学
  • 当用户关闭 IE 时显示消息框

    当用户关闭 IE 时 是否有 JavaScript 提示消息框 我尝试寻找代码示例很长一段时间但失败了 提前致谢 乔治 这是我的 html 代码 但有以下错误 有任何想法吗 为了帮助保护您的安全 Internet Explorer 已限制此
  • 每个会话的 Nhibernate 会话示例

    您好 nhibernate 的一些专业人士能给我每个会话的 Nhibernate 会话实现示例还是 unhaddins 实现吗 或者解释如何做到这一点 此致 恩迪斯 我使用 NHibernate 工作了 4 年 此前我曾与 每次操作打开会话
  • 将 IPython 控制台连接到互联网上的内核

    我一直在努力让这个工作正常进行 我已经按照我能找到的在线内容进行操作 但没有成功 例如 Ipython 文档 http ipython org ipython doc stable interactive qtconsole html 我正
  • 我需要什么类型签名才能将函数列表转换为 Haskell 代码? [复制]

    这个问题在这里已经有答案了 可能的重复 为什么 haskell 中不允许这样的函数定义 https stackoverflow com questions 6168880 why is such a function definition
  • 使用 jq 将两个 JSON 数组合并到一个文件中

    我有一个包含两个数组的 JSON 文件 我想将数组组合成一个对象数组 每个对象都包含每个原始数组中的一个元素 JSON 输入如下所示 en E1 E2 E3 E4 fr F1 F2 F3 F4 期望的输出 en E1 fr F1 en E2
  • 如何将/ff分支提升到HEAD

    我有一个受保护的分支 只有在集成构建上的集成构建通过后 才应提升 快进该分支 我目前尝试通过在集成分支的拉取请求上构建集成来解决这个问题 一旦成功 只需将发布分支快速转发到集成分支的尖端 但是 当我在 TFS 构建系统上构建分支时 它将检出