373 Stimmen

Auflisten von Untermodulen in einem Git-Repository

Ich habe ein Git-Repository, das mehrere Untermodule enthält. Wie liste ich die Namen aller Untermodule nach git submodule init durchgeführt wurde?

En git submodule foreach Befehl könnte die Namen der Submodule ausgeben, aber das funktioniert nur, wenn sie ausgecheckt wurden, was nach dem init-Schritt noch nicht geschehen ist. Es gibt weitere Schritte in der Kette, die stattfinden müssen, bevor sie ausgecheckt werden können, und ich möchte die Namen der Submodule nicht fest in das Skript einbauen müssen.

Gibt es also einen Git-Befehl, um die Namen aller derzeit registrierten, aber noch nicht ausgecheckten Submodule zu erhalten?

5voto

Caio Almeida Punkte 246

Nur eine einfache Liste von Submodulen:

git submodule--helper list | cut -d$'\t' -f 2

5voto

eQ19 Punkte 8782

Nehmen wir an, Sie haben alle derzeit registrierten, aber noch nicht ausgecheckten Submodule wie unten:

$ cat .gitmodules
[submodule ".github/workflows/packages"]
        path = .github/workflows/packages
        url = https://github.com/MarketLeader/Packages
[submodule ".github/workflows/builders"]
        path = .github/workflows/builders
        url = https://github.com/chetabahana/runner
[submodule "docs"]
        path = docs
        url = https://github.com/eq19/lexer

Hier ist der Git-Befehl, um auf die Wurzel des Repositorys :

$ git submodule foreach -q '[[ "$sm_path" == */* ]] || git config remote.origin.url'
https://github.com/eq19/lexer

Und hier ist der Git-Befehl, um die Liste auf einer spezifischer Pfad :

$ git submodule foreach -q '[[ ! "$sm_path" == .github/* ]] || git config remote.origin.url'
https://github.com/chetabahana/runner
https://github.com/MarketLeader/Packages

Natürlich können Sie die git config remote.origin.url nach Belieben mit anderen Befehlen kombinieren.

Übrigens verwende ich Git Version 2.38.1

get the names of allsubmodules

4voto

Ente Punkte 2125

In meiner Version von Git [1] hat jedes Git-Submodul eine name und eine path . Sie müssen nicht unbedingt dieselben sein [2] . Beides auf verlässliche Weise zu bekommen, ohne vorher die Submodule zu überprüfen ( git update --init ), ist eine knifflige Angelegenheit der Shell-Zauberei.

Eine Liste von Submodulen erhalten names

Ich habe keine Möglichkeit gefunden, wie man dies mit git config oder jede andere git Befehl. Damit sind wir wieder bei Regex auf .gitmodules (superhässlich). Aber es scheint einigermaßen sicher zu sein, da git begrenzt den für Submodule zulässigen Codebereich names . Da Sie diese Liste wahrscheinlich für die weitere Verarbeitung in der Shell verwenden wollen, wird die folgende Lösung die Einträge mit 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"

Und in Ihrem Drehbuch:

#!/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 '' erfordert bash und wird nicht funktionieren mit sh .

Eine Liste von Submodulen erhalten paths

In meinem Ansatz versuche ich no zur Verarbeitung der Ausgabe von git config --get-regexp con awk , tr , sed , ... sondern übergibt ihm stattdessen ein Null-Byte getrennt zurück an git config --get . Dies dient dazu, Probleme mit Zeilenumbrüchen, Leerzeichen und anderen Sonderzeichen (z. B. Unicode) im Submodul zu vermeiden paths . Da Sie diese Liste wahrscheinlich für die weitere Verarbeitung in der Shell verwenden möchten, wird die folgende Lösung die Einträge mit NULL -Bytes ( \0 ).

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

In einem Bash-Skript könnten Sie zum Beispiel dann:

#!/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 '' erfordert bash und wird nicht funktionieren mit sh .


Fußnoten

[1] Git-Version

$ git --version
git version 2.22.0

[2] Submodul mit divergierender name y path

Test-Repository einrichten:

$ 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 = ./

Submodul nach make verschieben name y path divergieren:

$ 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

Prüfung

Test-Repository einrichten:

$ 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 = ./

Liste der Submodule abrufen 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

Liste der Submodule abrufen 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

1voto

MrSwed Punkte 471

Wenn es keine gibt .gitmodules Datei, aber eine Submodulkonfiguration existiert in .git/modules/ :

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

1voto

So erhalten Sie den Pfad

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

So erhalten Sie Namen wie in Repos

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X