如何在pull请求之后拥有一个干净的repo,包括子模块



我处理一个git子模块child_repo,该子模块位于具有更多子模块的父repoproject_repo。我在child_repo中推送更改和打开拉取请求,这是我唯一拥有可见性(和写入权限)的repo(在所有子模块中),但整个项目的编译过程包括其他子模块。

在接受了包含我的更改的拉取请求后,保持整个父repoproject_repo的清洁和最新状态的最佳方法是什么?

目前,每当我需要开始开发新功能时,我只是克隆整个项目_repo,但我认为这不是最聪明/正确的方法。

我的猜测如下:

  • 首先丢弃未使用git checkout --<file>git clean -xdf提交的所有文件。这是因为我经常写一些脚本/东西来帮助我完成任务,但不能去master
  • project_repo中的git pull origin master,用于更新引用
  • git submodule update --recursive --init,用于更新子模块的内容

感谢您提供的所有细节Victor!

我将把父repo称为parent_repo,而不是project_repo-

几个问题:

  • 首先丢弃所有未使用gitcheckout或gitclean-xdf提交的文件。这是因为我经常写一些脚本/东西来帮助我完成任务,但无法掌握

您想在parent_repo中执行此操作是否正确?

不管怎样,我对你想做什么有一个很好的想法。

假设parent_repo/.gitmoduleschild_repo的设置将branch设置为master,如下面的示例所示:

[submodule "src/child_repo"]
path = src/child_repo
branch = master # or whatever branch your PR's for child_repo get merged into
# extra (unrelated) notes on other settings here:
url = ../child.git # if parent url is github.com/company/parent, use a relative url for your child_repo, this can avoid git auth/permission/repo access issues in some ci/cd environments
fetchRecurseSubmodules = true # hopefully this setting is pointless
# update = merge # you generally dont want to merge by default

合并child_repo的PR后,您的想法是正确的,但可以稍微优化。

假设您在parent_repo/src/child_repo中进行开发,那么:

git status # ensure you have no changes inside your `child_repo`, `git stash --all` if you do have changes.
git checkout master
git pull # now child_repo is on master with latest changes, assuming PR was merged into master
cd ../.. # now you're in `parent_repo` root
git status # clean things up if you need, stash, etc. Note, `git stash` or any other commands besides `git submodule ...` will NOT affect the state of your submodule. So, `git stash --all` should always work here 
git stash --all # Only if you have changes _besides_ your src/child_repo submodule pointer
git checkout master
git pull # optionally, `git pull origin master` if you like being specific
git status # should show something like `src/child_repo`

接下来,我们将运行git diff,但很可能会看到一个红色的提交哈希和一个绿色的提交哈希。在这种情况下,您可能想要运行git config --global diff.submodule log,这是我和我的同事首选的默认设置。更多信息请点击此处:https://www.jvt.me/posts/2018/05/04/git-submodule-diff-formats/

git diff # verify commits that have been merged in are correct, ensure you aren't deleting any commits
git diff --submodule=diff # verify actual code changes are also correct (optional)

假设您只看到添加了一些绿色提交消息,那么您就可以继续更新parent_repo以指向新版本的child_repo。如果你可以直接推到master(怀疑),你可以:

git add .
git commit -m "your_child_repo_name: Learned to handle `--force` setting"
git push

如果您没有推送权限,则必须为此进行另一次公关。更有可能的是,任何有权访问所有子模块的人都应该处理更新parent_repo以指向新的child_repo。对于您的主要开发人员/维护人员来说,这将非常容易,他们只需运行:

git submodule update
git add .
git commit -m "update child_repo, child_repo2, child_repo3"

这将在所有子模块中运行git pull。然后,他们可以通过运行git diff --submodule=log看到合并的新提交——当然,我假设这个首席开发人员有权直接推送到主

接下来我们将运行git diff,但很可能会看到红色提交哈希和绿色提交哈希
在这种情况下,您可能需要运行git config --global diff.submodule log

在这种情况下,使用Git 2.37(2022年第三季度),作为";CCD_ 17">(man)没有显示出在被比较的范围内变化的子模块的任何内容;CCD_ 18";工作不正常。

通过包括";CCD_ 19";无条件输出以进行比较。

请参阅Philippe Blain(phil-blain)提交的04b1f1f(2022年6月6日)
(由Junio C Hamano合并——gitster——提交ecbd60a,2022年6月13日)

range-diff:显示子模块的更改,而不考虑差异。submodule

签字人:Philippe Blain

在使用'git log'(man)调用为要比较的每个范围生成diff之后,range-diff.c::read_patches查找";CCD_ 25";在这些diff中的标头,以识别新变化的开始。

在一个包含子模块的项目中,配置中设置了"diff.submodule=log",更改后的子模块的diff缺少此标头,因此在diff范围内,任何子模块更改都会被忽略。

当在配置中设置了'diff.submodule=diff'时;CCD_ 28";子模块本身也缺少标头,但显示的是子模块内容更改,这很容易混淆'git range-diff'(man)并导致错误,如:

error: git apply: bad git-diff - inconsistent old filename on line 1
error: could not parse git header 'diff --git path/to/submodule/and/some/file/within
'
error: could not parse log for '@{u}..@{1}'

当调用"git log"为每个范围生成补丁时,强制子模块diff格式为其默认格式("short"),以便始终检测到子模块的更改。

添加一个测试,包括使用"--creation-factor=100"的调用,以强制该范围内的第二次提交不被视为完全重写,以便验证我们确实得到了";CCD_ 32";总体安排

最新更新