すべてのgitサブモジュールの最新をプルする簡単な方法


1846

私たちはgitサブモジュールを使用して、開発した他の多くのライブラリに依存するいくつかの大きなプロジェクトを管理しています。各ライブラリは、サブプロジェクトとして依存プロジェクトに組み込まれた個別のリポジトリです。開発中、依存するすべてのサブモジュールの最新バージョンを取得したいことがよくあります。

gitにはこれを行うための組み込みコマンドがありますか?そうでない場合、Windowsバッチファイルまたはそれを行うことができる同様のファイルはどうですか?


git-deepがこれに役立つはずです。
Mathew Kurian 2017年

9
@Bradは、サブモジュールのコピーをマスタープロジェクトで指定されたコミットリビジョンに更新しますか。または、すべてのサブモジュールから最新のHEADコミットをプルしますか?ここでの答えのほとんどは前者に対応しています。多くの人が後者を望んでいます。
chrisinmtown 2018

回答:


2464

それはだ場合は、初めてあなたがチェックアウトあなたが使用する必要がレポ--init最初に:

git submodule update --init --recursive

以下のためのgit 1.8.2以上、オプションは、--remoteリモートブランチの最新のヒントにサポート更新に追加されました。

git submodule update --recursive --remote

これには、.gitmodulesまたは.git/configファイルで指定された「デフォルト以外」のブランチを尊重するという追加の利点があります(たまたまある場合、デフォルトはorigin / masterです。この場合、他の回答のいくつかも機能します)。

以下のためのgit 1.7.3使用できる以上(ただし、更新はまだ適用されないものを周りの落とし穴以下):

git submodule update --recursive

または:

git pull --recurse-submodules

サブモジュールを現在のコミットではなく最新のコミットにプルしたい場合は、リポジトリがポイントします。

詳細はgit-submodule(1)を参照してください


299
おそらくあなたはgit submodule update --recursive今日を使うべきです。
Jens Kohl

38
パフォーマンスの向上:git submodule foreach "(git checkout master; git pull)&"
Bogdan Gusiev

18
updateは、各サブモジュールを指定されたリビジョンに更新しますが、そのリポジトリの最新のものに更新しません。
Peter DeWeese

21
追加するだけorigin masterで、一部のサブモジュールがその特定のサブモジュールの異なるブランチまたはロケーション名を追跡している場合、このコマンドの最後に盲目的に貼り付けると、予期しない結果になる可能性があります。一部の人にとっては明白ですが、おそらく誰にとってもそうではありません。
Nathan Hornby 14

31
皆のために明確にするために。git submodule update --recursive親リポジトリがサブモジュールごとに保存したリビジョンを確認し、各サブモジュールでそのリビジョンをチェックアウトします。各サブモジュールの最新のコミットはプルされませgit submodule foreach git pull origin masterまたはgit pull origin master --recurse-submodules、各サブモジュールを元のリポジトリから最新のものに更新する場合に必要です。そうして初めて、サブモジュールの更新されたリビジョンハッシュを持つ親リポジトリの保留中の変更が取得されます。それらをチェックインすれば、大丈夫です。
Chev

636
git pull --recurse-submodules --jobs=10

gitが1.8.5で最初に学習した機能。

バグが修正されるまで、初めて実行する必要があります

git submodule update --init --recursive


29
賛成、私はこれを使用します:エイリアスupdate_submodules = 'git pull --recurse-submodules && git submodule update'
Stephen C

3
これは、サブモジュールがすでに1回以上プルされている場合に機能しますが、チェックアウトされたことがないサブモジュールについては、以下のgahooaの回答を参照してください。
Matt Browne 2013年

8
これにより、トップリポジトリが指定するバージョンが表示されます。HEADをプルしません。たとえば、TopRepoがSubRepoのHEADの後ろにバージョン2を指定している場合、これはSubRepoを2つ後ろのバージョンでプルします。ここでの他の回答は、SubRepoでHEADをプルします。
Chris Moschini、2014年

11
どちらことを注意git pull --recurse-submodulesたりすることはgit submodule update --recursiveないではない、新たに追加されたサブモジュールを初期化しません。それらを初期化するには、を実行する必要がありますgit submodule update --recursive --initマニュアルからの引用:サブモジュールがまだ初期化されておらず、.gitmodulesに保存されている設定を使用したいだけの場合は、-initオプションを使用してサブモジュールを自動的に初期化できます。
patryk.beza 2016年

1
git submodule update --recursive --remote保存されたSHA-1ではなく、リモートの最新リビジョンにサブモジュールを更新するヒントを追加することもできます。
Hanno S.

386

initで次のコマンドを実行します。

git submodule update --init --recursive

git repoディレクトリ内から、私に最適です。

これにより、サブモジュールを含む最新のすべてがプルされます。

説明した

git - the base command to perform any git command
    submodule - Inspects, updates and manages submodules.
        update - Update the registered submodules to match what the superproject
        expects by cloning missing submodules and updating the working tree of the
        submodules. The "updating" can be done in several ways depending on command
        line options and the value of submodule.<name>.update configuration variable.
            --init without the explicit init step if you do not intend to customize
            any submodule locations.
            --recursive is specified, this command will recurse into the registered
            submodules, and update any nested submodules within.

この後、あなたはただ走ることができます:

git submodule update --recursive

git repoディレクトリ内から、私に最適です。

これにより、サブモジュールを含む最新のすべてがプルされます。


10
はい-投票数が最も多い回答が'09でそれを行うための最良の方法でしたが、これは現在、間違いなくよりシンプルで直感的です。
Michael Scott Cuthbert

2
@MichaelScottCuthbertおかげで、今後3年間でこのコマンドもクレイジーになると確信しています
abc123

5
それでも、これはサブモジュールから最新のリビジョンをチェックアウトせず、親が追跡している最新のリビジョンのみをチェックアウトします。
Nathan Osman

4
@NathanOsmanこれはあなたが望むものです...あなたは親のリビジョン追跡に従わないことによってコードが壊れてしまうでしょう。あなたが親のメンテナなら、自分で更新してコミットすることができます。
abc123

2
はい、しかし私の理解から、それはOPが望んでいたことではありません。
Nathan Osman

305

注:これは2009年のもので、当時は良かったかもしれませんが、現在はより良いオプションがあります。

これを使っています。それはgit-pup

#!/bin/bash
# Exists to fully update the git repo that you are sitting in...

git pull && git submodule init && git submodule update && git submodule status

適切なbinディレクトリ(/ usr / local / bin)に置くだけです。Windowsの場合、構文を変更して機能させる必要があるかもしれません:)

更新:

すべてのサブモジュールのすべてのHEADを取得することに関する元の作者のコメントへの回答-これは良い質問です。

gitこれには内部的にコマンドがないと確信しています。そのためには、サブモジュールにとってHEADが本当に何であるかを特定する必要があります。それmasterは、最新のブランチなどであると言うだけの簡単なことかもしれません...

これに続いて、以下を実行する簡単なスクリプトを作成します。

  1. git submodule status「変更された」リポジトリを確認します。出力行の最初の文字はこれを示しています。サブレポが変更された場合、続行しない場合があります。
  2. リストされた各リポジトリについて、そのディレクトリにcdして実行しgit checkout master && git pullます。エラーをチェックします。
  3. 最後に、サブモジュールの現在のステータスを示すために、ユーザーに表示を印刷することをお勧めします。おそらく、すべてを追加してコミットするように促すでしょうか?

このスタイルは、実際にはgitサブモジュールが設計されたものではないことを述べておきます。通常、「LibraryX」のバージョンは「2.32」で、「アップグレード」と指示するまでそのままです。

つまり、ある意味では、記述されたスクリプトを使用して実行していることですが、それは自動的に行われます。お手入れが必要です!

アップデート2:

Windowsプラットフォームを使用している場合は、Pythonを使用してスクリプトを実装することを検討することをお勧めします。スクリプトはこれらの領域で非常に機能します。unix / linuxを使用している場合は、bashスクリプトのみをお勧めします。

説明が必要ですか?コメントを投稿してください。


それは私が望んでいることではないと思います。スーパープロジェクトが最後にコミットされたサブモジュールのバージョンをプルしないでしょう。すべてのサブモジュールのヘッドバージョンを取得します。
Brad Robinson、

3
これはうまく機能し、サブモジュールを更新するだけでなく、必要な場合は初めてフェッチするためにも機能します。
Matt Browne 2013年

「現在のブランチの追跡情報がありません。マージするブランチを指定してください。」というメッセージが表示されます。私が何をしようとも:/
Nathan Hornby 14

9
エイリアスを作成してみませんか?スクリプトなしでgit config --global alias.pup '!git pull && git submodule init && git submodule update && git submodule status'使用しgit pupます。
fracz 2016

何らかの理由でgit 1.9.1を使用していgit submodule initますが、サブモジュールが含まれている最初のプルの後に実行する必要がありました。
ベンウスマン2016年

164

ヘンリックは正しい方向に進んでいます。'foreach'コマンドは任意のシェルスクリプトを実行できます。最新のものを取得する2つのオプションは、

git submodule foreach git pull origin master

そして、

git submodule foreach /path/to/some/cool/script.sh

これにより、初期化されたすべてのサブモジュールが反復処理され、指定されたコマンドが実行されます。


144

以下はWindows上で私のために働いた。

git submodule init
git submodule update

6
これは明らかにOPが要求したものではありません。関連するサブモジュールのコミットのみが更新され、最新のコミットは更新されません。
Patrick、

52
ただし、このページで、リポジトリを初めてチェックアウトしたときにgitがサブモジュールをプルしたのはこれだけです
theheadofabroom

2
次も使用できます:git submodule update --init --recursive(特に問題のサブモジュールが新しいクローンのRestKitの場合)
HCdev

33

編集

コメントで(philfreoによって)最新バージョンが必要であると指摘されました。最新バージョンである必要があるネストされたサブモジュールがある場合:

git submodule foreach --recursive git pull

-----以下の古いコメント-----

これは正式な方法ではありませんか?

git submodule update --init

毎回使っています。今のところ問題ありません。

編集:

私はあなたが使えることがわかりました:

git submodule foreach --recursive git submodule update --init 

これにより、サブモジュール、つまり依存関係もすべて再帰的にプルされます。


5
あなたの答えはOPの質問には答えませんが、あなたが提案したことを行うには、ただ言うことができますgit submodule update --init --recursive
philfreo

2
なるほど、最新版が必要です。ネストされたサブモジュールがある場合、これは有用かもしれません: git submodule foreach --recursive git pull
抗毒性

1
私はこれらのどれも実際には何もダウンロードすることができませんでした-「git submodule update --init --recursive」は私のために働きました。
BrainSlugs83 2013

33

サブモジュールのデフォルトのブランチがでない master場合があるので、これがGitサブモジュールの完全なアップグレードを自動化する方法です。

git submodule init
git submodule update
git submodule foreach 'git fetch origin; git checkout $(git rev-parse --abbrev-ref HEAD); git reset --hard origin/$(git rev-parse --abbrev-ref HEAD); git submodule update --recursive; git clean -dfx'

多くの質問に対する多くの回答のうち、これは私のために機能しました(2019、特定のハッシュIDによるgithubエラー)
philshem

30

初めて

サブモジュールの複製と初期化

git clone git@github.com:speedovation/kiwi-resources.git resources
git submodule init

残り

開発中にサブモジュールをプルして更新するだけです

git pull --recurse-submodules  && git submodule update --recursive

Gitサブモジュールをオリジンの最新のコミットに更新する

git submodule foreach git pull origin master

優先する方法は以下である必要があります

git submodule update --remote --merge

注:最後の2つのコマンドの動作は同じです


私は誤ってサブモジュールなしでgitクローンを作成しましたが、他のすべてのオプションは機能しませんでした。サブモジュールのクローンを作成する人はいませんでした。あなたのものを使ってgit submodule update、トリックをしました。次に、クローンの最初のステップで欠落しているサブモジュールデータをダウンロードしています。ありがとうございました。私はgitが得意ではありません:C
m3nda

このanserは、実際にここで質問するのに非常に良い答えです。なぜ「.. --recursive-submodules ..」、さらに「... update ...」「.. .foreach ... "後で最新のコミットを取得するには?これはすべてGITのようには見えません!「更新」とは何ですか。また、プルするために各モジュールに手動で移動する必要があるのはなぜですか。それは "... --recurse-submodules .."がしていることではないですか?ヒントはありますか?
Peter Branforn 2016年

20

これが機能しているgitのバージョンはわからないのですが、それがあなたが探しているものです:

git submodule update --recursive

私もそれを使ってgit pullルートリポジトリを更新しています:

git pull && git submodule update --recursive

10

上記の回答は適切ですが、これを簡単にするためにgit-hooksを使用していましたが、git 2.14ではgit config submodule.recurse、gitリポジトリにプルしたときにサブモジュールを更新できるようにtrueに設定できることがわかりました。

ただし、サブモジュールがブランチ上にある場合は、すべてのサブモジュールの変更をプッシュするという副作用がありますが、その動作が必要な場合は、これで十分です。

以下を使用して実行できます。

git config submodule.recurse true

git submodule initサブモジュールがまだ初期化されていない場合でも、残念ながらまだこのオプションを使用する必要があります。
ペレット

5

Windows 2.6.3の Git :

git submodule update --rebase --remote


それは私のために働いた唯一のものです。サブモジュールポインターがリモートにないバージョンを指しているため、初期化または更新さえできませんでした
Pavel P

4

リポジトリのトップレベルから:

git submodule foreach git checkout develop
git submodule foreach git pull

これにより、すべてのブランチが切り替えられ、最新の開発とプルが行われます


2
git 2.7では動作しません。
Bruno Haible

ツリー内のすべてのプロジェクト参照を追加するEverything slnファイルのようなものはありますか?また、どのようなエラーが表示されますか?gitignoreファイルも確認できますか
Srayan Guhathakurta

1
git submodule foreach git pull origin masterフェッチしたいブランチを追加する必要がありました。それ以外は、完全に機能しました。
締め付け

3

私は上記のgahooa答えを適応させることでこれを行いました:

gitと統合して[alias]...

親プロジェクトに次のようなものがある場合.gitmodules

[submodule "opt/submodules/solarized"]
    path = opt/submodules/solarized
    url = git@github.com:altercation/solarized.git
[submodule "opt/submodules/intellij-colors-solarized"]
    path = opt/submodules/intellij-colors-solarized
    url = git@github.com:jkaving/intellij-colors-solarized.git

.gitconfig内にこのようなものを追加してください

[alias]
    updatesubs = "!sh -c \"git submodule init && git submodule update && git submodule status\" "

次に、サブモジュールを更新するには、次のコマンドを実行します。

git updatesubs

私の環境設定リポジトリにその例があります


3

あとは簡単です git checkout

このグローバル設定を介して有効にしてください: git config --global submodule.recurse true


2

以下は、サブモジュールであるかどうかに関係なく、すべてのgitリポジトリから取得するコマンドラインです。

ROOT=$(git rev-parse --show-toplevel 2> /dev/null)
find "$ROOT" -name .git -type d -execdir git pull -v ';'

あなたは、トップのgitリポジトリでそれを実行している場合は、交換することができます"$ROOT".


1

これを行うには、スクリプトを作成する必要があると思います。正直に言うと、Pythonをインストールos.walkcdて各ディレクトリに移動し、適切なコマンドを発行できるようにするかもしれません。Pythonなど、バッチ以外のスクリプト言語を使用すると、スクリプトを変更せずにサブプロジェクトを簡単に追加/削除できます。


1

備考:あまり簡単な方法ではありませんが、実行可能であり、独自の独自の長所があります。

HEADリポジトリのリビジョンとHEADそのすべてのサブモジュールのs のみを複製する場合(つまり、「トランク」をチェックアウトする場合)、次のLuaスクリプトを使用できます。単純なコマンドを実行git submodule update --init --recursive --remote --no-fetch --depth=1すると、回復不可能なgitエラーが発生する場合があります。この場合、ディレクトリのサブディレクトリをクリーンアップ.git/modulesし、git clone --separate-git-dirコマンドを使用してサブモジュールを手動で複製する必要があります。唯一の複雑さは、スーパープロジェクトツリーでURL.gitサブモジュールのディレクトリのパス、サブモジュールのパスを見つけることです。

備考:スクリプトはhttps://github.com/boostorg/boost.gitリポジトリに対してのみテストされます。その特徴:同じホストでホストされているすべてのサブモジュールと、.gitmodules相対URLのみが含まれています

-- mkdir boost ; cd boost ; lua ../git-submodules-clone-HEAD.lua https://github.com/boostorg/boost.git .
local module_url = arg[1] or 'https://github.com/boostorg/boost.git'
local module = arg[2] or module_url:match('.+/([_%d%a]+)%.git')
local branch = arg[3] or 'master'
function execute(command)
    print('# ' .. command)
    return os.execute(command)
end
-- execute('rm -rf ' .. module)
if not execute('git clone --single-branch --branch master --depth=1 ' .. module_url .. ' ' .. module) then
    io.stderr:write('can\'t clone repository from ' .. module_url .. ' to ' .. module .. '\n')
    return 1
end
-- cd $module ; git submodule update --init --recursive --remote --no-fetch --depth=1
execute('mkdir -p ' .. module .. '/.git/modules')
assert(io.input(module .. '/.gitmodules'))
local lines = {}
for line in io.lines() do
    table.insert(lines, line)
end
local submodule
local path
local submodule_url
for _, line in ipairs(lines) do
    local submodule_ = line:match('^%[submodule %"([_%d%a]-)%"%]$')
    if submodule_ then
        submodule = submodule_
        path = nil
        submodule_url = nil
    else
        local path_ = line:match('^%s*path = (.+)$')
        if path_ then
            path = path_
        else
            submodule_url = line:match('^%s*url = (.+)$')
        end
        if submodule and path and submodule_url then
            -- execute('rm -rf ' .. path)
            local git_dir = module .. '/.git/modules/' .. path:match('^.-/(.+)$')
            -- execute('rm -rf ' .. git_dir)
            execute('mkdir -p $(dirname "' .. git_dir .. '")')
            if not execute('git clone --depth=1 --single-branch --branch=' .. branch .. ' --separate-git-dir ' .. git_dir .. ' ' .. module_url .. '/' .. submodule_url .. ' ' .. module .. '/' .. path) then
                io.stderr:write('can\'t clone submodule ' .. submodule .. '\n')
                return 1
            end
            path = nil
            submodule_url = nil
        end
    end
end
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.