git pull --rebase origin标记名?

时间:2015-12-02 23:21:51

标签: git git-rebase git-pull git-tag

我正在挖掘一些使用git的生产脚本,并尝试理解这个命令:

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

根据我在git pullgit rebase的文档中发现的内容,看起来永远的唯一内容应该是{{1} bash变量,必须是命令才能工作的分支名称。

对于给定标记或提交而不是分支,此命令将执行的操作是否存在记录的行为?我在哪里可以找到它?

2 个答案:

答案 0 :(得分:1)

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

上面的postgis变量可以重命名为tag_or_commit,或者只是tag_or_branch_or_commit。我认为变量名称有点误导/混淆。

我发现最常见的使用rebased来给出一个分支,这意味着将分支重新绑定到最近的提交。提供提交(或标记)将重新提交到该提交,而不再进一步。

所以上面的完整命令是从原点拉出来的,然后重新定位已经发生的提交,直到commit指的是这一点。一个用例可能是你想要重新生成已发布到生产的内容,并且你有一个标签tag_or_commit,那么如果你要执行:

production_release

您将获得git pull --rebase origin production_release标记之前的所有提交,但不会更多。

答案 1 :(得分:1)

修改:根据您对上一个答案的评论,您只是遗漏了一件事:git rebase步骤重新定义当前分支,无论您传递给git pull的论点是什么。你可以跳过剩下的所有内容了!

它实际上在the git pull documentation,但在典型的git文档方式中,使得更加混乱:

  

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

缺少的是“refspec”的完整定义以及git pull运行的两个部分的详尽描述。不幸的是,对于第一部分,refspecs同时出现在fetch和push中,但在它们中表现不同。可以说,对于获取目的,通常只需命名远程存在的分支或标记,git fetch将其复制到您自己的存储库,但将名称更改为远程跟踪分支,例如{ {1}},如果它是分支。对于标签,它保持名称不变。 (更准确地说,原始origin/master在您的存储库中变为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 merge tag将: 1

  1. 运行git pull
  2. 运行git fetch origin tag
  3. 如果需要,获取步骤将创建一个本地标记,如果需要,可以获取任何相应的提交和其他对象,或者如果您已经拥有标记,则只是一个美化的无操作。

    第二步是特别令人困惑的一点。将标记名称传递给git rebase tag作为其“上游”参数似乎很奇怪。然而,它是明确的,可以理解;如果您知道有关rebase的秘密,那么在the git rebase documentation中也可以很好地描述这一点:它不会更改任何提交,它只是复制一些提交,然后重新指出你当前的分支。

    首先,git获取当前分支中包含的提交列表, 2 ,不包括从命名上游可到达的任何提交:

    git rebase

    接下来,git进入一个新的匿名分支,从$ git rev-list tag..HEAD 参数标识的提交开始,或者如果没有--onto,则由“upstream”参数标识提交。在这种情况下,没有--onto,“上游”参数是一个标签,所以git可以简单地检查标签(它不完全 - 它使用一般用于分支名称的形式 - 但是它的效果相同)。

    作为倒数第二步,rebase“重放”其ID在--onto输出中的每个提交。从本质上讲,git cherry-将每个这样的提交选择到新的匿名分支中。

    作为最后一步(如果一切顺利,或者你已完成并完成git rev-list之后),git移动你在 3 上的分支指向通过复制所有要复制的提交进行的最终提交。假设您位于标记的提交git rebase --continue“之前”的某个分支上,我们可以绘制最终结果的图形,如下所示:

    T

    此处 A - B - C [abandoned] / o - o - T - o - o <-- somebranch \ A' - B' - C' <-- HEAD=yourbranch A是您在C步骤之前yourbranch上的原始提交,而git pull origin tagA'是他们的副本。

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

    2 如果您根本没有分支,这甚至可以工作:在这种情况下,git使用由git pull中的任何提交ID定义的匿名分支。

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