Git:签出以在标记后提交2
了解以下计划: 黄线是主分支。 红线是开发分支 我在6.2.1号标签上的Master上。 我需要的是自动获取用蓝色圈起来的提交的sha1,签出到这个sha1并从这个sha1创建我的分支。此提交不是develop的最后一次提交 要做的事情可能包括: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的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
。当我们检查commitH
时,我们会看到类似的内容(数字不同):
这意味着它有两个父级,c13c783…
和20690b2…
。哪一个是提交前提交H
因此,反对意见的答案是,在一次提交之前没有提交,在另一次提交之前可能有很多次(通常是1次,有时是2次,比较少见,但偶尔是零次,或三次或更多)提交。同样,在一次又一次的提交之后,可能没有提交,也可能有两次或更多的提交
要查找所需的提交,您需要更多信息
更多信息
一般来说,向后移动很容易。提交的第一个(通常是唯一的)父级通常是有趣的父级,因为它是在提交添加到分支之前在分支上的提交。也就是说,虽然commitH
同时具有D
和G
作为父对象,但如果master
过去指向D
,现在指向H
,那么它就是我们想要的H
的第一个父对象
有一个简单快捷的语法,用于跟踪第一个父项:只需添加一个波浪号~
字符和要后退的第一个父项的数量。因此,要从v2.1
返回两步,只需跟随第一代家长,只需编写v2.1~2
:
git checkout -b newbranch v2.1~2
你完成了
向前走更难。Git只存储向后的链接,所以您需要做的是提供稍后提交的名称或标识,Git可以从中向后工作以达到已知(标记的)提交。例如,如果我们有一个指向commitC
的标记,并且我们想向前推进两个步骤(到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