在合并分支分叉的地方获取提交(使用中间合并)
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
检索 develop
分支中的最后一次提交 非常容易:
git --no-pager show -s --format=%B $(git rev-parse develop)
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
结果也没用
但是 tig
和 git 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 -s
和 log --no-walk
几乎是一回事;这里的关键是删除不必要的 git rev-parse
)。
But I couldn't retrieve the first commit in develop
branch
该分支中的第一个提交是 master 1
,或者在您的映像中是 27ee6b8
(哈希 ID 会随着提交的时间而变化)。这也是分支 master
.
中的第一次提交
这里的问题是分支没有"starting points"。分支 是 ,在某种意义上,是从终点开始并返回起点所到达的结构——图形片段。这意味着一些提交在许多分支上;通常,root 提交,即您在存储库中进行的第一次提交,在 every 分支上(尽管在具有多个根的存储库中,一些根可能不在某些分支机构上)。
分支 name 通常(也有一些例外)与该分支上的 tip commit 同义,这就是为什么你不需要明确的 git rev-parse
.然而,分支名称的关键特征是它 随着时间的推移 移动,因此它总是命名分支的尖端提交。
另见 What exactly do we mean by "branch"?
如果你想标记一些特定的提交,以便以后记住它,常用的工具是 Git 标记。标签非常像分支名称,因为它标识一个特定的提交。然而,与分支名称不同的是,标签永远不会移动,并且 Git 不会自动移动它。
git reflog expire --expire=now --all
引用日志专门用于观察引用的移动(随时间推移)。像 develop
这样的分支名称的 reflog 默认保留 30 或 90 天,1 develop
用于识别。通过使它们过期,您已经失去了回到过去查看 develop@1
、develop@2
等的能力。如果您保留了它们,则可以查找现存最旧的 develop
。那可能是它出生的时候,你经常可以看出:
05d0c47 master@{37}: clone: from ...
(表示master
此时诞生)
不幸的是,reflogs do 会过期,所以这并不完全可靠。标签是可靠的,但可能很烦人,因为 git log
会用他们的标签装饰提交。如果有一个 procedure 用于查找有趣的提交,您可以使用它。在这种情况下,有 是 这样一个过程:您想要合并的 合并基础 的提交.
要找到合并基,找到合并本身,然后找到它的父代:
m=11c63bc # this is the merge
p1=$(git rev-parse ${m}^1)
p2=$(git rev-parse ${m}^2)
现在 $p1
和 $p2
是这个合并的两个父项。 (一个merge可以有两个以上的parents,但是大多数merges只有两个。)这两个branch最后合并的共同点是两个parents的merge base:
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。
让我们使用最新的 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
检索 develop
分支中的最后一次提交 非常容易:
git --no-pager show -s --format=%B $(git rev-parse develop)
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
结果也没用
但是 tig
和 git 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 -s
和 log --no-walk
几乎是一回事;这里的关键是删除不必要的 git rev-parse
)。
But I couldn't retrieve the first commit in
develop
branch
该分支中的第一个提交是 master 1
,或者在您的映像中是 27ee6b8
(哈希 ID 会随着提交的时间而变化)。这也是分支 master
.
这里的问题是分支没有"starting points"。分支 是 ,在某种意义上,是从终点开始并返回起点所到达的结构——图形片段。这意味着一些提交在许多分支上;通常,root 提交,即您在存储库中进行的第一次提交,在 every 分支上(尽管在具有多个根的存储库中,一些根可能不在某些分支机构上)。
分支 name 通常(也有一些例外)与该分支上的 tip commit 同义,这就是为什么你不需要明确的 git rev-parse
.然而,分支名称的关键特征是它 随着时间的推移 移动,因此它总是命名分支的尖端提交。
另见 What exactly do we mean by "branch"?
如果你想标记一些特定的提交,以便以后记住它,常用的工具是 Git 标记。标签非常像分支名称,因为它标识一个特定的提交。然而,与分支名称不同的是,标签永远不会移动,并且 Git 不会自动移动它。
git reflog expire --expire=now --all
引用日志专门用于观察引用的移动(随时间推移)。像 develop
这样的分支名称的 reflog 默认保留 30 或 90 天,1 develop
用于识别。通过使它们过期,您已经失去了回到过去查看 develop@1
、develop@2
等的能力。如果您保留了它们,则可以查找现存最旧的 develop
。那可能是它出生的时候,你经常可以看出:
05d0c47 master@{37}: clone: from ...
(表示master
此时诞生)
不幸的是,reflogs do 会过期,所以这并不完全可靠。标签是可靠的,但可能很烦人,因为 git log
会用他们的标签装饰提交。如果有一个 procedure 用于查找有趣的提交,您可以使用它。在这种情况下,有 是 这样一个过程:您想要合并的 合并基础 的提交.
要找到合并基,找到合并本身,然后找到它的父代:
m=11c63bc # this is the merge
p1=$(git rev-parse ${m}^1)
p2=$(git rev-parse ${m}^2)
现在 $p1
和 $p2
是这个合并的两个父项。 (一个merge可以有两个以上的parents,但是大多数merges只有两个。)这两个branch最后合并的共同点是两个parents的merge base:
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。