我该如何恢复对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'