繁体   English   中英

git pull --rebase原始标记名?

[英]git pull --rebase origin tagname?

我正在研究一些使用git的生产脚本,并试图理解此命令:

git pull --rebase origin "${tag_or_commit}"

从什么我发现了文档中的git pullgit rebase ,它看起来像应该永远是在唯一tag_or_commit bash的变量,必须是一个分支名称为命令在所有的工作。

给定标签或提交而不是分支的情况下,此命令将执行的操作是否有记录的行为? 在哪里可以找到它?

标签和分支实际上只是对提交的引用,主要区别是分支指向移动的目标(该分支上的最新提交),而标签则引用单个时间点提交,但最终它们只是指向一次提交。

上面的tag_or_commit变量可以重命名为tag_or_branch_or_commit ,或者简单地称为commit 我认为变量名有些误导/令人困惑。

我发现将其重新建立基础以提供分支的最常见用法,这意味着将分支重新构建为最新的提交。 提供一个提交(或标记)将根据该提交进行基础,并且不再进行。

因此,上面的完整命令是从原点开始的,然后根据已经发生的提交重新tag_or_commit引用的位置。 一个用例可能是,如果您想基于已发布到生产环境中的内容,并具有一个标签production_release ,那么如果要执行:

git pull --rebase origin production_release

您将获得所有提交,直到production_release标签为止,但没有更多。

编辑 :根据您对上一个答案的评论,您只缺少一件事: git rebase步骤为当前分支重新设置基础 ,无论您传递给git pull参数如何。 您可能可以跳过所有其他操作!


它实际上在git pull文档中 ,但是以典型的git文档方式,使人更加困惑:

<refspec>可以命名任意远程ref(例如,标记名称),甚至可以命名具有相应远程跟踪分支的ref集合(例如refs / heads / *:refs / remotes / origin / *),但是通常,它是远程存储库中分支的名称。

缺少的是对“ refspec”的详尽定义,以及对git pull运行的两个部分的详尽描述。 不幸的是,对于第一部分,refspecs出现在提取和推送中,但在它们中的表现却有所不同。 可以说,出于获取目的,通常只需命名远程git fetch上存在的分支或标记,然后git fetch复制到您自己的存储库中,但将名称更改为远程跟踪分支,例如origin/master如果是分支 对于标签,它的名称保持不变。 (更确切地说,origin的refs/heads/master变为您存储库中的refs/remote/origin/master ,而其refs/tags/v1.2保留为refs/tags/v1.2 。)

第二部分可能会更容易一些: git pull收集一些标志并对其进行操作,然后将其余标志传递到第一步git fetch git pull收集的标志之一是--rebase ,它告诉它使用git rebase作为第二步。 否则,它会查看是否git rebase其配置为自动使用git rebase 如果不是,则默认使用git merge

在这种情况下,给定标签名称taggit pull将: 1

  1. 运行git fetch origin tag
  2. 运行git rebase tag

提取步骤将在需要时创建一个本地标签,在需要时提取任何相应的提交和其他对象,或者如果已经有了该标签,则只是美化无操作。

第二步是特别令人困惑的地方。 将标签名称传递给git rebase作为其“上游”参数似乎很奇怪。 但是,它定义明确且有意义。 并且在git rebase文档中也对此进行了很好的描述,只要您知道有关rebase的秘诀:它不会更改任何提交,它只会复制一些提交,然后重新指向您的当前分支。

首先,git获取当前分支中包含的提交列表, 2排除从指定上游可到达的任何提交:

$ git rev-list tag..HEAD

接下来,git进入一个新的匿名分支,该分支以--onto参数标识的提交开始,或者如果没有--onto--onto “上游”参数标识的提交开始。 在这种情况下,没有--onto并且“ upstream”参数是一个标记,因此git可以简单地检出该标记(它并不完全—它也使用适用于分支名称的通用形式—但它可以正常工作一样)。

作为倒数第二步,rebase会“重播” ID在git rev-list输出中的每个提交。 从本质上讲,git cherry-picks将每个此类提交提交到新的匿名分支中。

作为最后一步(如果一切顺利,或者在完成所有工作之后, git rebase --continue ),git移动您所在的分支3指向通过应付所有待完成的最终提交复制的提交。 假设您在一个分支上,该分支起源于被标记的提交T之前的某个地方,我们可以这样绘制最终结果的图形:

    A - B - C            [abandoned]
  /
o - o - T - o - o         <-- somebranch
          \
           A' - B' - C'   <-- HEAD=yourbranch

这里AC是您在git pull origin tag步骤之前在yourbranch上的原始提交,而A'C'是它们的副本。


1这仍然是简化的,并且git pull随着时间的推移而发展; 实际的参数可能会变得非常复杂。 幸运的是,对于这个特殊情况,这些都不重要。

2如果您根本不在分支上,这甚至可以工作:在这种情况下,git使用由HEAD任何commit-ID定义的匿名分支。

3如果您不在分支上,那就更容易了:它只是完全跳过了这一步。 HEAD仍指向一个匿名分支,但现在是复制的分支。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM