【问题标题】:How to make the parent git folder always point to latest commit whenever there is a new commit in child module(submodule) - Any Alternative?每当子模块(子模块)中有新提交时,如何使父 git 文件夹始终指向最新提交 - 任何替代方案?
【发布时间】:2021-10-27 06:03:50
【问题描述】:

每次我将提交推送到子模块时,我都需要将父 repo 更新为子模块中的最新提交。有没有自动的方法在遥控器中做到这一点?

我知道我无法直接实现这一点,但是有人可以建议 git 子模块的替代方案吗?我刚刚看到了 git-tree、google repo 工具,但不确定如何更改我当前的设置以使用这些工具?

【问题讨论】:

  • 子模块 Git 存储库通常甚至不知道某些超级项目正在使用它们。这实际上是不可能的:如果我在 GitHub 上的 repo X 是您的子模块,并且我在我的 repo X 中进行了新提交,我不会提醒您注意它们。
  • @torek ,这是正确的,但我们可以在这个上做些什么,我的场景我想将基础设施相关代码放在一个单独的存储库中,应用程序代码应该在另一个存储库中,但是我的应用程序代码应该使用我的基础代码(在不同的仓库中)
  • 如果你控制了两个 repos,这里没有问题:每当你在 repo S(子模块)中进行新的提交时,在 repo R(超级项目)中进行新的提交。为自己写一个小脚本(甚至是一个大脚本,无论大小如何)。
  • @torek ,但如果我的基础存储库发生变化,每次都需要更新近 15-20 个应用程序代码存储库。即使我们编写了一个脚本,该脚本应该在哪里执行??????,我们如何调用脚本??????目前,每当 infra repo 发生变化时,我都会手动更新所有 repo。
  • 好的,所以你有一个“依赖于 S 的存储库”的列表。您的脚本将显示为:for R in <list of Rs> 或类似名称,具体取决于您用于编写脚本的语言。鉴于有许多 ,脚本可能应该维护一个小型数据库或日志文件,其中 已成功更新,而尚未更新。

标签: git git-submodules git-commit


【解决方案1】:

你提到了谷歌回购工具。这是repo 的解决方案。

假设您有两个存储库,parent.git 和 sub.git,托管在 https://hostingservice。预期的文件夹结构是

parent/
├── .git
└── sub/
    └── .git

由于sub不是parent的子模块,需要将其添加到parent的.gitignore中。

创建一个存储库以跟踪存储库清单。假设它是https://hostingservice/manifest.git。制作一个清单 foo.xml 来组织 parent.git 和 sub.git。

<?xml version="1.0" encoding="UTF-8"?>
<manifest>
    <remote fetch=".." name="origin"/>
    <default remote="origin"/>
    <project name="parent" path="parent" revision="release_v1.2" />
    <project name="sub" path="parent/sub" revision="release_v0.3" />
</manifest>

在manifest.git 中添加并提交foo.xml 并假设它在分支default 上。

现在您可以使用repo 下载parent.git 和sub.git,

# initialize the current folder as a repo environment
repo init -u https://hostingservice/manifest.git -b default -m foo.xml

# clone the repositories and check out their revisions
repo sync -c -d

repo init 克隆 manifest.git 并将 default 签出到 .repo/manifests。

foo.xml 指示repo 克隆parent.git 并将其分支release_v1.2 检出到当前目录下的文件夹parent 中,并克隆sub.git 并将其分支release_v0.3 检出到@987654353 @。

revision="release_v0.3" 表示每次重新运行repo init 和repo sync 命令时始终使用release_v0.3 的当前头。有时您可能希望从release_v0.3 访问特定的提交8b6228f4e0f5b059a6d5d93ba9aed15089c4b324,然后使用revision="8b6228f4e0f5b059a6d5d93ba9aed15089c4b324" upstream="release_v0.3" 来获得固定修订。

如果需要,您可以向foo.xml 添加更多存储库。

【讨论】:

【解决方案2】:

每次我将提交推送到子模块时,我都需要将父 repo 更新为子模块中的最新提交。有没有自动的方法在遥控器中做到这一点?

自动的方式来做到这一点?是的。 “在远程”取决于托管远程的内容。

要做到这一点本地,你可以有一个 pre-push 钩子来检查 repo 是否被用作 vanilla-ish 子模块(工作树直接嵌套在使用项目的工作树内)并自动更新包含项目,这是该逻辑的草图:

set -x
IFS=$'\n'  # just sidestep wordsplitting
toplevel=`git rev-parse --show-toplevel` || exit
if up=`git -C $toplevel/.. rev-parse --show-toplevel 2>&-`; then
        # we're checked out and nested inside another checkout
        sm_path=${toplevel#$up/}
        if uplink=`git -C $up rev-parse -q --verify :$sm_path`; then
                # and it's got an index entry for this checkout:
                # it's using us as a submodule. update its gitlink entry.
                git -C $up update-index --cacheinfo 160000,$(git rev-parse @),$sm_path
        fi
fi

这是最难的部分,自动更新包含项目的结帐。

这里的问题是,您到底有多确定包含 checkout 是否真的适合使用新的子模块内容进行更新,或者新的子模块内容不是不适合生产使用的探索性内容?我并不是说这不能完成,我是说您在此处所做的任何选择都会严重限制您可以安全使用的工作流程或使代码大大复杂化。在预推送中弹出一条消息可能更容易,提醒您可能还想添加、提交和推送包含的项目。

【讨论】:

  • 我的 repo 托管在 bitbucket .gitmodules 结构是:[submodule "infra/charts"] path = arch/chart url = bitbucket.xxxx.xxxxx/scmgmt/archdev/chart.git branch = develop
  • 然后学习如何在 bitbucket 托管的存储库上运行钩子并发现子模块结构等,或者在本地存储库上执行此操作并按照建议推送结果。
猜你喜欢
  • 2021-09-21
  • 2017-04-11
  • 1970-01-01
  • 1970-01-01
  • 2013-01-03
  • 2021-12-07
  • 2014-01-06
  • 2021-05-06
  • 2012-06-06
相关资源
最近更新 更多