You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何查找引入特定submodule commit的Git主仓库提交

子模块变更溯源:定位子模块提交首次进入主仓库的时机

问题场景

主仓库FOO包含子模块BAR,两者提交历史如下:

子模块BAR提交历史(最新提交在前)
o - commit E
|
o - commit D
|
o - commit C
|
o - commit B
|
o - commit A

主仓库FOO中子模块更新历史(最新提交在前)
o - commit 3: 更新子模块至commit E
|
o - commit 2: 更新子模块至commit C
|
o - commit 1: 更新子模块至commit A

需要确定子模块BAR的commit B首次被纳入主仓库FOO的提交,预期结果为commit 2——因为commit 1的子模块指向A(不含B的变更),commit 2指向C(已包含B的所有变更)。

当前临时方案

  1. 进入主仓库FOO,提取子模块BAR的更新记录:
cd foo
git log -p bar

手动记录各主仓库提交对应的BAR哈希(如commit 1对应A、commit 2对应C、commit 3对应E)。
2. 进入子模块BAR,找到commit B的哈希:

cd bar
git log
  1. 手动比对BAR的提交顺序,判断B在A之后、C之前,从而得出commit 2是引入B变更的主仓库提交。

注:git submodule summary仅报告子模块合并的起止哈希,无法直接满足需求。

优化解决方案

可以通过组合Git命令直接定位目标主仓库提交,无需手动比对:

单命令快速检索

cd foo
git log --oneline --grep="$(git -C bar rev-parse B)" --follow -- bar

精准定位脚本命令

如果需要更精准地输出第一个符合条件的主仓库提交,可使用以下脚本:

cd foo
# 获取子模块BAR中commit B的哈希值
bar_b_hash=$(git -C bar rev-parse B)

# 遍历主仓库中所有修改子模块BAR的提交,找到首个包含B变更的提交
git log --oneline --follow -- bar | while read commit_info; do
    commit_hash=$(echo "$commit_info" | cut -d' ' -f1)
    # 获取当前主仓库提交指向的BAR哈希
    bar_target_hash=$(git show "$commit_hash":bar)
    # 检查B是否是BAR目标版本的祖先(即该版本已包含B的变更)
    if git -C bar merge-base --is-ancestor "$bar_b_hash" "$bar_target_hash"; then
        echo "$commit_info"
        break
    fi
done

该命令逻辑:

  • 遍历主仓库FOO中所有修改子模块BAR的提交
  • 对每个提交,提取当时指向的BAR版本哈希
  • 通过merge-base --is-ancestor检查commit B是否已包含在该BAR版本中
  • 找到第一个满足条件的主仓库提交后立即输出并终止执行

内容的提问来源于stack exchange,提问作者MrMas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 15:10:24