サブモジュールを削除するにはどうすればよいですか?


3539

Gitサブモジュールを削除するにはどうすればよいですか?

ちなみに、単純にできないのは git submodule rm whateverなぜですか?


109
単純な回答stackoverflow.com/a/21211232/94687が正しいものになり、そのようにマークする必要があります。さて、それは単純 git rm modulenamerm -rf .git/modules/modulename
imz-Ivan Zakharyaschev

10
それは実際には真実ではありません。その回答では、サブモジュールエントリをから削除することについては触れていません.git/config。受け入れられた答えは、サブモジュールを完全に削除するための最新の方法を示しています。また、この回答では、より簡潔に説明されています:stackoverflow.com/a/36593218/1562138
fvgs

この記事は、サブモジュールの削除に非常に役立ちました。.gitsubmodulesおよび.git / configファイルリンクの
Ri_

12
少し時間を節約して、(2017年に)機能する答えに直接進んでください:stackoverflow.com/a/36593218/528313
Vincenzo Pii

サブモジュールの問題に2日間取り組んできました。私がこれを見つけたときに画期的な出来事がありました:forums.developer.apple.com/thread/13102。基本的に、Xcodeおよびおそらく他のアプリは、「〜」を含むURLを展開するのに苦労しています。ssh://username@server.remoteHost.com/~/git/MyRepo.gitをssh://username@server.remoteHost.com/home/username/git/MyRepo.gitに変更したら(実際のパスを調べます)あなたのサーバー上で)、すべての奇妙さは10分で消えました。stackoverflow.com/questions/32833100/…
エリーゼファンルーイ

回答:


2213

git1.8.3(2013年4月22日)以降:

submodule init」でサブモジュールに興味を示したら、「このサブモジュールにはもう興味がない」という磁器の方法はありませんでした。
submodule deinit」はそうする方法です。

削除プロセスでも使用しますgit rm(2013年10月git1.8.5以降)。

概要

3ステップの削除プロセスは次のようになります。

0. mv a/submodule a/submodule_tmp

1. git submodule deinit -f -- a/submodule    
2. rm -rf .git/modules/a/submodule
3. git rm -f a/submodule
# Note: a/submodule (no trailing slash)

# or, if you want to leave it in your working tree and have done step 0
3.   git rm --cached a/submodule
3bis mv a/submodule_tmp a/submodule

説明

rm -rf:これはDaniel Schroeder回答で言及されており、Eonil のコメントで要約されています

これは.git/modules/<path-to-submodule>/変更されません。
そのため、この方法でサブモジュールを一度削除してから再度追加すると、リポジトリがすでに破損しているため不可能です。


git rmコミット95c16418を参照

現在git rmサブモジュールで「」を使用すると、サブプロジェクトのワークツリーがスーパープロジェクトのワークツリーから削除され、gitlinkがインデックスから削除されます。
ただし、のサブモジュールのセクション.gitmodulesは変更されていません。これは、現在削除されているサブモジュールの残りであり、ユーザーを苛立たせる可能性があります(.git/config、これは、ユーザーがこのサブモジュールに興味を示したことを思い出させるために残しておく必要があります。古いコミットがチェックアウトされたとき)。

「してみましょうgit rm」ヘルプのみ作業ツリーからサブモジュールを削除しないことによっても除去することにより、利用者「submodule.<submodule name>から」セクション.gitmodulesファイルとステージの両方を。


git submodule deinitこのパッチに由来します

git submodule init」を使用すると、ユーザーはgitに1つまたは複数のサブモジュールを気にするように指示でき、「git submodule update」への次の呼び出しでそれを入力したいとします。
しかし、現在、サブモジュールを気にせず、ローカルの作業ツリーを削除することを望んでいるgitに簡単に伝える方法はありません(ユーザーがサブモジュールの内部についてよく知っていて、「submodule.$name.url.git/configており、作業と共に "設定ツリー自身)。

' deinit'コマンドを提供して、それらのユーザーを支援します。
これにより、指定されたサブモジュールsubmodule.<name>.git/config(または ' .'が指定された場合に初期化されたすべてのサブモジュール)からセクション全体が削除されます。
強制されない限り、現在の作業ツリーに変更が含まれていると失敗します。
コマンドラインで指定されたサブモジュールの場合、URL設定がで見つからない場合でも文句を言いますが.git/config、それでも失敗しません。

これは、(非)初期化手順(.git/configおよび.git/modules/xxx

git1.8.5以降、git rmは次のもの処理します。

  • addサブモジュールのURLを.gitmodulesファイルに記録する' 'ステップ:削除する必要があります。
  • サブモジュールの特別なエントリこの質問で示されています):git rmがインデックスから削除します:(
    git rm --cached path_to_submodule末尾のスラッシュはありません)
    特別なモード「160000」でインデックスに保存されているディレクトリを削除し、サブモジュールのルートディレクトリとしてマークします。

最後のステップを忘れて、サブモジュールを通常のディレクトリとして追加しようとすると、次のようなエラーメッセージが表示されます。

git add mysubmodule/file.txt 
Path 'mysubmodule/file.txt' is in submodule 'mysubmodule'

注:Git 2.17(2018年第2四半期)以降、gitサブモジュールdeinitはシェルスクリプトではなくなりました。
これは、C関数の呼び出しです。

コミット2e61273コミット1342476(2018年1月14日)のPrathamesh Chavan(pratham-pc)を参照してください。
(合併によりJunio C浜野- gitster-ead8dbeをコミットする、2018年2月13日)

git ${wt_prefix:+-C "$wt_prefix"} submodule--helper deinit \
  ${GIT_QUIET:+--quiet} \
  ${prefix:+--prefix "$prefix"} \
  ${force:+--force} \
  ${deinit_all:+--all} "$@"

18
の使用例を教えていただけますsubmodule deinitか?
ザクダンス2013

5
@yourfriendzakは、誰かがそれをうまく使用した例の1つです:stackoverflow.com/a/16161950/6309。しかし、私が当初信じていたのとは逆に、1.8.3はまだリリースされていないことに注意してください。Unixでは、ソースからコンパイルできます。
VonC 2013

2
@HamishDowner特別なエントリがなくなっているはずです(ディレクトリはサブモジュールではなくなります)。そして、.gitmodules大丈夫ですが、.gitディレクトリ(つまり、ローカルリポジトリ内のローカル構成)で何かを再確認します。git pull)により変更
VonC 2013年

2
@Jayenはい、.gitmodulesエントリの削除とインデックス内の特別なエントリの削除をコミットし、そのリポジトリをプッシュすると、他の人がそれをプルでき、そのサブモジュールはなくなります。
VonC 2013

3
現在のgit(v1.9以降)では、git rm submodule他の人がすでに言っているように、plain old はまさにあなたが望むことをします。
ピートピーターソン

3445

Gitサブモジュールチュートリアルページから:

サブモジュールを削除するには、次のことを行う必要があります。

  1. .gitmodulesファイルから関連するセクションを削除します。
  2. .gitmodules変更をステージングします。
    git add .gitmodules
  3. から関連するセクションを削除します.git/config
  4. 作業ツリーとインデックスからサブモジュールファイルを削除します。
    git rm --cached path_to_submodule末尾のスラッシュなし)。
  5. サブモジュールの.gitディレクトリを削除します。
    rm -rf .git/modules/path_to_submodule
  6. 変更をコミットします。
    git commit -m "Removed submodule <name>"
  7. 追跡されなくなったサブモジュールファイルを削除します。
    rm -rf path_to_submodule

参照してください以下の代替手順を


410
「ところで、私がgit submodule rmを何でも簡単に実行できない理由はありますか?」?
アベルニエ、2011年

48
@abernier悪質な答えは「そのようなコマンドが存在しないため」である可能性があります。私の推測では、偶発的なデータ損失を回避するために、サブモジュールファイルとサブモジュール構成を明示的に削除しようとしているのではないでしょうか。たぶん、1人git submodule rmはサブモジュールの登録を削除するだけだと考え、コマンドがローカルリポジトリも削除した場合は驚くでしょう。ローカルでの変更はすべて、回復不能に失われます。そして、おそらく別の人は、ファイルだけが削除されると思います。
John Douthat、2011年

119
正直なところ、理由はわかりません。ただし、コマンドを追加してほしい。これらの4つのステップは複雑すぎます。
John Douthat、2011年

25
これは、サブモジュールを削除するbashスクリプトです。submodule
Capi Etheriel

33
rm -rf .git \ modules \ submodule nameも必要ですか?
rogerdpack、2012年

484

ただのメモ。git 1.8.5.2以降、2つのコマンドで実行できます。

git rm the_submodule
rm -rf .git/modules/the_submodule

@Mark Chevertonの答えが正しく指摘しているように、2行目が使用されていない場合、現時点でサブモジュールを削除しても、残りの.git / modules / the_submoduleフォルダーは、同じサブモジュールが再び追加されたり、置き換えられたりするのを防ぎます。また、@ VonCが述べたように、git rmほとんどの作業はサブモジュールで行います。

-更新(2017年7月5日)-

明確にするためにthe_submodule、プロジェクト内のサブモジュールの相対パスです。たとえばsubdir/my_submodule、サブモジュールがサブディレクトリ内にある場合ですsubdirです。

コメントやその他の回答で正しく指摘されているように、2つのコマンド(サブモジュールを削除するには機能的に十分です)は、(2017年7月現在)の[submodule "the_submodule"]セクションにトレースを残し.git/configます。これは、3番目のコマンドを使用して削除できます。

git config -f .git/config --remove-section submodule.the_submodule 2> /dev/null

5
私はgitバージョン2.4.9(Apple Git-60)を使っていて、rm the_submoduleを実行するだけで済みました。私はそれをプッシュし、サブモジュールと同じ名前のフォルダーを再度追加しましたが、問題なく動作しました。
David Silva Smith

19
これはサブモジュールエントリをから削除しません.git/config。サブモジュールを削除する完全な方法については、stackoverflow.com / a / 36593218/1562138を参照してください。
fvgs

2
@drevickoこれをGit 2.11.1でテストしたところ、以前と同じ動作が見られます。エントリとディレクトリとその内容をgit init && git submodule add <repository> && git rm <name>残します。削除する前にサブモジュールを初期化しなかったのでしょうか?.git/config.git/modules/<name>
fvgs 2017

2
私はこれを最初に実行する方が安全だと感じています.. git submodule deinit -f the_submodule
danday74

1
@JarrodSmithはい、それはパスです。アップデートをご覧ください。
tinlyx 2017

478

この質問に対する回答の大部分は、古くなっている、不完全である、または不必要に複雑です。

git 1.7.8以降を使用して複製されたサブモジュールは、ローカルリポジトリに最大4つのトレースを残します。これらの4つのトレースを削除するプロセスは、以下の3つのコマンドによって提供されます。

# Remove the submodule entry from .git/config
git submodule deinit -f path/to/submodule

# Remove the submodule directory from the superproject's .git/modules directory
rm -rf .git/modules/path/to/submodule

# Remove the entry in .gitmodules and remove the submodule directory located at path/to/submodule
git rm -f path/to/submodule

39
なぜこの回答に賛成票が少ないのですか?これらの一般的な回答はすべて何かを見逃しています。これは、サブモジュールのすべての痕跡を可能な限り単純な方法で本当に削除する唯一のものです。注:コマンドの順序は重要です。
mbdevpl 2016


5
@mbdevplは、回答が承認されてから3年後のものであり、OPがこれを受け入れるように説得できた人は誰もいないと思います
Andy

10
これは2018年の複雑な答えではありませんか?
ウォーレンP

9
.gitmodulesファイルは、これらのコマンドを実行しても影響を受けないようです
Fractalf

206

簡単な手順

  1. 構成エントリを削除します。
    git config -f .git/config --remove-section submodule.$submodulename
    git config -f .gitmodules --remove-section submodule.$submodulename
  2. インデックスからディレクトリを削除:
    git rm --cached $submodulepath
  3. コミット
  4. 未使用のファイルを削除します。
    rm -rf $submodulepath
    rm -rf .git/modules/$submodulename

注意: $submodulepath先頭または末尾のスラッシュは含まれません。

バックグラウンド

するとgit submodule add、それはに追加されるだけ.gitmodulesですがgit submodule init、一度追加すると、に追加されます.git/config

したがって、モジュールを削除したいが、すぐに復元できる場合は、次のようにします。

git rm --cached $submodulepath
git config -f .git/config --remove-section submodule.$submodulepath

git rebase HEAD最初に行うことをお勧めしますgit commit スクリプトに入れる場合は、最後に行うことをお勧めします。

また、見てきた答えができます私はGitのサブモジュールをunpopulate?


1
私はたくさんのサブモジュール(そしてより大きな混乱)を持っていたので、それらをforループに通さなければなりませんでした。それらのほとんどが特定のディレクトリとls出力の下にあるため、末尾にスラッシュが含まれていました。のようなことをしましたfor dir in directory/*; do git rm --cached $dir; done
パブロオルモスデアギレラC.

再帰的な削除のためのスクリプトで使用することができ、このリストを取得するには- git config -f .git/config -l | cut -d'=' -f1 | grep "submodule.$MODPATH" | sed 's/^submodule\.//' | sed 's/\.url$//'- -ルックスあなたがめちゃめちゃに何かがあれば、本当に場合にはこれを行うには持っているように、それ以外の場合はちょうどgit submodule | grep -v '^+' | cut -d' ' -f3
errordeveloper

2
ローカルの変更が加えられていないモジュールのリストを取得するgit submodule | grep '^+' | cut -d' ' -f2
errordeveloper '12 / 10/12

ノート、私は含まれなければならなかったsubmodulename、二重引用符で"submodulename"参照... .git/configファイル
ミュオン

シンプル。効率的。2.25.0では、ステップ1の後、ステップ2の前に.gitmodulesの変更をステージングする必要があります
Michel Donais

83

推奨事項rm -Rf .git/modules/path/to/submoduleに加えて、同じ名前の新しいサブモジュールを追加できるようにする必要もありました(私の場合、フォークを元のフォークで置き換えていました)


1
私もこれで困っていました。同じパスにサブモジュールを再インストールしようとすると、ブランチ情報は、問題を引き起こした言及した場所にキャッシュされたままになります。
jangosteve 2012年

ありがとう、これも必要でした。@Anton、同意し、トップ投票の回答を編集してこの情報を追加しました。
ウィリアム・デニス

--nameオプションを使用して置換を機能させました... stackoverflow.com/questions/14404704/…を
joseph.hainline

60

追加されたサブモジュールを削除するには:

git submodule add blah@blah.com:repos/blah.git lib/blah

実行:

git rm lib/blah

それでおしまい。

古いバージョンのgit(約〜1.8.5)を使用する場合:

git submodule deinit lib/blah
git rm lib/blah
git config -f .gitmodules --remove-section submodule.lib/blah

1
確かに+1。これはgit 1.8.3以降の唯一の正解です。正しいものとして受け入れられるべきです。
Xananax 14

6
git rmまだものを残し.git/modules/ます。(2.5.4)
ルドルフアダムコビッチ

1
@RudolfAdamkovicそれは私のために働きますか?正確なパスが一致する場合にのみサブモジュールエントリを削除することに注意してください。サブモジュールを移動してから使用したgit rm場合、移動しません。ここではマニュアルに記載されている私のMac上で2.5.4で簡単なテストは、.gitmodulesファイルを更新します。git-scm.com/docs/git-rm#_submodules ...しかし、あなたは、プラットフォームの組み合わせのいくつかの種類を発見した場合/これが発生しないバージョンでは、おそらくそれに関するバグを提出する必要があります。
Doug

2
この答えは完全に正しいわけではありません。dirと fileにgit rm内容を残します(ubuntu、git 2.7.4)。その他の回答は100%機能します:stackoverflow.com/a/36593218/4973698.git/modules/.git/config
mbdevpl

50

.gitmodulesおよびのエントリ.git/configを削除し、モジュールのディレクトリを履歴から削除する必要があります。

git rm --cached path/to/submodule

gitのメーリングリストに投稿する場合、おそらく誰かがシェルスクリプトを作成してくれるでしょう。


:任意のシェルスクリプトのための必要はありません、他の答えは、すべてのサブモジュールの痕跡削除するためのコマンドがあるstackoverflow.com/a/36593218/4973698
mbdevplを

42

エイリアスを使用して、他の人が提供するソリューションを自動化できます。

[alias]
  rms = "!f(){ git rm --cached \"$1\";rm -r \"$1\";git config -f .gitmodules --remove-section \"submodule.$1\";git config -f .git/config --remove-section \"submodule.$1\";git add .gitmodules; }; f"

それをgit configに入れれば、次のことができます。 git rms path/to/submodule


これは明白すぎるので、-1。まず、これはサブモジュールの名前とパスが同一であることを前提としていますが、ほとんどの場合はそうではありません。IE git clone https://github.com/hilbix/empty.git; cd empty; git submodule add https://github.com/hilbix/empty.git one; git mv one two; git rms two。2番目:正しいパスから実行する必要があります。 gitエイリアスはワークツリーのどこでも機能するはずです(または正常に失敗します)。THIRD:通常はファイルがあるgit config -f .git/configので.git、サブモジュール内で失敗します。
Tino、

42

要約すると、これはあなたがすべきことです:

  1. 変数を設定path_to_submodule(末尾にスラッシュなし):

    path_to_submodule=path/to/submodule

  2. .gitmodulesファイルから関連する行を削除します。

    git config -f .gitmodules --remove-section submodule.$path_to_submodule

  3. .git / configから関連するセクションを削除します

    git config -f .git/config --remove-section submodule.$path_to_submodule

  4. ステージングを解除し、インデックスからのみ$ path_to_submoduleを削除します(情報の損失を防ぐため)。

    git rm --cached $path_to_submodule

  5. .gitmodulesに加えられた変更を追跡する

    git add .gitmodules

  6. スーパープロジェクトをコミットする

    git commit -m "Remove submodule submodule_name"

  7. 追跡されなくなったサブモジュールファイルを削除する

    rm -rf $path_to_submodule

    rm -rf .git/modules/$path_to_submodule


だから私の変更を引き下げる他の誰もが、サブモジュールのキャッシュを削除するためにrm -rf $ path_to_submodule rm -rf .git / modules / $ path_to_submoduleを実行する必要がありますか?
j2emanue 2015

更新することをお勧めしgit submodule updateます。そして、サブモジュールパスが(gitのは、エラーがスローされます)が正しく更新されなかった場合は、それらを削除:rm -rf .git/modules/<submodule> && rm -rf <submodule> && git submodule update
luissquall

40

すでにGitリポジトリ(含まれている)であるフォルダーを追加、コミット、およびプッシュしたためにサブモジュールが誤って追加された場合、編集.gitする.gitmodulesファイルなどはありません.git/configこの場合、必要なのは次のとおりです。

git rm --cached subfolder
git add subfolder
git commit -m "Enter message here"
git push

FWIW.git実行する前にフォルダも削除しましたgit add


まさに私の場合
zhekaus

37

deinitは私にとって良い作品を見つけました:

git submodule deinit <submodule-name>    
git rm <submodule-name>

git docsから:

deinit

指定されたサブモジュールの登録を解除します。つまりsubmodule.$name 、ワークツリーとともに.git / configからセクション全体を削除します。


同意して同じ解決策を見つけた。2018年の今日は最良の方法です)
woto

1
.git / modules / ..は削除されませんでした。あなたは@fvgsで答えを参照してください、それらを削除する必要があります
ヴィレーム・クルツ

このシンプルで簡単なソリューションがなぜ1番にならないのか分からない
Marc Magon

AFAICSこれは、を知っている新しいgits にとって最も安全な回答のようです。もう1つの回答はディレクトリを削除するのが早すぎるため、新しいsが時折失敗するようです。また、(私のコメントを参照)削除は間違ったパスになる可能性があるため、これは危険なステップであり、後で苦情があった場合にのみ行うのが最適です(または、299%確信している場合、これが正しいパスであり、本当に必要です)。deinit.git/modules/submodulegit.git/modules/submodulegit
Tino、

またgit commit、作業ディレクトリで段階的な変更をコミットする必要もありました:modified .gitmodulesdeleted <submodule-path>
Yuriy Pozniak

20

このサイトでさまざまな答えをすべて試した後、私はこの解決策を見つけました:

#!/bin/sh
path="$1"
if [ ! -f "$path/.git" ]; then
  echo "$path is no valid git submodule"
  exit 1
fi
git submodule deinit -f $path &&
git rm --cached $path &&
rm -rf .git/modules/$path &&
rm -rf $path &&
git reset HEAD .gitmodules &&
git config -f .gitmodules --remove-section submodule.$path

これにより、サブモジュールを追加する前とまったく同じ状態が復元されます。サブモジュールをすぐに再度追加することができますが、ここではほとんどの回答では不可能でした。

git submodule add $giturl test
aboveScript test

これにより、コミットする変更がないクリーンなチェックアウトが可能になります。

これは以下でテストされました:

$ git --version
git version 1.9.3 (Apple Git-50)

なぜあなたは使用しないgit rm --cached $path、その後rm -rf $pathの代わりにgit rm -r $path
bfontaine 2014年

-1サブモジュール内のサブモジュールを削除しようとしても機能しません(サブモジュールはツリーを形成できます!)。また、これは引用が欠落しているため危険なバグがあります!例git submodule add https://github.com/hilbix/empty.git 'dangerous .. submodule'->スクリプトで 'dangerous .. submodule'を削除しようとすると、これはrm -rf ..おそらく望んでいることではありません..
Tino

17

私が現在2012年12月に行っていること(これらの回答のほとんどを組み合わせたもの):

oldPath="vendor/example"
git config -f .git/config --remove-section "submodule.${oldPath}"
git config -f .gitmodules --remove-section "submodule.${oldPath}"
git rm --cached "${oldPath}"
rm -rf "${oldPath}"              ## remove src (optional)
rm -rf ".git/modules/${oldPath}" ## cleanup gitdir (optional housekeeping)
git add .gitmodules
git commit -m "Removed ${oldPath}"

15

これが私がしたことです:

1.).gitmodulesファイルから関連セクションを削除します。以下のコマンドを使用できます:

git config -f .gitmodules --remove-section "submodule.submodule_name"

2.).gitmodules変更をステージングする

git add .gitmodules

3.)から関連セクションを削除します.git/config。以下のコマンドを使用できます:

git submodule deinit -f "submodule_name"

4.)gitlinkを削除します(末尾のスラッシュなし):

git rm --cached path_to_submodule

5.)クリーンアップ.git/modules

rm -rf .git/modules/path_to_submodule

6.)コミット:

git commit -m "Removed submodule <name>"

7.)追跡されなくなったサブモジュールファイルを削除する

rm -rf path_to_submodule

これをありがとう。私にとって、最初の3つのステップの順序を3)、1)、2)に並べ替える必要がありました。1)を実行すると、最初fatal: no submodule mapping found in .gitmodules for path 'submodule_name'にステップ3で行われますが、両方のステップが必要でした。(git v2.8.2)
U007D 2016

13

私は最近、多くの便利なgit関連コマンドを含むgitプロジェクトを見つけました:https : //github.com/visionmedia/git-extras

インストールして次のように入力します。

git-delete-submodule submodule

その後、物事が行われます。サブモジュールディレクトリはリポジトリから削除され、ファイルシステムにまだ存在します。その後、次のように変更をコミットできますgit commit -am "Remove the submodule"


動作するパスにある必要があるためgit delete-submodule、これをとして呼び出すことができますgit-extras。また、その多くの部分は非常にバグが多く危険なので、使用しないgit-extrasことをお勧めします。IE は以下の間違ったパスを削除する可能性があります。これは、モジュールとパスが同一であると想定しているため(多くの場合そうではない)、サブモジュール内のサブモジュールを削除しようとしても正しく機能しません。 99%役立つかもしれませんが、それを使用して完全にうまくいかなくても文句を言わないでください。 警告されました!git-delete-submodule.git/modules/*git-extras
Tino、

10

John Douthatの手順をさらに一歩進めcdてサブモジュールのディレクトリに移動し、Gitリポジトリを削除する必要がありました。

cd submodule
rm -fr .git

次に、サブモジュールへの古い参照なしで、ファイルを親Gitリポジトリの一部としてコミットできます。


git rm --cache手順を実行しようとしたときに「致命的:gitリポジトリではありません:」というエラーを回避するためにも、これを行う必要がありました。
RickDT 2013

9

ここに、私が必要または有用であると判断した4つのステップがあります(重要なステップが最初)。

git rm -f the_submodule
rm -rf .git/modules/the_submodule
git config -f .git/config --remove-section submodule.the_submodule
git commit -m "..."

理論的にgit rmステップ1で処理する必要があります。うまくいけば、OP質問の2番目の部分は1日で肯定的に回答できます(これは1つのコマンドで実行できます)。

ただし、2017年7月現在、データを削除するにはステップ2が必要.git/modules/です。それ以外の場合は、たとえばサブモジュールを後で追加することはできません。

tinlyxの答えが指摘しているように、git 1.8.5以降では上記の2つのステップで問題を回避できます。git submoduleコマンドが機能しているように見えるのでます。

ステップ3はthe_submodule、ファイル内ののセクションを削除します.git/config。これは完全を期すためになされるべきです。(エントリは古いgitバージョンで問題を引き起こす可能性がありますが、テストするものはありません)。

このため、ほとんどの回答はの使用を推奨していgit submodule deinitます。私はそれを使用する方がより明確で混乱が少ないと思いますgit config -f .git/config --remove-sectiongit-サブモジュールのドキュメントによると、git deinit

指定されたサブモジュールの登録を解除します...サブモジュールをリポジトリから削除してコミットする場合は、代わりに git-rm [1]を 使用してください

最後git commitに重要なことですが、そうしないと 、実行時にエラーが発生しますgit submodule summary(git 2.7以降)。

fatal: Not a git repository: 'the_submodule/.git'
* the_submodule 73f0d1d...0000000:

これは、ステップ2と3のどちらを実行するかには関係ありません。


7
project dir:     ~/foo_project/
submodule:       ~/foo_project/lib/asubmodule
- - - - - - - - - - - - - - - - - - - - - - - - -
run:
  1.   cd ~/foo_project
  2.   git rm lib/asubmodule && 
          rm .git/modules/lib/asubmodule && 
            git submodule lib/asubmodule deinit --recursive --force

7

.submodule(正確な名前を忘れた)隠しファイルを見つけました。これにはリストがあります...それらを個別に消去できます。持っていたので削除しました。単純ですが、サブモジュールに何が接続されているかわからないので、Gitを台無しにする可能性があります。libetpanの通常のアップグレードの問題は別として、これまでのところ問題はないようですが、それは(うまくいけば)無関係です。

誰も手動消去を投稿していないことに気付いたので追加


それは.gitmodules
Arialdo Martini

7

git 2.17以降では、次のようになります。

git submodule deinit -f {module_name}
git add {module_name}
git commit

もも動作しgit 2.17.1ませんでしたgit 2.20.1。ただし、両方git rmgit add機能する代わりに使用します。注:物事がきれい-f場合は必要ありません。必ずオプションを使用することはありませんgit、あなたが意図しないデータ損失から保護したい場合。また、これはそのまま.git/modules/{module_name}になります。 これがgit原因で何かがブロックされた場合に、正しい(!)の出力がどのように進むかを助けるので、それをそこに保つことがベストプラクティスです。
Tino、

4

サブモジュールを追加したばかりで、たとえば、間違ったサブモジュールを追加した場合や、間違った場所に追加した場合git stashは、フォルダーを削除してください。これは、サブモジュールの追加が最近のリポジトリで行った唯一のものであることを前提としています。


3

読者の利益のために、ここではそれを要約し、物事が期待どおりに機能しない場合にそれを行う方法について段階的なガイドを提供することを試みます。以下は、サブモジュールを取り除くためのバージョン以上のテスト済みで安全な方法です。git2.17

submodule="path/to/sub"              # no trailing slash!
git submodule deinit -- "$submodule"
git rm -- "$submodule"
  • これでうまくいかない場合は、以下を参照してください。
  • オプションはありません。危険はありません。そして、もっとやることを考えさえしないでください!
  • Debian Buster 2.20.1およびUbuntu 18.04でテスト済み2.17.1
  • "$submodule" 名前を付ける場所を強調するだけで、スペースなどに注意する必要があります
  • Windowsの場合、最初の行を無視"$submodule"し、サブモジュールへの適切に指定されたパスのWindowsの方法で置き換えます。(私はWindowsではありません)

警告!

.git自分でディレクトリの内部に触れないでください。 内部編集.gitはダークサイドに入ります。絶対に近づかないでください!

そして、はい、git多くの便利なものが欠けていたので、あなたはこれのせいにすることができますgit過去にたので、。サブモジュールを再び削除する適切な方法のように。

のドキュメントには非常に危険な部分があると思いますgit submodule$GIT_DIR/modules/<name>/自分自身を削除することをお勧めします。 私の理解では、これは明らかに間違っているだけでなく、非常に危険であり、将来的に大きな頭痛の種となるでしょう! 下記参照。

ご了承ください

git module deinit

の直接逆

git module init

だが

git submodule deinit -- module
git rm -- module

また、かなり逆です

git submodule add -- URL module
git submodule update --init --recursive -- module

一部のコマンドは、基本的に1つ以上のことを実行する必要があるためです。

  • git submodule deinit -- module
    • (1)アップデート .git/config
  • git rm
    • (2)モジュールのファイルを削除します
    • (3)これにより、サブモジュールのサブモジュールが再帰的に削除されます
    • (4)アップデート .gitmodules
  • git submodule add
    • データを引き込む .git/modules/NAME/
    • (1)するgit submodule initので、更新.git/config
    • (2)行うgit submodule updateので、モジュールを非再帰的にチェックアウトします
    • (4)アップデート .gitmodules
  • git submodule update --init --recursive -- module
    • 必要に応じてさらにデータを取得します
    • (3)サブモジュールのサブモジュールを再帰的にチェックアウトします

これを完全に対称にすることはできません。厳密に対称に保つことはあまり意味がありません。3つ以上のコマンドは必要ありません。また、「データのプル」は暗黙的に行われます。必要なためですが、キャッシュされた情報の削除は行われません。これはまったく必要がなく、貴重なデータを消去する可能性があるためです。

これは本当に初心者には不可解ですが、基本的には良いことです。 git明らかにそれを実行し、それを正しく実行するだけで、それ以上のことはしません。 gitは、単なる別の "Eierlegende Wollmilchsau"( "Eierlegende Wollmilchsau"は "スイスアーミーナイフのいくつかの邪悪なバージョン"と解釈されます)ではなく、信頼できる仕事をしなければならないツールです。

だから私は「なぜ私にはgit明白なことをしないのか」と言って人々の不満を理解しています。これは、ここでの「自明」が観点から決まるためです。あらゆる状況での信頼性ははるかに重要です。したがって、多くの場合、明らかなことは、考えられるすべての技術的状況において正しいことではありません。覚えておいてください:AFAICSgitは社会的な道ではなく、技術的な道をます。(したがって、賢い名前:git)

これが失敗した場合

上記のコマンドは、次の理由で失敗する可能性があります。

  • あなたgitは年を取りすぎています。その後、新しいを使用してくださいgit。(以下の方法を参照してください。)
  • コミットされていないデータがあり、データを失う可能性があります。次に、最初にそれらをコミットします。
  • あなたのサブモジュールはあるgit clean意味できれいではありません。次に、最初にそのコマンドを使用してサブモジュールをクリーンアップします。(下記参照。)
  • あなたは過去にサポートされていない何かをしました git。次に、あなたは暗い側面にあり、物事は醜く複雑になります。(おそらく別のマシンを使用すると修正されます。)
  • おそらく、私が気づいていない失敗する方法が他にもあるでしょう(私は一部のgitパワーユーザーです)。

可能な修正が続きます。

新しいものを使う git

あなたのマシンが古すぎる場合は全くありませんsubmodule deinit、あなたにgit。を更新したくない(または更新できない)場合gitは、新しいgit!の別のマシンを使用してください。 git完全に分散されることを意図しているので、別のものgitを使って仕事を終わらせることができます:

  • workhorse:~/path/to/worktree$ git status --porcelain 何も出力しないでください!ある場合は、最初にクリーンアップしてください!
  • workhorse:~/path/to/worktree$ ssh account@othermachine
  • othermachine:~$ git clone --recursive me@workhorse path/to/worktree/.git TMPWORK && cd TMPWORK
  • 次にサブモジュールのことを行います
  • othermachine:~/TMPWORK$ git commit . -m . && exit
  • workhorse:~/path/to/worktree$ git fetch account@othermachine:TMPWORK/.git
  • workhorse:~/path/to/worktree$ git merge --ff-only FETCH_HEAD。これが機能しない場合は、git reset --soft FETCH_HEAD
  • クリーンアップするようにgit statusなりました。最初のステップのおかげで、以前はきれいにしていたので、それを行うことができます。

これothermachineは、VMでも、WindowsでのUbuntu WSLでもかまいません。a chroot(ただし、ルートでない場合はroot、新しいに更新する方が簡単であるため、ルートでないことを前提としていますgit)。

ssh入室できない場合は、gitリポジトリを転送する方法がたくさんあることに注意してください。ワークツリーをUSBスティック(.gitディレクトリを含む)にコピーし、スティックからクローンを作成できます。コピーを複製して、再びクリーンな状態にしてください。他のマシンから直接サブモジュールにアクセスできない場合、これはPITAである可能性があります。しかし、これに対する解決策もあります:

git config --add url.NEWURLPREFIX.insteadOf ORIGINALURLPREFIX

この乗算を使用でき、これはに保存され$HOME/.gitconfigます。何かのようなもの

git config --add 'url./mnt/usb/repo/.insteadof' https://github.com/

のようなURLを書き換えます

https://github.com/XXX/YYY.git

/mnt/usb/repo/XXX/YYY.git

gitこのような強力な機能に慣れ始めたら簡単です。

最初にクリーンアップする

手動でクリーンアップすることをお勧めします。これにより、忘れていたものを検出できる可能性があります。

  • 保存されていないものについてgitが文句を言う場合は、コミットして安全な場所にプッシュしてください。
  • gitのは、いくつかの残り物を訴え、場合git statusgit clean -ixfdあなたの友達です
  • オプションを控えるようにしてくださいrmdeinitすることができます限り。あなたがプロであるなら-f、オプション(のような)gitは良いです。しかし、あなたがここに来たとき、あなたはおそらくそのsubmodule地域でそれほど経験されていません。申し訳ありませんが、安全であることをお勧めします。

例:

$ git status --porcelain
 M two
$ git submodule deinit two
error: the following file has local modifications:
    two
(use --cached to keep the file, or -f to force removal)
fatal: Submodule work tree 'two' contains local modifications; use '-f' to discard them
$ cd two
$ git submodule deinit --all
error: the following file has local modifications:
    md5chk
(use --cached to keep the file, or -f to force removal)
fatal: Submodule work tree 'md5chk' contains local modifications; use '-f' to discard them
$ cd md5chk
$ git submodule deinit --all
error: the following file has local modifications:
    tino
(use --cached to keep the file, or -f to force removal)
fatal: Submodule work tree 'tino' contains local modifications; use '-f' to discard them
$ cd tino
$ git status --porcelain
?? NEW
$ git clean -i -f -d
Would remove the following item:
  NEW
*** Commands ***
    1: clean                2: filter by pattern    3: select by numbers    4: ask each
    5: quit                 6: help
What now> 1
Removing NEW
$ cd ../../..
$ git status --porcelain
$ git submodule deinit two
Cleared directory 'two'
Submodule 'someunusedname' (https://github.com/hilbix/src.git) unregistered for path 'two'

ご覧のとおり、には-f必要ありませんsubmodule deinit。あるgit clean意味で物事がきれいなら。また、git clean -x必要ないことに注意してください。 これgit submodule deinitは、無視された追跡されていないファイルを無条件に削除することを意味します。 これは通常あなたが望むものですが、忘れないでください。キャッシュされたデータが再計算されるまでに数時間から数日かかるような、無視されたファイルは貴重な場合があります。

なぜ削除し$GIT_DIR/modules/<name>/ないのですか?

後で問題が発生するのを恐れているため、おそらくキャッシュされたリポジトリを削除したいと思うでしょう。これは本当ですが、その「問題」に遭遇することがそれを解決する正しい方法です!修正は簡単で、正しく行われるので、いつまでも幸せに暮らせるでしょう。これにより、自分でデータを削除する場合よりも厄介な問題を回避できます。

例:

mkdir tmptest &&
cd tmptest &&
git init &&
git submodule add https://github.com/hilbix/empty.git two &&
git commit -m . &&
git submodule deinit two &&
git rm two &&
git commit -m . &&
git submodule add https://github.com/hilbix/src.git two

最後の行は次のエラーを出力します:

A git directory for 'two' is found locally with remote(s):
  origin    https://github.com/hilbix/empty.git
If you want to reuse this local git directory instead of cloning again from
  https://github.com/hilbix/src.git
use the '--force' option. If the local git directory is not the correct repo
or you are unsure what this means choose another name with the '--name' option.

なぜこのエラーなのか?ので.git/modules/two/以前から移入されたhttps://github.com/hilbix/empty.gitとなりましすなわち、何か他のものから再投入されなければならないhttps://github.com/hilbix/src.githttps://github.com/hilbix/empty.gitから再入力しても、これは表示されません

今何をする?まあ、ちょうど言われたとおりにしてください!使用する--name someunusedname

git submodule add --name someunusedname https://github.com/hilbix/src.git two

.gitmodules その後のようになります

[submodule "someunusedname"]
    path = two
    url = https://github.com/hilbix/src.git

ls -1p .git/modules/ 与える

someunusedname/
two/

この方法では、将来、ブランチ/コミットを前後に切り替えることができtwo/2つの異なる(場合によっては互換性のない)アップストリームリポジトリがあるため、再び問題が発生することはありません。そして、最高のものは、両方ともローカルにキャッシュすることです。

  • これはあなただけに当てはまるわけではありません。これは、リポジトリを使用する他のすべてのユーザーにも当てはまります。
  • そして、あなたは歴史を失うことはありません。古いサブモジュールの最新バージョンをプッシュするのを忘れた場合は、ローカルコピーを入力して後で実行できます。誰かがいくつかのサブモジュールをプッシュするのを忘れるのはごく一般的なことです(これは、慣れるまで、これは新参者のためのPITAであるためgit)。

しかし、キャッシュされたディレクトリを削除した場合、--nameオプションを使用しないため、両方の異なるチェックアウトが互いにぶつかります。したがって、チェックアウトを実行するたびに、おそらく.git/modules/<module>/ディレクトリを何度も削除する必要があります。これは非常に扱いにくく、のようなものを使用するのを難しくしますgit bisect

したがって、このモジュールディレクトリをプレースホルダーとして保持することには、非常に技術的な理由があります。以下の何かを削除することを推奨する人々は、これがそのようなサブモジュールの非互換性を越える.git/modules/と、これが強力な機能git bisectを使用することをほぼ不可能にするようなことをよく知らない、または忘れることを忘れます。

さらなる理由は上に示されています。を見てくださいls。そこで何が見えますか?

さて、モジュールの2番目のバリアントはtwo/.git/modules/two/にありません、下にあり.git/modules/someunusedname/ます!のようなものgit rm $module; rm -f .git/module/$moduleは完全に間違っています!相談するmodule/.git.gitmodules、削除する適切なものを見つける必要があります!

したがって、他のほとんどの回答がこの危険なトラップに該当するだけでなく、非常に人気のあるgit拡張機能このバグがありました現在は修正されています)。そのため、.git/正確に行わない場合は、ディレクトリを手元に置いておくことをお勧めします。

そして哲学的な観点から、歴史を拭くのは常に間違っています! いつものように、量子力学を除いて、これは完全に異なるものです。

FYIあなたはおそらくそれを推測:hilbixは、私のGitHubのアカウントです。


この投稿の百科事典は、実際の回答を示すために、大きく/明確な小見出しを持つ明確なセクションと、さまざまな「トラブルシューティング」/その他のセクションに分割する必要があります。
Andrew

2

要約すると、これはあなたがすべきことです:

path_to_submodule変数を設定します(末尾のスラッシュなし):

path_to_submodule=path/to/submodule

.gitmodulesファイルから関連する行を削除します。

git config -f .gitmodules --remove-section submodule.$path_to_submodule

.git / configから関連するセクションを削除します

git config -f .git/config --remove-section submodule.$path_to_submodule

ステージングを解除し、インデックスからのみ$ path_to_submoduleを削除します(情報の損失を防ぐため)。

git rm --cached $path_to_submodule

.gitmodulesに加えられた変更を追跡する

git add .gitmodules

スーパープロジェクトをコミットする

git commit -m "Remove submodule submodule_name"

追跡されなくなったサブモジュールファイルを削除する

rm -rf $path_to_submodule

rm -rf .git/modules/$path_to_submodule

参照:代替ガイドライン


これを「git submodule add」の後にサブモジュールを削除する方法で拡張していただけますか?その場合、サブモジュールを削除するためにコミットは必要ないと思いますよね?
カルロウッド

私はあなたが交換しないする必要があると思うgit rm --cached $path_to_submoduleし、git add .gitmodules何を?最初のコマンドでエラーが発生しました:fatal: Please stage your changes to .gitmodules or stash them to proceedへのステージングされていない変更があったため.gitmodulesです。やってgit add .gitmodulesいることを最初に解きを。
カルロウッド

2

簡単だ:

  1. からセクションを削除 .gitmodules
  2. コール: git add .gitmodules
  3. コール: git submodule deinit <path to submodule>
  4. コール: git rm <path to submodule>
  5. コミットしてプッシュ

プロジェクトのモジュールファイルを手動で削除する必要があります。


2
私にとっては、呼び出すことが十分だったgit submodule deinit <submodule_name>git rm <path_to_submodule>。最後のコマンドは、内のエントリを自動的に削除し.gitmodulesます。Git 2.17
Dmytro Ovdiienko


0

最新のgitでは、gitサブモジュールを削除するには、わずか4つの操作が必要です。

  • の対応するエントリを削除 .gitmodules
  • ステージ変更 git add .gitmodules
  • サブモジュールディレクトリを削除する git rm --cached <path_to_submodule>
  • コミットする git commit -m "Removed submodule xxx"

0

以下のようにbashスクリプトを使用して1行のコマンドで実行する必要がある場合:

$ cd /path/to/your/repo && /bin/bash $HOME/remove_submodule.sh /path/to/the/submodule

$HOMEieという名前のディレクトリにbashスクリプトファイルを作成しますremove_submodule.sh

#!/bin/bash

git config -f .gitmodules --remove-section submodule.$1
git config -f .git/config --remove-section submodule.$1
git rm --cached $1
git add .gitmodules
git commit -m "Remove submodule in $1"
rm -rf $1
rm -rf .git/modules/$1
git push origin $(git rev-parse --abbrev-ref HEAD) --force --quiet


0
  • サブモジュールは、を実行して削除できますgit rm <submodule path> && git commit。これはを使用して元に戻すことができますgit revert
    • 削除すると、スーパープロジェクトの追跡データが削除され.gitmodulesます。これは、gitlinkエントリとファイル内のセクションの両方です。
    • サブモジュールの作業ディレクトリはファイルシステムから削除されますが、Gitディレクトリは別のリポジトリからフェッチすることなく過去のコミットをチェックアウトできるようにするために残されています。
  • サブモジュールを完全に削除するには、さらに手動でを削除し$GIT_DIR/modules/<name>/ます。

ソース: git help submodules


-1

gitサブモジュールの削除

git以下のサブモジュールを削除するには、4つのステップが必要です。

  1. .gitmodulesファイル内の対応するエントリを削除し ます。エントリーは以下のようになるかもしれません
[submodule "path_to_submodule"]
    path = path_to_submodule
    url = url_path_to_submodule
  1. ステージ変更 git add .gitmodules
  2. サブモジュールディレクトリを削除しgit rm --cached <path_to_submodule>ます。
  3. コミットしgit commit -m "Removed submodule xxx"てプッシュします。

ローカルで複製されたコピーのサブモジュールを完全にクリーンアップするには、以下で説明する追加の2つのステップが必要です。

  1. .git/configファイル内の対応するエントリを削除します。エントリーは以下のようになるかもしれません
[submodule "path_to_submodule"]
    url = url_path_to_submodule
  1. 行う rm -rf .git/modules/path_to_submodule

これらの5番目と6番目の手順では、コミットが必要な変更は作成されません。


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