基本的に私の問題は、_~/main-project/submodule
_がサブモジュールであることをgitに理解できないことです。
gitサブモジュールの使用経験があります:
dotfiles repository で_~/dotfiles-repo
_に.gitmodulesファイルを作成し、そこにパスとURLを追加しました。それ以来、サブモジュール内のファイルに変更を加えて_git status
_を実行すると、次のようなものが得られます:.vim/bundle/auto-complete (new commits) # in red
_.gitmodules
_ファイルを_~/main-project
_に作成しましたが、
~/main-project/submodule
_に変更を加え、その変更をプッシュしても、_git status
_を_~/main-project
_で実行すると、<submodule> (new commits) # in red
のような同様の応答が返されません。 それらのディレクトリで行われた変更を取得するだけですこれらのディレクトリのgithub
にあるフォルダのリンクをクリックすると、リポジトリ自体にリダイレクトされませんが、同じリポジトリにとどまります。
~/main-project/submodule
_内のファイルをインデックスに追加するように既にgitに指示しているからでしょうか?この質問 を読んだので、私は この答え に至りましたが、_git-subtree
_が必要かどうかわかりません。変更を元に戻すのが難しいかもしれないことはしたくありません。
編集: これは重複した解決策を提案しました も機能しませんでした。_
Updates were rejected because the remote contains work that you do not have locally
_というエラーを受け取りました。 @ GabLeRoux は、実際に_<repo-A>
_を_<repo-B>
_のURLにプッシュするように指示したようです。
ソリューションは非常に簡単です。 here から抽出されました。
git rm submodule-dir
submodule-dir
で追跡していたすべてのファイルを削除しますrm -rf submoduledir
submodule-dir
に残っていた可能性のある他のすべてのファイルを削除します。git commit
submodul-dir
でgitが追跡したファイルと追跡しなかったファイルを削除しました。それでは、次の作業を行います。git submodule add <remote-path-to-submodule>
.gitmodules
をチェックし、サブモジュールが正常に追加されたかどうかを確認することをお勧めします。私の場合、すでに.gitmodules
ファイルがあったので、修正する必要がありました。v2.12.0-rc であり、 this commit の後、git submodule absorbgitdirs
を受け取りました。これは、この質問を投稿したときにまさに必要でした。
これが docs このコマンドの状態です:
サブモジュールのgitディレクトリがサブモジュール内にある場合、サブモジュールのgitディレクトリをスーパープロジェクト
$GIT_DIR/modules
パスに移動し、core.worktree
を設定してを追加してgitディレクトリとその作業ディレクトリを接続します。スーパープロジェクトのgitディレクトリに埋め込まれたgitディレクトリを指すgitファイル。
そのため、@ DomQと私が以前の回答で提案したように最初からやり直す代わりに、次を実行するだけで追加できます。
.gitmodules
および.git/config
に追加します。git submodule add <url> <path>
$GIT_DIR
ディレクトリ(通常のリポジトリでは.git
)を.git/modules/<path>
に移動しますgit submodule absorbgitdirs <path>
基本的に最初からやり直すふりをするよりも良い方法はありません:
git submodule add
サブリポジトリのリモートからcd mysubmodule
git fetch ../wherever/you/stashed/the/sub-repository/in/step-1
git merge FETCH_HEAD
これがなぜそうなのかを説明するために、 git-submodule(1)
マニュアルページから収集できるものよりも、どのサブモジュールareが必要かをより深く理解するよりも、または、Gitブックの 関連の章でも )。 このブログ投稿 でさらに詳細な説明を見つけましたが、その投稿は少し長いので、ここでそれらを自由に要約します。
低レベルでは、gitサブモジュールは次の要素で構成されます。
.git/modules
のサブディレクトリ、.gitmodules
構成ファイルのエントリ。コミットオブジェクトは、親ツリーオブジェクトに含まれています(より正確には、SHA1によって参照されます)。 通常 は逆のことが起こるため、これは異常ですが、サブモジュールでコミットを実行した後にメインリポジトリのgit status
にディレクトリが表示される理由を説明します。 いくつかの実験 をgit ls-tree
で作成して、このコミットオブジェクトをより詳細に観察することもできます。
.git/modules
のサブディレクトリは、サブモジュールの.git
サブディレクトリを表します。そして実際、サブモジュールには.git
行を使用して前者を指すgitdir:
fileがあります。これは、Gitのバージョン1.7.8以降のデフォルトの動作 です 。別の.git
ディレクトリを保持しているだけですべてが機能しない理由はわかりません。ただし、リリースノートに記載されている場合を除き、サブモジュールを持つブランチとそうでないブランチを切り替えるときに問題が発生する可能性があります't。
.gitmodules
ファイルは、git submodule update --remote
および友人がプルするURLを提供します。これは明らかに、メインリポジトリのリモートのセットとは異なります。また、.gitmodules
コマンドと、それをバックグラウンドで呼び出す他のコマンドによって、.git/config
の一部がgit submodule sync
にコピーされることに注意してください。
.gitmodules
+ .git/config
、および.git/modules
+ mysubmodule/.git
(および実際にはgit submodule absorbgitdirs
(後者の場合)、実際には、ツリー内コミットオブジェクトのみを作成するための磁器はありません。したがって、上記の変更を移動+再実行することにより提案されたソリューション。
質問に順番に回答するには:
git rm --cached submodule-name/
。次に、中間コミットを作成してから、フォルダーをリポジトリーとして追加します:git add submodule-name
(サブモジュールの場合、サブモジュール名の後に末尾のスラッシュがないことに注意してください)。あなたが言及した answer は、コミットの履歴も修正するかもしれません:
そのフォルダーは、将来のコミットだけでなく、すべてのコミット履歴でサブモジュールとして扱われます。これにより、フォルダのように扱われた以前のバージョンにチェックアウトする場合の複雑さを回避できます。ブランチの先端に戻ると、サブモジュールも入力し、最新のコミットをチェックアウトして、すべてのファイル(作業ディレクトリから削除される可能性がある)を復元する必要があるため、これは複雑です。これは、最新のコミットに対して何らかの再帰的なチェックアウトを行うことで回避できます。
コミット履歴が変更された場合、他のすべてのコントリビューターは、マージの競合またはさらに悪化するため、プロジェクトを再クローンする必要があります。問題をコミットしてプロジェクトに再導入します。