web-dev-qa-db-ja.com

Gitリポジトリ内のサブモジュールを一覧表示する

私はそれにいくつかのサブモジュールがあるGitリポジトリを持っています。 git submodule initが実行された後にすべてのサブモジュールの名前をリストするにはどうすればいいですか?

git submodule foreachコマンドはサブモジュールの名前をエコーすることができます、しかしそれはそれらがチェックアウトされた後にだけうまくいきます、そしてそれはinitステップの後に起こりませんでした。チェックアウトする前に実行する必要があるチェーン内のステップは他にもあります。サブモジュールの名前をスクリプトにハードワイヤリングする必要はありません。

では、現在登録されているがまだチェックアウトされていないサブモジュールすべての名前を取得するGitコマンドはありますか?

183
tpg2114

あなたはgit submodule initがそれ自身を使うのと同じメカニズム、すなわち.gitmodulesを見てください。このファイルは各サブモジュールパスとそれが参照するURLを列挙します。

たとえば、リポジトリのルートから、cat .gitmodulesは内容を画面に表示します(catがあると仮定します)。

.gitmoduleファイルはGit設定フォーマットを持っているので、git configを使ってそれらのファイルを解析することができます。

git config --file .gitmodules --name-only --get-regexp path

すべてのサブモジュールエントリを表示します。

git config --file .gitmodules --get-regexp path | awk '{ print $2 }'

サブモジュールパス自体を取得するだけです。

126
Ikke

入れ子になったサブモジュールを表示したい場合は、git submodule statusまたはオプションでgit submodule status --recursiveを使用できます。

GIT SCMのドキュメントから:

サブモジュールのステータスを表示します。これは、サブモジュールパスとSHA-1のgit describeの出力とともに、各サブモジュールの現在チェックアウトされているコミットのSHA-1を出力します。各SHA-1には、サブモジュールが初期化されていない場合は - 、現在チェックアウトされているサブモジュールのコミットが含まれるリポジトリのインデックスで見つかったSHA-1と一致しない場合は+、サブモジュールにマージ競合がある場合はUが付きます。

74
Jon Koops

登録されているサブモジュールの名前だけを返すには、次のコマンドを使います。

grep path .gitmodules | sed 's/.*= //'

存在しないgit submodule --listと考えてください。

58
mholm815

次のコマンドはサブモジュールを一覧表示します。

git submodule--helper list

出力は次のようになります。

<mode> <sha1> <stage> <location>

注:git 2.7.0以上が必要です。

47
A.T.

私は答えが選択されているのを見ることができます、しかし、このページにたどり着く他の誰かのために:

$ git submodule

指定されたgitリポジトリ内のすべてのサブモジュールを一覧表示します。

乾杯

18
Sandeep Gill

私はこれを使う:

git config --list|egrep ^submodule
16
Robert Sjödahl

私はこの質問に対する答えで提供されたコマンドが私が探していた情報を与えてくれたことに気づいた:

サブモジュールではないパスの.gitmoduleにサブモジュールマッピングが見つかりません

git ls-files --stage | grep 160000
16
Max Cantor

あなたが使用することができます:

git submodule | awk '{ print $2 }'
9
fabceolin

初期化されたサブモジュールだけで操作しても構わない場合は、テキストの解析を避けるためにgit submodule foreachを使用できます。

git submodule foreach --quiet 'echo $name'
9
benesch

私はこれを使う:

git submodule status | cut -d' ' -f3-4 

出力(パス+バージョン):

tools/deploy_utils (0.2.4)
8
Skarab

すべてのサブモジュールを名前で一覧表示するには

git submodule --quiet foreach --recursive 'echo $name'

7
bGorle

これは私のために働いた:

git ls-files --stage | grep ^160000

この素晴らしい記事に基づくと、 http://www.speirs.org/blog/2009/5/11/understanding-git-submodules.html

編集:それはgrep ^160000を読む必要があります

7
LTK

git config 設定ファイルを指定することができます。
そして.gitmodules設定ファイルです。

それで、 " cutコマンドではスペースを区切り文字として使う "の助けを借りて:

git config --file=.gitmodules --get-regexp ^^submodule.*\.path$ | cut -d " " -f 2

これは、宣言されたサブモジュールごとに1つのパスだけをリストします。

として ティノ 指摘 コメント内

  • スペースが含まれているサブモジュールでは失敗します。
  • サブモジュールパスには、改行を含めることができます。

    git submodule add https://github.com/hilbix/bashy.git "sub module"
      git mv 'sub module' $'sub\nmodule'
    

より堅牢な代替手段として、Tinoは次のように提案します。

git config -z --file .gitmodules --get-regexp '\.path$' | \
  sed -nz 's/^[^\n]*\n//p' | \
  tr '\0' '\n' 

改行を含むパス(git mvで作成することができます)については、| tr '\0' '\n'を省略し、bashでさらに処理するために... | while IFS='' read -d '' path; do ...のようなものを使用してください。
これはread -d ''を理解する最新のbashが必要です(-d and ''の間のスペースを忘れないでください)。

5
VonC

ただサブモジュールパスどうぞ、奥さん...

git config --list | grep \^submodule | cut -f 2 -d .
Vendor/BaseModel
Vendor/ObjectMatcher
Vendor/OrderedDictionary
Vendor/_ObjC
Vendor/XCodeHelpers

????????

5
Alex Gray

私のバージョンのgit [1]、すべてのgitサブモジュールにはnamepathがあります。必ずしも同じである必要はありません [2]。最初にサブモジュール(git update --init)をチェックアウトせずに両方を信頼できる方法で取得することは、シェルウィザードのややこしい作業です。

サブモジュールnamesのリストを取得します

git configまたは他のgitコマンドを使用してこれを実現する方法が見つかりませんでした。したがって、.gitmodules(非常にexい)の正規表現に戻ります。ただし、gitは、サブモジュールnamesに許可されるコードスペースを制限するため、多少安全であるようです。さらに、おそらくこのリストをシェルのさらなる処理に使用する必要があるため、以下のソリューションでは、エントリをNULL- bytes(\0)で区切ります。

$ sed -nre \
  's/^\[submodule \"(.*)\"]$/\1\x0/p' \
  "$(git rev-parse --show-toplevel)/.gitmodules" \
| tr -d '\n' \
| xargs -0 -n1 printf "%b\0"

そしてあなたのスクリプトで:

#!/usr/bin/env bash

while IFS= read -rd '' submodule_name; do
 echo submodule name: "${submodule_name}"
done < <(
  sed -nre \
    's/^\[submodule \"(.*)\"]$/\1\x0/p' \
    "$(git rev-parse --show-toplevel)/.gitmodules" \
  | tr -d '\n' \
  | xargs -0 -n1 printf "%b\0"
)

read -rd ''にはbashが必要で、shでは動作しません

サブモジュールpathsのリストを取得します

私のアプローチでは、notを試してgit config --get-regexpからの出力をawktrsedで処理しますが、代わりにゼロを渡しますgit config --getに分離されたバイト。これは、サブモジュールpaths内の改行、スペース、およびその他の特殊文字(ユニコードなど)に関する問題を回避するためです。さらに、おそらくこのリストをシェルのさらなる処理に使用する必要があるため、以下のソリューションでは、エントリをNULL- bytes(\0)で区切ります。

$ git config --null --file .gitmodules --name-only --get-regexp '\.path$' \
| xargs -0 -n1 git config --null --file .gitmodules --get

たとえば、bashスクリプトでは次のことができます。

#!/usr/bin/env bash

while IFS= read -rd '' submodule_path; do
 echo submodule path: "${submodule_path}"
done < <(
  git config --null --file .gitmodules --name-only --get-regexp '\.path$' \
  | xargs -0 -n1 git config --null --file .gitmodules --get
)

read -rd ''にはbashが必要で、shでは動作しません


脚注

[1] gitバージョン

$ git --version
git version 2.22.0

[2] namepathが異なるサブモジュール

テストリポジトリを設定します。

$ git init test-name-path
$ cd test-name-path/
$ git checkout -b master
$ git commit --allow-empty -m 'test'
$ git submodule add ./ submodule-name
Cloning into '/tmp/test-name-path/submodule-name'...
done.
$ ls
submodule-name

$ cat .gitmodules 
[submodule "submodule-name"]
    path = submodule-name
    url = ./

サブモジュールを移動して、namepathを分岐させます:

$ git mv submodule-name/ submodule-path

$ ls
submodule-path

$ cat .gitmodules 
[submodule "submodule-name"]
    path = submodule-path
    url = ./

$ git config --file .gitmodules --get-regexp '\.path$'
submodule.submodule-name.path submodule-path

テスト中

テストリポジトリを設定します。

$ git init test
$ cd test/
$ git checkout -b master
$ git commit --allow-empty -m 'test'
$
$ git submodule add ./ simplename
Cloning into '/tmp/test/simplename'...
done.
$
$ git submodule add ./ 'name with spaces'
Cloning into '/tmp/test/name with spaces'...
done.
$
$ git submodule add ./ 'future-name-with-newlines'
Cloning into '/tmp/test/future-name-with-newlines'...
done.
$ git mv future-name-with-newlines/ 'name
> with
> newlines'
$
$ git submodule add ./ 'name-with-unicode-????'
Cloning into '/tmp/test/name-with-unicode-????'...
done.
$
$ git submodule add ./ sub/folder/submodule
Cloning into '/tmp/test/sub/folder/submodule'...
done.
$
$ git submodule add ./ name.with.dots
Cloning into '/tmp/test/name.with.dots'...
done.
$
$ git submodule add ./ 'name"with"double"quotes'
Cloning into '/tmp/test/name"with"double"quotes'...
done.
$
$ git submodule add ./ "name'with'single'quotes"
Cloning into '/tmp/test/name'with'single'quotes''...
done.
$ git submodule add ./ 'name]with[brackets'
Cloning into '/tmp/test/name]with[brackets'...
done.
$ git submodule add ./ 'name-with-.path'
Cloning into '/tmp/test/name-with-.path'...
done.

.gitmodules

[submodule "simplename"]
    path = simplename
    url = ./
[submodule "name with spaces"]
    path = name with spaces
    url = ./
[submodule "future-name-with-newlines"]
    path = name\nwith\nnewlines
    url = ./
[submodule "name-with-unicode-????"]
    path = name-with-unicode-????
    url = ./
[submodule "sub/folder/submodule"]
    path = sub/folder/submodule
    url = ./
[submodule "name.with.dots"]
    path = name.with.dots
    url = ./
[submodule "name\"with\"double\"quotes"]
    path = name\"with\"double\"quotes
    url = ./
[submodule "name'with'single'quotes"]
    path = name'with'single'quotes
    url = ./
[submodule "name]with[brackets"]
    path = name]with[brackets
    url = ./
[submodule "name-with-.path"]
    path = name-with-.path
    url = ./

サブモジュールのリストを取得names

$ sed -nre \
  's/^\[submodule \"(.*)\"]$/\1\x0/p' \
  "$(git rev-parse --show-toplevel)/.gitmodules" \
| tr -d '\n' \
| xargs -0 -n1 printf "%b\0" \
| xargs -0 -n1 echo submodule name:
submodule name: simplename
submodule name: name with spaces
submodule name: future-name-with-newlines
submodule name: name-with-unicode-????
submodule name: sub/folder/submodule
submodule name: name.with.dots
submodule name: name"with"double"quotes
submodule name: name'with'single'quotes
submodule name: name]with[brackets
submodule name: name-with-.path

サブモジュールのリストを取得paths

$ git config --null --file .gitmodules --name-only --get-regexp '\.path$' \
| xargs -0 -n1 git config --null --file .gitmodules --get \
| xargs -0 -n1 echo submodule path:
submodule path: simplename
submodule path: name with spaces
submodule path: name
with
newlines
submodule path: name-with-unicode-????
submodule path: sub/folder/submodule
submodule path: name.with.dots
submodule path: name"with"double"quotes
submodule path: name'with'single'quotes
submodule path: name]with[brackets
submodule path: name-with-.path
1
Ente

.gitmodulesがなく、submodules configが.git/modules /に存在する場合

find .git/modules/ -name config -exec grep url {} \;
0
MrSwed

Sedまたは派手なIFS設定を必要とせずに、.gitmodulesからgitサブモジュール名を解析する別の方法を次に示します。 :-)

#!/bin/env bash

function stripStartAndEndQuotes {
  temp="${1%\"}"
  temp="${temp#\"}"
  echo "$temp"
}

function getSubmoduleNames {
  line=$1
  len=${#line} # get line length
  stripStartAndEndQuotes "${line::len-1}" # remove last character
}

while read line; do
  getSubmoduleNames "$line"
done < <(cat .gitmodules | grep "\[submodule.*\]" | cut -d ' ' -f 2-)
0
devC0de