繁体   English   中英

获取合并分支分支的提交(中间合并)

[英]Get commit where merged branch forked from (with intermediate merge)

让我们使用最新的git 2.16.2和tig 2.3.3。

cd /tmp && mkdir fit && cd fit

git init
touch m1 && git add m1 && git commit -m "master 1"
touch m2 && git add m2 && git commit -m "master 2"
git checkout -b develop
touch d1 && git add d1 && git commit -m "develop 1"
git checkout master
touch m3 && git add m3 && git commit -m "master 3"
git checkout develop
git merge master --no-edit
touch d2 && git add d2 && git commit -m "develop 2"
touch d3 && git add d3 && git commit -m "develop 3"
git checkout master
git merge develop --no-edit
touch m4 && git add m4 && git commit -m "master 4"

git reflog expire --expire=now --all && git gc --prune=now --aggressive

TIG 在此处输入图片说明

检索develop分支中的最后一个提交非常容易:

git --no-pager show -s --format=%B $(git rev-parse develop)

发展3

但是我无法在develop分支中检索到第一次提交 所以我找不到分支从哪里分支的提交。

git merge-base --fork-point develop
git rev-list develop..master
git rev-list develop master
git rev-list master develop
git rev-list ^develop master

结果没有用。

我找到了一个问题的解决方案, 如何从合并分支分支的地方获得提交

git oldest-ancestor master develop
git oldest-ancestor develop master

结果也没有用。

但是, tiggit log --graph仍然能够看到develop 1是第一个提交的develop分支,这个分支从分叉master 2在提交master

是否可以使用当前的git控制台工具检索master 2

 git --no-pager show -s --format=%B $(git rev-parse develop) 

更简单:

git --no-pager show -s --format=%B develop

要么:

git --no-pager log --no-walk --format=%B develop

show -slog --no-walk几乎是同一件事;这里的关键项是删除不必要的git rev-parse )。

但是我无法在develop分支中检索到第一次提交

该分支中的第一个提交是master 127ee6b8中的27ee6b8 (哈希ID随提交时间的不同而不同)。 这也是分支master的第一次提交。

这里的问题是分支没有“起点”。 从某种意义上说,分支结构(即图形片段),它是通过从终点开始然后再回到起点而到达的。 这意味着某些提交在许多分支上; 通常, 提交是您在存储库中进行的第一次提交,位于每个分支上(尽管在具有多个根的存储库中,某些根可能不在某些分支上)。

通常,分支名称 (有些例外)与该分支上的tip commit同义词,这就是为什么您不需要显式的git rev-parse 但是,分支名称的主要特征是它随着时间的推移而移动 ,因此它总是命名分支的尖端提交。

另请参见“分支”到底是什么意思?

如果您希望标记某些特定的提交,以便以后记住它,通常的工具是Git标签。 标签非常类似于分支名称,因为它标识一个特定的提交。 但是,与分支名称不同,永远不要移动标签,并且Git不会自动移动标签。

 git reflog expire --expire=now --all 

专门存在引用日志是为了能够观察引用的移动(随时间变化)。 一个分支名状的引用日志develop保留,默认情况下为30天或90天,1散列ID的develop 用于识别。 通过使它们过期,您已经失去了回到过去并查看develop@1develop@2等的功能。 如果保留了它们,则可以寻找现有的最古老的develop 可能是它诞生的时候,您通常可以说:

05d0c47 master@{37}: clone: from ...

(表明此刻master已出生)。

不幸的是,刷新日志确实会过期,因此这不是完全可靠的。 标签是可靠的,但可能会令人讨厌,因为git log会用其标签装饰提交。 如果有寻找有趣的提交程序 ,你可以使用。 在这种情况下,有一个这样的过程:您想要的合并曾经是或曾经是合并的提交。

要找到合并基础,请找到合并本身,然后找到其父级:

m=11c63bc  # this is the merge
p1=$(git rev-parse ${m}^1)
p2=$(git rev-parse ${m}^2)

现在$p1$p2是此合并的两个父级。 (一个合并可以有两个以上的父级,但是大多数合并只有两个。)最后两个合并这两个分支的共同点是两个父级的合并基础:

git merge-base --all $p1 $p2

由于只有一个合并基础,因此只打印一个提交哈希。 如果有几个,它将打印所有的,因为我们使用了--all 省略--all ,我们将(显然)随机地选择一个(实际选择的一个取决于用于查找合并基础的算法)。

和以前一样,不需要很多临时变量,我们可以这样做:

mbases=$(git merge-base --all ${m}^1 ${m}^2)

因为git merge-base采用与git rev-parse相同的commit-specifier语法: ^1^2后缀在那里工作相同(并且实际上在大多数Git命令中工作)。


1到期时间是可配置的。 较短的时间(默认为30天)用于从引用的当前值无法访问的哈希ID。 90天的默认较长时间是从引用的当前值可访问的哈希ID。

暂无
暂无

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

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