У моїй версії Git [1] кожен підмодуль Git має a nameі a path. Вони не обов'язково повинні бути однаковими [2] . Отримання обох надійним способом, не перевіряючи підмодулі спочатку ( git update --init), є хитрою майстерністю роботи оболонки.
Отримайте список підмодуля names
Я не знайшов способу досягти цього за допомогою git configбудь-якої іншої gitкоманди. Тому ми знову повертаємось до регулярного вираження .gitmodules(супер некрасиво). Але це здається дещо безпечним, оскільки 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
У моєму підході я намагаюся НЕ обробляти вихід з git config --get-regexpз awk, tr, sed, ... , але замість того, щоб передати його нульові байти відокремленими назад git config --get. Це дозволяє уникнути проблем з новими рядками, пробілами та іншими спеціальними символами (наприклад, Unicode) в підмодулі 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] Підмодуль з розбіжними nameіpath
Налаштування тестового сховища:
$ 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 = ./
Перемістіть підмодуль для створення nameта pathрозходження:
$ 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
git submoduleведе себе так, як я очікував, що гіпотетичноgit submodule listповодитись - я просто ніколи не думав перевіряти, що відбувається без аргументівgit submodule. (Радий, що я перевірив це посилання, оскільки спочатку я схопив неправильне посилання "Поділитися")