Git:签出以在标记后提交2

Git:签出以在标记后提交2,git,Git,了解以下计划: 黄线是主分支。 红线是开发分支 我在6.2.1号标签上的Master上。 我需要的是自动获取用蓝色圈起来的提交的sha1,签出到这个sha1并从这个sha1创建我的分支。此提交不是develop的最后一次提交 要做的事情可能包括: 获取标签6.2.1的sha1:git log--oneline | head-1 | cut-d''-f1 获取标记6.2.1的父级:称为提交“P” 获取名为commit“C1”的“P”的以下提交,该提交应处于开发状态 在develope上获得名为

了解以下计划:

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

我在6.2.1号标签上的Master上。 我需要的是自动获取用蓝色圈起来的提交的sha1,签出到这个sha1并从这个sha1创建我的分支。此提交不是develop的最后一次提交

要做的事情可能包括:

  • 获取标签6.2.1的sha1:
    git log--oneline | head-1 | cut-d''-f1
  • 获取标记6.2.1的父级:称为提交“P”
  • 获取名为commit“C1”的“P”的以下提交,该提交应处于开发状态
  • 在develope上获得名为“C2”的“C1”的以下提交

目前,我必须手动进入Gitlab,在签出之前获取相关的sha1,然后创建我的分支

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

git log branchname --oneline
它将在提交消息旁边显示sha1

git分支名称

有办法,但也有潜在的问题

标记名标识提交

更具体、更精确地说,像
v2.1
这样的标记名是完全限定引用名
refs/tags/v2.1
的简短版本,任何Git引用都标识一些Git对象。所有分支名称,例如
master
(refs/heads/master的缩写)都被约束为仅标识提交对象。标记名通常标识提交对象Git称之为轻量级标记或带注释的标记对象,后者接着标识提交。在任何一种情况下,
name^{commit}
都会引用特定的提交,如果您需要的话(通常您不知道,例如,
Git checkout
需要提交并自动添加
^{commit}

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

反对,法官大人! 如果在提交之前有提交,那么在提交之后怎么可能没有提交呢?例如,让我们在一行中写下四个提交:

A <- B <- C <- D
提交
H
,它是分支
master
的尖端,是一个合并提交。它有两个父项:
D
G
。当我们检查commit
H
时,我们会看到类似的内容(数字不同):

这意味着它有两个父级,
c13c783…
20690b2…
。哪一个是提交前提交
H

因此,反对意见的答案是,在一次提交之前没有提交,在另一次提交之前可能有很多次(通常是1次,有时是2次,比较少见,但偶尔是零次,或三次或更多)提交。同样,在一次又一次的提交之后,可能没有提交,也可能有两次或更多的提交

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

更多信息 一般来说,向后移动很容易。提交的第一个(通常是唯一的)父级通常是有趣的父级,因为它是在提交添加到分支之前在分支上的提交。也就是说,虽然commit
H
同时具有
D
G
作为父对象,但如果
master
过去指向
D
,现在指向
H
,那么它就是我们想要的
H
的第一个父对象

有一个简单快捷的语法,用于跟踪第一个父项:只需添加一个波浪号
~
字符和要后退的第一个父项的数量。因此,要从
v2.1
返回两步,只需跟随第一代家长,只需编写
v2.1~2

git checkout -b newbranch v2.1~2
你完成了

向前走更难。Git只存储向后的链接,所以您需要做的是提供稍后提交的名称或标识,Git可以从中向后工作以达到已知(标记的)提交。例如,如果我们有一个指向commit
C
的标记,并且我们想向前推进两个步骤(到
D
,然后到
H
),我们会给Git两位信息:

  • 请在
    v2.1
  • 并从
    master
  • 并让它枚举这两点之间的所有提交,然后选择“更接近
    master
    ”的两步,而不是
    v2.1
    的最后一步。现在让我们假设
    master
    上有更多提交,因此图形如下所示:

       tag:v2.1
          |
          v
    A--B--C--D---H--I   <-- master
        \       /
         E--F--G     <-- feature
    
    此处的双点语法表示“不包括
    v2.1
    本身”,因此这将列出从主控开始并在
    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
    
    如果我们希望在标记的commit
    *
    之后执行commit“三步”,那么可以是
    C
    G
    。使用
    git rev list tag..branch
    将通过
    H
    打印所有
    A
    (按一定顺序)。添加
    --first parent
    将切断
    G
    C
    -这两个选项中只有一个可以是
    H
    的第一个父级-如果您想同时查看这两个选项,则不能使用
    --first parent
    。添加
    --祖先路径
    将使
    git版本列表
    忽略
    D-E-F
    ;其余的仍将以某种顺序出现。添加
    --topo order
    将保证
    B
    排在倒数第二,
    A
    排在倒数第二(记住,Git是向后工作的),并且
    C
    G
    以任何顺序排在前面,而
    H
    排在第一

    这不是一个完整的解决方案,但没有完整的解决方案
       tag:v2.1
          |
          v
    A--B--C--D---H--I   <-- master
        \       /
         E--F--G     <-- feature
    
    git rev-list v2.1..master
    
    0fbc341...   # id of I
    a9315c3...   # id of H
    9911231...   # id of D
    
       tag:v2.1
          |
          v
    A--B--C--D---------H--I   <-- master
              \       /
               E--F--G     <-- feature
    
    ...--o--*--A--B--C
          \        \  \
           D--E--F--G--H   <-- branch