查找从未被推送到公共存储库的子模块提交

时间:2012-01-25 23:36:00

标签: git shell git-submodules

有人可以帮助我填写我正在尝试编写的脚本中缺少的部分吗?我刚刚意识到我有一个公共存储库,其中包含对子模块中提交的引用,这些提交从未推送到源(提交在推送之前已重新组织)。我不知道它发生了多少次,但我想找出并创建临时分支以推动原点。

所以,回到剧本。我知道我可以获得一个包含对子模块更改的提交列表,我可以使用grep进行过滤,并使用cutmy_submodule获取实际的SHA1标记:

git log -u origin/master -- my_submodule \
    | grep "^\+Subproject" \
    | cut -d" " -f 3

此时,我有20个标签,我只是使用文本编辑器制作一个脚本,用“tag_00xx”手动标记每个标签。然后我在Git Extensions中手动查看了存储库,并删除了任何已使其成为origin / master的提交标记,留下了一个从未被推送过的标记。

我应该怎么做只为不在origin / master中的提交创建标签?我知道我能做到:

git branch -r --contains <commit_sha1>

但是这并没有设置我可以用来有选择地创建新标签的退出代码。我怎么能完成任务的自动化?

1 个答案:

答案 0 :(得分:1)

我可能会通过以下方式执行此操作 - 首先,您可以通过执行以下操作列出所有已提交的子模块版本,而不是grepcut

git rev-list origin/master | while read COMMIT
do
    SUBMODULE_COMMIT=$(git rev-parse $COMMIT:my_submodule 2> /dev/null)
    if [ $? = 0 ]
    then
        echo $SUBMODULE_COMMIT
    fi
done | sort | uniq > committed-submodule-versions

然后,对于每个子模块,您需要更改为子模块并检查它是否在origin/master中。可能最简单的方法是grep git branch -r --contains <SUBMODULE-COMMIT>的输出,从那以后你可以使用grep的退出代码。

例如:

cd my_submodule
while read S
do
    if git rev-parse --verify $S > /dev/null 2> /dev/null
    then
        git branch -r --contains $S 2> /dev/null \
            | grep origin/master > /dev/null \
            || git branch missing-${S:0:8} $S
    else
        echo $S not found in the repository at all
    fi

done < ../committed-submodule-versions

另一点需要注意的是,我正在为未提交的提交而不是标签创建分支。这样做的原因是git submodule update导致git fetch,而不是git fetch --tags,这意味着不会提取未指向已知提交的标记(!)。< / p>