Git:在标签后结帐到2次提交

时间:2017-03-10 14:13:37

标签: git

了解以下方案: enter image description here

黄线是主分支。 红线是开发分支。

我在标签6.2.1上的主人。 我需要自动获取以蓝色圈出的提交的sha1,检查这个sha1并从这个sha1创建我的分支。此提交不是开发的最后一次提交。

要做的事情可能包括:

  • 获取标记6.2.1的sha1:git log --oneline | head -1 | cut -d ' ' -f1
  • 获取标记6.2.1的父级:名为commit' P'
  • 获得以下“P' P'叫做提交' C1'哪个应该开发
  • 接下来提交' C1'叫做“C2'也在发展。

目前我必须手动继续使用Gitlab,在签出之前获取相关的sha1,然后创建我的分支。

2 个答案:

答案 0 :(得分:1)

有一种方法,但存在潜在的问题。

标签名称标识提交。

更具体而又准确地说,像[{1}}这样的标记名称是完全限定的引用名称v2.1的简短版本,任何Git引用都标识了一些Git对象。所有分支名称(例如refs/tags/v2.1都是master的缩写)被限制为仅识别 提交对象。标记名称通常标识提交对象-Git,将其称为轻量级标记 - 或带注释的标记对象,然后继续识别提交。在任何一种情况下,special gitrevisions syntax refs/heads/master都会引用特定提交,如果您需要(通常您不会发现,例如,name^{commit}需要提交,自动添加git checkout

问题是,您不希望标记识别的提交。您需要附近的提交。你说"两次提交之后"这是一个问题:在另一次提交之后没有提交这样的事情。在另一次提交之前只有提交

异议,你的荣幸!

如果在提交之前有提交,那么在提交之后如何没有提交?例如,让我们连续写下四个提交:

^{commit}

在Git中,提交A <- B <- C <- D 存储其提交的ID,即提交D。因此,C给出D很容易回到C。同样,C存储B的ID和B商店A。 (如果A是第一次提交,那么没有父级:您无法后退,A root commit 。 root commit是没有父级的。)

这里的问题是,在提交之前或提交之后,可能会有多个提交。而不仅仅是上述内容,请考虑此图片段:

A--B--C--D---H   <-- master
    \       /
     E--F--G     <-- feature

提交H,即分支master提示,是 merge 提交。它有两个父母:DG。当我们检查提交H时,我们会看到类似这样的内容(使用不同的数字):

$ git show master
commit 3e5c63943d35be1804d302c0393affc4916c3dc3
Merge: c13c783 20690b2

这意味着它有两个父母,c13c783...20690b2...在提交H之前哪一个 提交?

因此,异议的答案是在提交之前没有 提交,有可能 - 很多(通常为1,有时为2,稀有)但在另一次提交之前偶尔会提交零或三次或更多次提交。同样,在另一次提交之后,可能没有或两次或更多次提交

要查找您想要的提交,您需要更多信息。

更多信息

一般来说,向后移动很容易。提交的第一个(通常是唯一的)父级通常是有趣的,因为它是之前的分支的提交/ em>该提交已将添加到该分支。也就是说,虽然提交H同时将D G作为父项,但master过去曾指向D现在指向H,它是我们想要的H 第一个父级。

Gitrevisions有一个快速简单的语法来跟踪前父母:你只需添加一个代字号~字符和一个有多少第一父母退一步的计数。所以,要从v2.1继续执行 back 两个步骤,仅关注第一个父母,只需写下v2.1~2

git checkout -b newbranch v2.1~2

你已经完成了。

前往前进更难。 Git只存储向后链接,因此您需要提供以后提交的名称或标识,Git可以从此向后工作以达到您已知(标记)的提交。例如,如果我们有一个指向提交C的标记,并且我们想要向前移动两步(到D再到H),我们会给Git 两个< / em>信息:

  1. 请以v2.1
  2. 结束
  3. master
  4. 开始

    让它枚举这两点之间的所有提交,然后选择一两步&#34;接近master&#34;而不是v2.1的最后一个。现在让我们说master现在还有更多提交,所以图纸看起来像这样:

       tag:v2.1
          |
          v
    A--B--C--D---H--I   <-- master
        \       /
         E--F--G     <-- feature
    

    要以这种方式查找H,我们会使用git rev-listyet more gitrevisions syntax。 (到目前为止,显然学习gitrevisions语法对于使用Git 至关重要。)

    git rev-list v2.1..master
    

    这里的双点语法意味着&#34; 不要包括v2.1本身&#34;,所以这将列出从master开始提交并返回到在v2.1之后提交:

    0fbc341...   # id of I
    a9315c3...   # id of H
    9911231...   # id of D
    

    我们获取这两个ID中的最后两个,丢弃这些ID中的最后一个一个,然后获取a9315c3,即H的ID。

    但仍存在潜在问题

    如果图表看起来更像这样怎么办?

       tag:v2.1
          |
          v
    A--B--C--D---------H--I   <-- master
              \       /
               E--F--G     <-- feature
    

    我们之前注意到,使用~表示法使用 first 父级。我们可以使用git rev-list --first-parent v2.1..master来完成此操作。这将使Git无法列出G-F-E,这将确保我们找到H而不是E

    --topo-order添加到rev-​​list命令也是一个好主意,因为否则这些提交会按提交日期顺序列出,如果日期/时间被搞砸了在制作存储库时涉及的计算机中,提交可能以错误的顺序列出。

    还有--ancestry-path选项,在某些情况下很有用(可能不适用于您自己的情况):它确保git rev-list仅列出后代的提交..操作的左侧。你可以在不需要--first-parent的地方使用它,例如:

    ...--o--*--A--B--C
          \        \  \
           D--E--F--G--H   <-- branch
    

    如果我们想要提交&#34;三个步骤&#34;在标记提交*之后,可以是CG。使用git rev-list tag..branch会打印AH的所有内容(按某种顺序排列)。添加--first-parent会切断G C - 这两个中只有一个可以是{{1>的第一个父级 - 如果你想看两者,你就不能使用H。添加--first-parent会使--ancestry-path省略git rev-list;其余的仍将以某种顺序出现。添加D-E-F将保证--topo-order倒数第二,B最后出现(请记住,Git正在倒退),A和{{1}在他们之前的任何顺序,并C首先。

    这不是一个完整的解决方案,但如果你有一个像这样的分支和合并图,那么就没有完整的解决方案。

    无论如何,选择这些选项的一些子集。如果你知道你的图表是第一父母的,那么,例如:

    G

    将为您提供所需的哈希值。

    (对于另一个稍微微妙的技巧,添加H以从git rev-list --topo-order --first-parent tag..branchname | tail -2 | head -1反转打印输出顺序,然后使用--reverse打印第二行。但是,您无法在此处使用git rev-list的{​​{1}}标记,因为它会从未反转的列表中计算并停止,而我们我不知道会有多少次提交,我们想要的是次要的,不管多少次。)

答案 1 :(得分:0)

打开git bash,转到所选目录,然后运行以下命令。 获取SHA1运行命令

git log branchname --oneline

它将在提交消息旁边显示sha1

enter image description here

git branch branchname <sha1-of-commit>