我该如何恢复对git子模块的更改?

我有一个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 submodule foreach git reset --hard

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

git submodule foreach --recursive git reset --hard

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

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

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

对我来说,有

 git reset --hard 

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

 git submodule update --init 

然后当我做git status ,它是干净的子模块。

顺序执行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 v1.7.1,我们有一个DEV包回购和LIVE包回购。 仓库本身不过是一个包装项目资产的shell。 所有的子模块。

LIVE永远不会有意更新,但caching文件或事故可能发生,使回购肮脏。 添加到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 

由于Git 2.14(2017年第3季度),你不必进入每个子模块做一个git reset (如git submodule foreach git reset --hard

这是因为git重置自己现在知道如何recursion地进入子模块。

请参阅提交35b96d1 (2017年4月21日),并提交 Stefan Beller( stefanbeller )的 f2d4899 , 提交823bab0 , 提交cd279e2 (2017年4月18日) 。
(由Junio C gitster合并- gitster -参与2017年5月29日5f074ca )

内build/复位:加–recurse-submodules开关

git-reset是另一个有效的树操作器,应该教给子模块。

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

警告 :区别:

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

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

这工作对我来说,包括recursion进入子模块(也许这就是为什么你的-f不工作,导致你改变子模块内的子模块):

 git submodule update -f --recursive 

对于git <= 2.13这两个命令组合应该用recursion子模块重置您的回购:

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

我的方式来重置所有子模块(不分离和保持其“主”分支):

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