web-dev-qa-db-ja.com

Gitリポジトリ内で既存のGitサブモジュールを移動するにはどうすればよいですか?

GitスーパープロジェクトのGitサブモジュールのディレクトリ名を変更したいと思います。

.gitmodulesファイルに次のエントリがあるとします。

[submodule ".emacs.d/vimpulse"]  
path = .emacs.d/vimpulse  
url = git://gitorious.org/vimpulse/vimpulse.git

.emacs.d/vimpulseディレクトリを最初に削除せずに.emacs.d/vendor/vimpulseディレクトリに移動して(説明は here および here )、それから再度追加するには何を入力する必要がありますか?.

Gitはサブモジュールタグに完全なパスを本当に必要としますか

[submodule ".emacs.d/vimpulse"]

または、サブプロジェクトの名前だけを保存することもできますか?

[submodule "vimpulse"]
314
thisch

注:コメントで述べたように、この回答は古いバージョンのgitで必要な手順を指します。 Gitはサブモジュールの移動をネイティブでサポートするようになりました。

Git 1.8.5以降、git mv old/submod new/submodは期待どおりに動作し、すべての配管を行います。サブモジュールの移動の修正が含まれているため、git 1.9.3以降を使用することをお勧めします。


サブモジュールを削除する方法と似ています( サブモジュールを削除するにはどうすればよいですか? を参照)。

  1. .gitmodulesを編集し、サブモジュールのパスを適切に変更し、git add .gitmodulesでインデックスに配置します。
  2. 必要に応じて、サブモジュールの新しい場所の親ディレクトリ(mkdir -p new/parent)を作成します。
  3. すべてのコンテンツを古いディレクトリから新しいディレクトリ(mv -vi old/parent/submodule new/parent/submodule)に移動します。
  4. Gitがこのディレクトリ(git add new/parent)を追跡していることを確認してください。
  5. git rm --cached old/parent/submoduleを使用して古いディレクトリを削除します。
  6. ディレクトリ.git/modules/old/parent/submoduleをそのすべてのコンテンツとともに.git/modules/new/parent/submoduleに移動します。
  7. .git/modules/new/parent/configファイルを編集し、ワークツリーアイテムが新しい場所を指していることを確認します。この例では、worktree = ../../../../../new/parent/moduleになります。通常、その場所の直接パスには、さらに2つの..ディレクトリが必要です。
  8. ファイルnew/parent/module/.gitを編集し、その中のパスがメインプロジェクト.gitフォルダー内の正しい新しい場所を指していることを確認してください。この例ではgitdir: ../../../.git/modules/new/parent/submoduleです。

    git statusの出力は、後で私にとって次のようになります。

    # On branch master
    # Changes to be committed:
    #   (use "git reset HEAD <file>..." to unstage)
    #
    #       modified:   .gitmodules
    #       renamed:    old/parent/submodule -> new/parent/submodule
    #
    
  9. 最後に、変更をコミットします。

308
Axel Beckert

上記のValloricのコメントから取られた最も現代的な答え:

  1. Git 1.9.3にアップグレードします(または サブモジュールにネストされたサブモジュールが含まれる場合は2.18
  2. git mv old/submod new/submod
  3. その後、.gitmodulesとサブモジュールディレクトリは既にコミット用にステージングされています(これはgit statusで確認できます)。
  4. git commitを使用して変更をコミットすると、準備完了です!

できた!

207
phatmann

私の場合、サブモジュールをあるディレクトリからサブディレクトリに移動したかったのです。 「AFNetworking」->「ext/AFNetworking」。これらは私が従った手順です:

  1. .gitmodulesを編集して、サブモジュール名とパスを「ext/AFNetworking」に変更します
  2. サブモジュールのgitディレクトリを「.git/modules/AFNetworking」から「.git/modules/ext/AFNetworking」に移動します
  3. ライブラリを「AFNetworking」から「ext/AFNetworking」に移動します
  4. 「.git/modules/ext/AFNetworking/config」を編集し、[core] worktree行を修正します。鉱山が../../../AFNetworkingから../../../../ext/AFNetworkingに変更されました
  5. 「ext/AFNetworking/.git」を編集し、gitdirを修正します。鉱山が../.git/modules/AFNetworkingから../../git/modules/ext/AFNetworkingに変更されました
  6. git add .gitmodules
  7. git rm --cached AFNetworking
  8. git submodule add -f <url> ext/AFNetworking

最後に、gitステータスで見ました:

matt$ git status
# On branch ios-master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   modified:   .gitmodules
#   renamed:    AFNetworking -> ext/AFNetworking

出来上がり。上記の例では、ディレクトリの深さは変更されません。これにより、タスクの複雑さが大きく変わり、サブモジュールの名前は変更されません(実際には必要ではないかもしれませんが、そのパスに新しいモジュールを追加した場合に発生します。)

55
Matt Connolly

[更新:2014-11-26] Yar は以下をうまく要約しているので、何かをする前に、サブモジュール。不明な場合は、 .git/.gitmodules を開いてキーを調べます submodule.<name>.url

私のために働いたのは、 古いサブモジュールを削除するgit submodule deinit <submodule>に続いてgit rm <submodule-folder>を使用することでした。次に、新しいフォルダー名でサブモジュールを再度追加し、コミットします。コミットする前にgitステータスを確認すると、古いサブモジュールが新しい名前に変更され、.gitmoduleが変更されたことが示されます。

$ git submodule deinit foo
$ git rm foo
$ git submodule add https://bar.com/foo.git new-foo
$ git status
renamed:    foo -> new-foo
modified:   .gitmodules
$ git commit -am "rename foo submodule to new-foo"
18
Mark Mikofski

トリックは、サブモジュールの.gitディレクトリが.git/modulesの下のマスターリポジトリに保持され、各サブモジュールがそれを指す.gitファイルを持っていることを理解しているようです。これが今必要な手順です:

  • サブモジュールを新しいホームに移動します。
  • サブモジュールの作業ディレクトリ内の.gitファイルを編集し、そこに含まれるパスを変更して、マスターリポジトリの.git/modulesディレクトリ内の正しいディレクトリを指すようにします。
  • マスターリポジトリの.git/modulesディレクトリを入力し、サブモジュールに対応するディレクトリを見つけます。
  • configファイルを編集し、worktreeパスを更新して、サブモジュールの作業ディレクトリの新しい場所を指すようにします。
  • マスターリポジトリのルートにある.gitmodulesファイルを編集し、サブモジュールの作業ディレクトリへのパスを更新します。
  • git add -u
  • git add <parent-of-new-submodule-directory>(サブモジュールディレクトリ自体ではなく、を追加することが重要です。)

いくつかのメモ:

  • [submodule "submodule-name"].gitmodules.git/config行は互いに一致する必要がありますが、他の行とは一致しません。
  • サブモジュールの作業ディレクトリと.gitディレクトリは、互いに正しくポイントする必要があります。
  • .gitmodulesおよび.git/configファイルは同期する必要があります。
11

標準のコマンドを使用して、新しいサブモジュールを追加し、古いサブモジュールを削除することができます。 (.git内の偶発的なエラーを防止する必要があります)

設定例:

mkdir foo; cd foo; git init; 
echo "readme" > README.md; git add README.md; git commit -m "First"
## add submodule
git submodule add git://github.com/jquery/jquery.git
git commit -m "Added jquery"
## </setup example>

「jquery」を「vendor/jquery/jquery」に移動する例:

oldPath="jquery"
newPath="vendor/jquery/jquery"
orginUrl=`git config --local --get submodule.${oldPath}.url`

## add new submodule
mkdir -p `dirname "${newPath}"`
git submodule add -- "${orginUrl}" "${newPath}"

## remove old submodule
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 old src
rm -rf ".git/modules/${oldPath}" ## cleanup gitdir (Housekeeping)

## commit
git add .gitmodules
git commit -m "Renamed ${oldPath} to ${newPath}"

大きなサブモジュールのボーナス方法:

サブモジュールが大きく、クローンを待たない場合は、Originとして古いを使用して新しいサブモジュールを作成し、Originを切り替えることができます。

例(同じセットアップ例を使用)

oldPath="jquery"
newPath="vendor/jquery/jquery"
baseDir=`pwd`
orginUrl=`git config --local --get submodule.${oldPath}.url`

# add new submodule using old submodule as Origin
mkdir -p `dirname "${newPath}"`
git submodule add -- "file://${baseDir}/${oldPath}" "${newPath}"

## change Origin back to original
git config -f .gitmodules submodule."${newPath}".url "${orginUrl}"
git submodule sync -- "${newPath}"

## remove old submodule
...
9
Lance Rushing

「[サブモジュール」の後の引用符で囲まれた文字列は重要ではありません。必要に応じて「foobar」に変更できます。 「.git/config」で一致するエントリを見つけるために使用されます。

したがって、「git submodule init」を実行する前に変更を加えた場合、正常に機能します。変更を加える(またはマージによって変更を取得する)場合は、手動で.git/configを編集するか、「git submodule init」を再度実行する必要があります。後者を行うと、.git/configに古い名前の無害な「孤立した」エントリが残ります。

8
Bob Bell

昨日、この試練を経て、 この答え は完璧に機能しました。明確にするために、ここに私の手順を示します。

  1. サブモジュールがチェックインされ、サーバーにプッシュされていることを確認します。また、どのブランチがオンになっているかを知る必要があります。
  2. サブモジュールのURLが必要です!more .gitmodulesを使用します
  3. これで、deinitrmsubmodule addを使用できます

コマンド

    git submodule deinit Classes/lib/mustIReally
    git rm foo
    git submodule add http://developer.audiob.us/download/SDK.git lib/AudioBus

    # do your normal commit and Push
    git commit -a 

注:git mvはこれを行いません。まったく。

2
Dan Rosenstark

シェルスクリプト git-submodule-move を使用するだけです。

2
Flimm

与えられた解決策は私にとってはうまくいきませんでしたが、同様のバージョンはうまくいきました...

これは複製されたリポジトリを使用しているため、サブモジュールgitリポジトリは最上位リポジトリ.git dirに含まれています。すべてのカチオンは、トップリポジトリからのものです。

  1. .gitmodulesを編集し、問題のサブモジュールの「path =」設定を変更します。 (ラベルを変更したり、このファイルをインデックスに追加したりする必要はありません。)

  2. .git/modules/name/configを編集し、問題のサブモジュールの "worktree ="設定を変更します

  3. 実行:

    mv submodule newpath/submodule
    git add -u
    git add newpath/submodule
    

リポジトリがアトミックまたは相対サブモジュールである場合、違いがあるのか​​どうか疑問に思います(私の場合、サブモジュール/.gitはtopproject/.git/modules/submoduleに戻る参照です)

2
arand