web-dev-qa-db-ja.com

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

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

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

1535
Brad Robinson

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

あなたがサブモジュールを最新のコミットに引っ張りたいなら、リポジトリが指しているものの代わりに。

注: 初めての場合 リポジトリをチェックアウトする場合は、最初に--initを使用する必要があります。

git submodule update --init --recursive

より古い、git 1.6.1 またはそれ以上のものに似たものを使うことができます(それに合うように修正されています):

git submodule foreach git pull Origin master

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

2012

サブモジュール用のものをサブモジュールリポジトリに引き込む必要がある場合

git pull --recurse-submodules

1.7.3で初めて学んだ機能git。

しかし、これはサブモジュール内の適切なコミット(あなたのマスターリポジトリが指すもの)をチェックアウトしません。

サブモジュール内の適切なコミットをチェックアウトするには、を使って引っ張った後にそれらを更新する必要があります。

git submodule update --recursive --remote
584

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ディレクトリの中から、私にとっては最もうまくいきます。

これはサブモジュールを含むすべての最新のものを引っ張ります。

説明済み

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.
            any submodule locations.
            --recursive is specified, this command will recurse into the registered
            submodules, and update any nested submodules within.
341
abc123

注:これは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. リストされたそれぞれのリポジトリについて、そのディレクトリに移動してgit checkout master && git pullを実行します。エラーを確認してください。
  3. 最後に、サブモジュールの現在の状態を示すためにユーザーに表示を印刷することをお勧めします - おそらく、すべてを追加してコミットするように促しますか?

私はこのスタイルがgitサブモジュールのために設計されたものではないことに言及したいと思います。通常、 "LibraryX"はバージョン "2.32"であり、 "upgrade"を指示するまでそのままにします。

つまり、ある意味では、記述されているスクリプトを使用していますが、もっと自動的に行われています。注意が必要です!

更新2:

Windowsプラットフォームを使用している場合は、スクリプトを実装するためにPythonを使用することを検討するとよいでしょう。あなたがunix/linuxを使っているならば、私はただbashスクリプトを提案します。

明確化が必要ですか?コメントを投稿するだけです。

301
gahooa

ヘンリックは正しい方向に進んでいます。 'foreach'コマンドは任意のシェルスクリプトを実行することができます。最新のものを引き出すための2つの選択肢は、

git submodule foreach git pull Origin master

そして、

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

それはすべての 初期化 サブモジュールを通して繰り返し、与えられたコマンドを実行します。

153
mturquette

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

git submodule init
git submodule update
142
zachleat

編集

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

git submodule foreach --recursive git pull

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

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

git submodule update --init

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

編集:

私はあなたが使用できることをちょうど見つけました:

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

これはまたすべてのサブモジュール、すなわち依存性を再帰的に引っ張ります。

33
antitoxic

サブモジュールのデフォルトのブランチが not 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'
31

初めて

クローン作成モジュールと初期化サブモジュール

git clone [email protected]:speedovation/kiwi-resources.git resources
git submodule init

残り

開発中はサブモジュールを引っ張って更新するだけです

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

GitサブモジュールをOriginの最新のコミットに更新

git submodule foreach git pull Origin master

好ましい方法は下記の通りです

git submodule update --remote --merge

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

25
Yash

どのバージョンのgitが動いているのか私は知りませんが、それがあなたが探しているものです:

git submodule update --recursive

私はgit pullと共にそれを使ってルートリポジトリも更新します。

git pull && git submodule update --recursive
18
Jens Kohl
6
jerico.dev

Windows用Git 2.6.3

git submodule update --rebase --remote

4
seoul

私は gahooa s 上記の答えを適用することによってこれを行いました

Git [alias]と統合してください。 

あなたの親プロジェクトが.gitmodulesにこのようなものがあるならば:

[submodule "opt/submodules/solarized"]
    path = opt/submodules/solarized
    url = [email protected]:altercation/solarized.git
[submodule "opt/submodules/intellij-colors-solarized"]
    path = opt/submodules/intellij-colors-solarized
    url = [email protected]:jkaving/intellij-colors-solarized.git

あなたの.gitconfigの中にこのようなものを追加してください。

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

それからサブモジュールを更新するために、実行してください。

git updatesubs

環境設定リポジトリ - に example があります。

3
Tom

上記の答えは良いですが、これを容易にするためにgit-hooksを使用していましたが、 git 2.14 では git config submodule.recurse をtrueに設定してサブモジュールを更新することができます。あなたのgitリポジトリに移動してください。

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

を使用して行うことができます:

git config submodule.recurse true
3
JamesD

サブモジュールかどうかに関わらず、すべてのgitリポジトリから取得するコマンドラインは次のとおりです。

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

あなたのtop gitリポジトリでそれを実行しているなら、"$ROOT".に置き換えることができます。

2
kenorb

リポジトリのトップレベルから: gitサブモジュールforeach git checkout development gitサブモジュールforeach

これはすべてのブランチを開発し最新のものにするために切り替えます

1

注:それほど簡単な方法ではありませんが、実行可能で、独自の独自の長所があります。

リポジトリのHEADリビジョンとそのすべてのサブモジュールのHEADsだけをクローンしたい(すなわち、 "trunk"をチェックアウトする)場合は、次の Lua scriptを使用できます。単純なコマンド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 _ sだけを含んでいます。

-- 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
1
Orient

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

1
baudtack

今必要なのは単純なgit checkoutだけです

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

1
Pellet