2011-10-24 18 views
78

私はメインのgitリポジトリにgitサブモジュールを持っています。私が理解しているように、メインリポジトリにはSHAの値(どこか...)が格納されており、サブモジュールの特定のコミットを指し示しています。Git Submoduleポインタを含むリポジトリに格納されているコミットに戻すには?

私はサブモジュールに入り、git checkout some_other_branchと入力しました。私はどちらが来たのか分かりません。

メインのレポとサブモジュールが再び同期するように、そのポインタを元に戻したいと思います。

私の最初の(おそらく素朴な)本能は、git reset --hardと言われました - それは他のすべてのために働くようです。私の驚いたことに、このシナリオではうまくいかなかった。

git diffと入力すると、サブモジュールポインタが持っていたSHA IDをメモしてから、サブモジュールとgit checkout [SHA ID]に向かうことに気がつきましたが、もっと簡単な方法が必要ですか?

私はまだgitサブモジュールについて学んでいるので、わからない概念の言葉があれば、私の用語を修正してください。

答えて

112

あなたはそれが親リポジトリはそれがあるべきと考えているものと同期しているので、あなたのサブモジュールを更新する:コマンドレベルでは、あなたが)ダウンサブモジュールにcdを有するスキップすることができます。これとすべてがうまくあるべき

 
Update the registered submodules, i.e. clone missing submodules and 
checkout the commit specified in the index of the containing 
repository. This will make the submodules HEAD be detached unless 
--rebase or --merge is specified or the key submodule.$name.update 
is set to rebase or merge. 

実行:サブモジュールのmanページから

:「親プロジェクト」フォルダ内の

git submodule update 
+2

どういうわけか:サブモジュールで

git reset --hard git submodule update 

:親で

:私は完全に私の親とサブモジュールの両方でunstaged変更を破棄したいのであれば、私は次の操作を行います'--init'を追加します。それがなければ、サブモジュールは '(新しいコミット)'の状態に留まります。私のサブモジュールは既に初期化されていました。 – Ambidex

+0

@Ambidexはいすべての場合、 '--init'オプションは非常に重要です。サブモジュールがhttpsでクローンされていたので、私はユーザー名とパスワードの入力を求められました。私は両方のフォルダに行き、チェックアウトのために 'ssh'プロトコルを使うようにリモートを設定しました。 –

14

サブモジュールが指しているコミットを変更するには、サブモジュール内のそのバージョンをチェックアウトしてから、そのリポジトリに戻り、その変更を追加してコミットする必要があります。

サブポールを上位のリポジトリが指すバージョンにしたい場合は、git submodule update --recursiveを実行します。クローン作成したばかりの場合は--initを追加してください。

また、submoduleコマンドを使用しないでgit submoduleを実行すると、指示しているコミットが表示されます。同期していなければ、コミットの前に - または+が付きます。

サブモジュールがあるツリーを見ると、そのサブモジュールがブロブまたはツリーではなく、commitとマークされていることがわかります。特定のは、あなたができるサブモジュールにポイントWRTをコミットするかを確認するには

git ls-tree <some sha1, or branch, etc> Submodule/path 

あなたはなど、ログにそれを渡すことによって、あなたのような場合にはコミットまたは何か他のものを参照することができます(gitのでgit-dirオプション

git --git-dir=Submodule/path log -1 $(<the above statement>) 
4

使用git ls-tree HEADが見てこれがために、更新コマンドがあるものですあなたのサブモジュールを最初にコミットしたもの。サブモジュールディレクトリに移動し、git log --oneline --decorateを使用して、元のコミットがどのブランチであるかを確認します。最後に、git checkout original-commit-branch。私はセットアップいくつかのテストのディレクトリを使用して

は、ここではコマンドがどのように見えるかです:

$ git --version 
git version 1.7.4.1 
$ git status 
# On branch master 
# Changes not staged for commit: 
# (use "git add <file>..." to update what will be committed) 
# (use "git checkout -- <file>..." to discard changes in working directory) 
# 
# modified: sm2 (new commits) 
# 
no changes added to commit (use "git add" and/or "git commit -a") 
$ git ls-tree HEAD 
100644 blob 76813a07ae558db274cefc6d903ec24323fdeb0d .gitmodules 
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 main 
160000 commit 7c5889497938cd5699a9234a98ee93947e52b1ed sm1 
160000 commit f68bed61cba6f94cef57554f2cf46a45a4a0d337 sm2 
$ cd sm2 
$ git log --oneline --decorate 
5b8d48f (HEAD, foo1) foo1.1 
f68bed6 (origin/master, origin/HEAD, master) Initial commit. 
$ git checkout master 
Switched to branch 'master' 
$ cd .. 
$ git status 
# On branch master 
nothing to commit (working directory clean) 

「親プロジェクトは、」コミットf68bed6でSM2サブモジュールを示したが、SM2は、それが5b8d48fでHEADのしています。サブモジュールコミットf68bed6には、サブモジュールディレクトリのチェックアウトに使用できる3つの分岐があります。

+0

感謝ダン、パーフェクト! – Alec

2

もう1つのケースは、破棄したいサブモジュールに不安定な変更がある場合です。 gitサブモジュールの更新でその変更が削除されることはなく、親ディレクトリの-hardもリセットされません。サブモジュールディレクトリに移動し、git reset -hardを実行する必要があります。私は必要な私のために、

git reset --hard 
関連する問題