変更をgitサブモジュールに戻すにはどうすればよいですか?


270

リポジトリに追加した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>
ジェリーK.

回答:


208

サブモジュールのディレクトリに移動し、次にを実行して、git reset --hard変更されたすべてのファイルを最後にコミットされた状態にリセットします。これにより、コミットされていないすべての変更が破棄されることに注意してください。


6
gitサブモジュールの更新(--initがなくても)は、実際には何も変更していなかったときにサブモジュールの「変更」を放棄するのに役立ちました。サブモジュールディレクトリに移動してgitステータスが空になった場合は、リセットの代わりにこれを試してください。
折衷的なDNA

16
git submodule update --init私のために働いた。--initそれなしでは全く機能しませんでした。
Lundberg作

見事!!インポートした私のリポジトリのサブモジュールに変更を加えました。そして、これはそれを本来あるべき状態に戻しました。
Noitidart 2016年

2
reset --hardは私にとっては機能しませんでした。ローカルの変更のため、サブモジュールを終了できませんでした。
マルハル2016

33
@markshizに加えて、git submodule update -f --init私の場合。
otiai10 2017

280

ディレクトリを変更せずにすべてのサブモジュールに対してこれを実行したい場合は、次を実行できます

git submodule foreach git reset --hard

再帰フラグを使用して、すべてのサブモジュールに適用することもできます。

git submodule foreach --recursive git reset --hard


7
これは、各サブモジュールディレクトリにcdするよりも、自動化の方がはるかに優れています。
Travis Castillo

4
次のこともお勧めしますgit submodule foreach --recursive git clean -x -f -d
ヨーヨー

1
私のマシン(Git 2.22.0を使用するWindows)--recursiveフラグを使用する場合、2番目のgitコマンドを単一引用符で囲む必要があります。そうしないと機能しません。git submodule foreach --recursive 'git clean -x -f -d'
aatwo

196

以前のすべての回答よりもフェイルセーフな方法:

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

最初のコマンドはすべてのサブモジュールを完全に「バインド解除」し、2番目のコマンドはそれらの新しいチェックアウトを行います。
他の方法よりも時間がかかりますが、サブモジュールの状態に関係なく機能します。


1
残念ながら、私の場合(gitサブモジュールのローカルファイルが変更されている場合)は機能しませんでした。 "update --init"コマンドが出力されますerror: Your local changes to the following files would be overwritten by checkout
rogerdpack

特定のサブモジュールを更新するには、次のようにします。$ git submodule deinit -f-<submodule_path>そして$ git submodule update --init-<submodule_path>
Priyank

この方法にたどり着くまで、上記の方法をすべて試しました。私にとって、これは私のgitを「クリーン」に見せた唯一のものです(*私の中PS1git status -uno説明できないものなしで)。
ガイラパポート

60

私にとっては、

git reset --hard

サブモジュールをチェックアウトした状態にリセットするだけで、メインのリポジトリがコミット/状態を参照する必要はありません。OPが言ったように、私はまだ「変更されたコンテンツ」を持っています。したがって、サブモジュールを正しいコミットに戻すために、次のコマンドを実行します。

git submodule update --init

それから私がするときgit status、それはサブモジュールできれいです。


残念submodule update --initながら、私の場合、ローカルの変更を元に戻すことはできません:|
rogerdpack 2016

48

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

2
私も助けてくれた唯一の人。
Victor Sergienko、2014年

質問、サブモジュールが新しい場合、そのディレクトリ内に.gitファイルはありませんよね?gitコマンドは親リポジトリにバブルしますか?
サンティアゴアリスティ2016年

1
@jiahutこれを行った後でも、親から「git status」を実行すると、サブモジュールの横に「(新しいコミット)」がまだありますか?
David Doria 2017年

1
@DavidDoria git submodule updateは修正されたものでした(new commits)私をてくれました。
ubershmekel 2018

31

これは、サブモジュールに再帰的に含めることを含め、私にとっては機能しました(おそらく、-fが機能しなかったため、サブモジュール内のサブモジュールが変更されました)。

git submodule update -f --recursive

12

他の人が言っているように、まずこれを試してください:

git submodule update --init

それが機能しない場合は、サブモジュールディレクトリに移動し、次のコマンドを使用してサブモジュールに変更があるかどうかを確認します。

git status

サブモジュールに変更がある場合は、それらを取り除きます。「git status」を実行しても変更が表示されないことを確認します。

次に、メインリポジトリに戻り、「git submodule update --init」を再度実行します。


9

Git 2.14(2017年第3四半期)以降、各サブモジュールに移動する必要はありませんgit resetgit submodule foreach git reset --hard

これは、git reset自体がサブモジュールに再帰的に入る方法を知っているためです。

参照してください35b96d1コミット(2017年4月21日)を、そしてf2d4899をコミットし823bab0をコミットしcd279e2コミットにより(2017年4月18日)のステファンBeller( )stefanbeller
(による合併Junio C浜野- gitster-5f074caをコミットし、2017年5月29日)

builtin / reset:--recurse-submodulesスイッチを追加

git-reset さらに別の作業ツリーマニピュレータです。サブモジュールについて学習する必要があります。

ユーザーがgit-resetを使用してサブモジュールに再帰するように要求すると、サブモジュールがスーパープロジェクトに記録されているオブジェクト名にリセットされ、HEADが切り離されます。

警告:次の違い:

  • git reset --hard --recurse-submodule そして
  • git submodule foreach git reset --hard

前者はメインの親リポジトリの作業ツリーもリセットします。後者はサブモジュールの作業ツリーのみをリセットするためです。
したがって、注意して使用してください。


7

git <= 2.13の場合、これらの2つのコマンドを組み合わせると、再帰サブモジュールでリポジトリがリセットされます。

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

3

これは、GIT v1.7.1を実行しているライブラリで機能し、DEVパッケージリポジトリとLIVEパッケージリポジトリがあります。リポジトリ自体は、プロジェクトのアセットをパッケージ化するためのシェルにすぎません。すべてのサブモジュール。

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

2

サブモジュールと一緒にリポジトリ全体のすべての変更を破棄したい場合は、

git restore . --recurse-submodules

これにより、リポジトリとサブモジュールで行われたすべての変更が取り消されます。


0

すべてのサブモジュールをリセットする私の方法(「マスター」ブランチを切り離して保持することなく):

gitサブモジュールforeach 'git checkout master && git reset --hard $ sha1'

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.