在提交中恢复对子模块的更改

revert a change to submodule in a commit

我在提交主存储库中的文件时不小心更改了 2 个子模块 的状态。它可能发生在变基,但我不确定我不明白子模块

有没有一种方法可以编辑提交并撤消对 子模块 的更改,而不撤消对文件的良好更改?我熟悉使用 git rebase -igit commit --amend 对常规项目执行此操作,但我不知道如何为 submodules.[=18= 执行此操作]

这是混乱的提交:https://github.com/PiRK/ElectrumABC/commit/f1bf0893c1becc01b8191c4a8c37eafd26c2a29d 我需要 contrib/tor 再次指向 it's remote repository, and contrib/ssl to point back to fd78df59b0 in https://github.com/openssl/openssl/

中的 7ce4ae344 commot

我很高兴添加一个仅修复 两个子模块 的提交,或者通过编辑我的错误提交来更改历史记录(这最好,因为它避免了不一致的情况陈述几次提交)。

要添加修复两个子模块的新提交:

  1. 检查超级项目,它位于以“错误”提交结尾的分支的顶端。 运行 git submodule update --init 如果需要克隆两个子模块。

  2. 输入每个子模块并检查 正确的 提交,通过您列出的两个原始哈希 ID:

    (cd contrib/tor && git checkout 7ce4ae344)
    (cd contrib/ssl && git checkout fd78df59b0)
    

    (如果您愿意,可以使用 git switch --detach 而不是 git checkout;效果没有区别。)

  3. git status 现在将在“changes not staged for commit”部分显示两个子模块。将它们添加到 Git 的索引中:

    git add contrib/tor contrib/ssl
    

    现在 git status 将在“为提交准备的更改”部分显示它们。

  4. 进行新的提交。

可能的,使用git rebase等,用新的和改进的替换一些旧的提交;在第 4 步中使用 git commit --amend 而不是 git commit 将仅替换一个 tip 提交;但总的来说,用新的和改进的替换旧的错误提交会让其他已经接受错误提交的人头疼,而且它增加的价值很小。如果您非常确定没有其他人发现错误的提交,请随意做额外的工作以使其看起来没有错误,但没有人会真正关心。

怎么回事

Git 存储库中的每个 提交表示该存储库中所有文件 的确切状态。也就是说,每次提交都包含每个文件的完整快照。子模块“文件”只是存储在某个路径名中的提交哈希 ID。这是对超级项目 Git 的指令: 当此提交被检出时,这些子模块路径和哈希 ID 在 Git 的索引中, git submodule update 应在指定的提交上输入每个命名的子模块和 运行 git checkout

因此,每个具有子模块的提交实际上只有一个路径(例如 contrib/tor)和一个原始哈希 ID。该哈希 ID 最好是存在于克隆中的某个提交的哈希 ID,该克隆是通过克隆存储在 .gitmodules.git/config 中的任何 path 为该子模块创建的, 如果子模块还没有被克隆;或者,最好是该克隆中存在的某个提交的哈希 ID,或者如果超级项目 Git 进入子模块 Git 存储库并且 运行s git fetch.

这就是所有的子模块:一个指令。输入一些 other Git 存储库和 运行 git checkout。要更新指令,您只需输入存储库 yourself、运行 给定的 git checkout、return 返回超级项目,然后 运行 git add。这会更新 Git 的 索引 ,这是您将进行的 下一次提交 的来源。因此 next 提交现在将包含另一个哈希 ID。

请注意,子模块不使用分支名称。它们总是由原始哈希 ID 完成。您 可以 为它们设置分支名称,但这些(至​​少目前)仅用于特殊的 git submodule update 选项(特别是 git submodule update --remote)。因为 most Git 命令使用原始哈希 ID,我建议坚持使用原始哈希 ID 方法,至少在您熟悉它并遇到特殊情况 git submodule update --remote 变得有用:请记住,即使 --remote 仍然可以通过哈希 ID 工作,它只是 从某个棘手的地方获取 哈希 ID .