【问题标题】:How do I revert my changes to a git submodule?如何恢复对 git 子模块的更改?
【发布时间】:2012-06-05 23:52:44
【问题描述】:

我有一个 git 子模块 (RestKit),已添加到我的仓库中。

我不小心更改了其中的一些文件,我想回到源版本。为了做到这一点,我尝试运行

Mac:app-ios user$ git submodule update RestKit

但正如您在此处看到的,这不起作用,因为它仍然是“修改后的内容”:

Mac:app-ios user$ git status
...
#   modified:   RestKit (modified content)

均匀

Mac:app-ios user$ git submodule update -f RestKit 

不会还原本地修改的文件。
如何重置该子模块的内容?

【问题讨论】:

  • 如果git reset --hard不起作用,请先尝试使用git reset --hard origin/<branch_name>指定远程分支。

标签: git git-submodules


【解决方案1】:

如果您想对所有子模块执行此操作,而无需更改目录,则可以执行

git submodule foreach git reset --hard

您也可以使用递归标志应用于所有子模块:

git submodule foreach --recursive git reset --hard

【讨论】:

  • 这对于自动化来说比尝试 cd 进入每个子模块目录要好得多。
  • 请注意,您可能还想git submodule foreach --recursive git clean -x -f -d
  • 在我的机器上(使用 Git 2.22.0 的 Windows)在使用 --recursive 标志时,我需要在第二个 git 命令周围加上单引号,否则它将不起作用: git submodule foreach --recursive 'git清洁 -x -f -d '
  • 你应该用 sudo 调用它,以防有写保护的文件。
  • 对我不起作用。新提交仍以红色突出显示。 git restore 也不起作用
【解决方案2】:

比以前所有答案都更安全的方法:

git submodule deinit -f .
git submodule update --init

第一个命令完全“解除绑定”所有子模块,第二个命令重新检出它们。
它比其他方法花费更长的时间,但无论您的子模块的状态如何,它都可以工作。

【讨论】:

  • 遗憾的是,这在我的情况下不起作用(在 git 子模块中修改了本地文件),“update --init”命令会喷出error: Your local changes to the following files would be overwritten by checkout
  • 要更新特定的子模块: $ git submodule deinit -f -- 然后 $ git submodule update --init --
  • 我尝试了上述所有方法,直到我得到这个。对我来说,这是唯一一个让我的 git 看起来“干净”的(没有 PS1 中的 * git status -uno 无法解释)。
  • 谢谢你,这工作:)
【解决方案3】:

移动到子模块的目录,然后执行git reset --hard 将所有修改过的文件重置为上次提交的状态。请注意,这将丢弃所有未提交的更改。

【讨论】:

  • git 子模块更新(即使没有--init)在我实际上没有更改任何内容时让我放弃了子模块“更改”。如果您转到子模块目录并且 git status 为空,请尝试此操作而不是重置。
  • git submodule update --init 为我工作;没有--init,它根本不起作用。
  • reset --hard 对我不起作用,由于本地更改,我的子模块仍然无法 deinit。
  • 除了@markshiz,我的情况是git submodule update -f --init
  • 只有git submodule update --init --recursive对我有用。
【解决方案4】:

对我来说很好,有

git reset --hard

只需将子模块重置为它签出的状态,而不需要主的 repo 引用的提交/状态。我仍然会像 OP 所说的那样拥有“修改过的内容”。所以,为了让子模块回到正确的提交,我运行:

git submodule update --init

然后当我执行git status 时,它在子模块上是干净的。

【讨论】:

  • 遗憾的是,submodule update --init 在我的情况下似乎并没有恢复本地修改:|
  • 这对我来说是正确的答案,因为我刚刚在我的子模块中做了一个git pull。使用更新我能够回到我的主模块引用的提交
【解决方案5】:

依次执行 4 个步骤:

git submodule foreach git reset --hard HEAD
git submodule update
git submodule foreach "git checkout master; git pull"
git submodule foreach git clean -f

【讨论】:

  • 问题,如果子模块是新的,那么该目录中不会有 .git 文件,对吗? git 命令会冒泡到父仓库吗?
  • @jiahut 即使在这样做之后,当从父级执行“git status”时,我的子模块旁边仍然有“(新提交”)?
  • @DavidDoria git submodule update 为我修复了 (new commits)
【解决方案6】:

这对我有用,包括递归进入子模块(也许这就是你的 -f 不起作用的原因,因为你在子模块中更改了一个子模块):

git submodule update -f --recursive

【讨论】:

    【解决方案7】:

    先试试这个,就像其他人说的那样:

    git submodule update --init
    

    如果不行,切换到子模块目录,使用如下命令查看子模块是否有变化:

    git status
    

    如果您的子模块有更改,请将其删除。验证运行“git status”时看不到任何更改。

    接下来,回到主仓库,再次运行“git submodule update --init”。

    【讨论】:

      【解决方案8】:

      如果您想丢弃整个存储库中的所有更改以及子模块,您可以使用:

      git restore . --recurse-submodules
      

      这将撤消在存储库和子模块中所做的所有更改。

      【讨论】:

        【解决方案9】:

        自 Git 2.14(2017 年第三季度)以来,您不必进入每个子模块来执行 git reset(如 git submodule foreach git reset --hard

        那是因为 git reset 本身现在知道如何递归地进入子模块。

        请参阅commit 35b96d1(2017 年 4 月 21 日)和commit f2d4899commit 823bab0commit cd279e2(2017 年 4 月 18 日)Stefan Beller (stefanbeller)
        (由 @987654327 中的 Junio C Hamano -- gitster -- 合并@,2017 年 5 月 29 日)

        内置/重置:添加 --recurse-submodules 开关

        git-reset 是另一个工作树操纵器,应该教它有关子模块的知识。

        当用户使用 git-reset 并请求递归到子模块时, 这会将子模块重置为记录在 超级项目,分离 HEAD。

        警告:区别:

        • git reset --hard --recurse-submodule
        • git submodule foreach git reset --hard

        是前者还会重置您的主父 repo 工作树,因为后者只会重置子模块工作树。
        所以请谨慎使用。

        【讨论】:

          【解决方案10】:

          对于 git

          git submodule foreach --recursive git reset --hard
          git submodule update --recursive --init
          

          【讨论】:

            【解决方案11】:

            很简单:

            cd /path/to/submodule/root
            git submodule update -f --init  .
            

            大多数答案都建议重置所有子模块,我认为这不是最好的方法,因为它们可能会有合法的变化。

            【讨论】:

              【解决方案12】:

              这适用于我们运行 GIT v1.7.1 的库,其中我们有一个 DEV 包 repo 和 LIVE 包 repo。存储库本身只不过是为项目打包资产的外壳。所有子模块。

              LIVE 永远不会有意更新,但是可能会发生缓存文件或意外,从而使存储库变脏。添加到 DEV 的新子模块也必须在 LIVE 中初始化。

              DEV 中的包存储库

              在这里,我们想要提取我们尚未意识到的所有上游更改,然后我们将更新我们的包存储库。

              # Recursively reset to the last HEAD
              git submodule foreach --recursive git reset --hard
              
              # Recursively cleanup all files and directories
              git submodule foreach --recursive git clean -fd
              
              # Recursively pull the upstream master
              git submodule foreach --recursive git pull origin master
              
              # Add / Commit / Push all updates to the package repo
              git add .
              git commit -m "Updates submodules"
              git push   
              

              LIVE 中的包存储库

              这里我们想要拉取提交到 DEV 存储库的更改,而不是未知的上游更改。

              # Pull changes
              git pull
              
              # Pull status (this is required for the submodule update to work)
              git status
              
              # Initialize / Update 
              git submodule update --init --recursive
              

              【讨论】:

                【解决方案13】:

                如果你的子模块有变化,那么使用

                git submodule foreach --recursive git reset --hard
                

                如果您的更改是远程子模块更改,则使用

                git submodule update --init
                

                如果这些更改已提交,则使用

                git reset --hard
                git submodule update --init
                

                【讨论】:

                  【解决方案14】:

                  我重置所有子模块的方法(分离并保留它们的master 分支):

                  git submodule foreach 'git checkout master && git reset --hard $sha1'
                  

                  【讨论】:

                  • 什么是 $sha1 ?
                  猜你喜欢
                  • 2019-07-11
                  • 2012-06-30
                  • 1970-01-01
                  • 1970-01-01
                  • 2013-09-07
                  • 1970-01-01
                  • 2014-02-17
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多