如何将我的更改还原为git子模块?

Eri*_*ric 241 git git-submodules

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

我不小心改变了那里的一些文件,我想回到源版本.为了做到这一点,我试着跑

Mac:app-ios user$ git submodule update RestKit
Run Code Online (Sandbox Code Playgroud)

但正如你在这里看到的,这不起作用,因为它仍然是"修改内容":

Mac:app-ios user$ git status
...
#   modified:   RestKit (modified content)
Run Code Online (Sandbox Code Playgroud)

甚至

Mac:app-ios user$ git submodule update -f RestKit 
Run Code Online (Sandbox Code Playgroud)

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

the*_*ven 257

如果要对所有子模块执行此操作,而不必更改目录,则可以执行

git submodule foreach git reset --hard

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

git submodule foreach --recursive git reset --hard

  • 对于自动化而言,这比尝试cd进入每个子模块目录要好得多. (7认同)
  • 对我不起作用。新提交仍以红色突出显示。`git Restore` 也不起作用 (7认同)
  • 请注意,您可能还想要`git submodule foreach --recursive git clean -x -f -d` (4认同)
  • 在我的机器上(使用 Git 2.22.0 的 Windows),使用 --recursive 标志时,我需要在第二个 git 命令周围加上单引号,否则它将无法工作: git submodule foreach --recursive 'git clean -x -f -d ' (2认同)

Jam*_*ney 185

进入子模块的目录,然后执行a git reset --hard将所有已修改的文件重置为上次提交的状态.请注意,这将丢弃所有未提交的更改.

  • 对我来说,只有`git submodule update --init`才有效. (234认同)
  • 除了@markshiz,`git submodule update -f --init`就我的情况而言. (28认同)
  • `git submodule update --init`为我工作; 没有`--init`它根本不起作用. (8认同)
  • 对我来说,只有“git submodule update --init --recursive”有效。 (6认同)
  • 当我没有真正改变任何东西时,git子模块更新(即使没有--init)也可以让我放弃子模块"更改".如果你转到子模块目录并且git status为空,请尝试此而不是重置. (5认同)
  • reset --hard 对我不起作用,由于本地更改,我的子模块仍然无法 deinit。 (2认同)

qwe*_*guy 166

比以前所有答案更安全的自动防范方法:

git submodule deinit -f .
git submodule update --init
Run Code Online (Sandbox Code Playgroud)

第一个命令完全"解除绑定"所有子模块,然后第二个命令对它们进行新的检查.
它需要比其他方法更长的时间,但无论子模块的状态如何都可以.

  • 只有对我有用的解决方案,谢谢! (7认同)
  • 我尝试了上面所有的方法,直到我找到了这个。对我来说,这是唯一让我的 git 看起来“干净”的(在我的“PS1”中没有“*”,而“git status -uno”无法解释)。 (3认同)
  • 我必须运行 `git submodule update --init --recursive` 。 (3认同)
  • 要更新特定的子模块,请执行: $ git submodule deinit -f -- <submodule_path> 然后 $ git submodule update --init -- <submodule_path> (2认同)

che*_*sum 55

好吧,对我来说,有

git reset --hard
Run Code Online (Sandbox Code Playgroud)

只需将子模块重置为其签出的状态,而不是主要的repo引用的提交/状态.我还是会像OP说的那样"修改内容".因此,为了使子模块返回到更正提交,我运行:

git submodule update --init
Run Code Online (Sandbox Code Playgroud)

然后,当我这样做时git status,它在子模块上是干净的.


小智 44

按顺序执行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
Run Code Online (Sandbox Code Playgroud)

  • 这个答案比我接受的答案更能帮助我(很多). (4认同)
  • @DavidDoria `git submodule update` 是为我修复了 `(新提交)` 的。 (3认同)
  • 唯一帮助我的人. (2认同)
  • @jiahut 即使在这样做之后,当我从父模块执行“git status”时,我的子模块旁边仍然有“(新提交”)? (2认同)

Ser*_*scu 26

这对我有用,包括递归到子模块(也许这就是为什么你的-f不起作用,导致你改变了子模块中的子模块):

git submodule update -f --recursive
Run Code Online (Sandbox Code Playgroud)


Jea*_*era 18

首先尝试这个,正如其他人所说:

git submodule update --init
Run Code Online (Sandbox Code Playgroud)

如果这不起作用,请切换到子模块目录并使用以下命令查看子模块是否有任何更改:

git status
Run Code Online (Sandbox Code Playgroud)

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

接下来,返回主存储库并再次运行“git submodule update --init”。


A. *_* K. 12

很简单:

cd /path/to/submodule/root
git submodule update -f --init  .
Run Code Online (Sandbox Code Playgroud)

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


Von*_*onC 6

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

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

请参阅提交35b96d1(2017年4月21日),并提交f2d4899,提交823bab0,提交cd279e2(2017年4月18日)作者:Stefan Beller(stefanbeller).
(由Junio C gitsterHamano合并- -5f074ca的承诺中,2017年5月29日)

builtin/reset:添加--recurse-submodules开关

git-reset 是另一个工作树操纵器,应该教授子模块.

当用户使用git-reset并将请求递归到子模块时,这会将子模块重置为超级项目中记录的对象名称,从而分离HEAD.

警告:区别:

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

是前者还将重置您的主要父回购工作树,因为后者只会重置子模块工作树.
所以要谨慎使用.


cmc*_*nty 6

对于git <= 2.13,这两个命令组合在一起应该使用递归子模块重置你的repos:

git submodule foreach --recursive git reset --hard
git submodule update --recursive --init
Run Code Online (Sandbox Code Playgroud)


小智 6

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

git restore . --recurse-submodules

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