Files
git_man/register-submodules.sh
T
mk aa5052f073 Обновить register-submodules.sh
## 📋 Новые опции в скрипте

| Опция | Описание |
|-------|----------|
| `--ignore=MODE` | Установить режим игнорирования для ВСЕХ подмодулей |
| `--ignore-submodule PATH:MODE` | Установить режим для конкретного подмодуля |
| `--remove-ignore` | Удалить все настройки игнорирования |

### Режимы игнорирования (`MODE`)

| Режим | Что делает |
|-------|------------|
| `all` | Полностью скрывает изменения в подмодулях (не показывает ничего) |
| `dirty` | Скрывает только изменения в файлах подмодуля |
| `untracked` | Скрывает только неотслеживаемые файлы в подмодуле |
| `none` | Показывает все изменения (поведение по умолчанию) |

---

## 📝 Примеры использования

```bash
# 1. Регистрация с игнорированием всех изменений
./register-submodules.sh --ignore=all

# 2. Регистрация с игнорированием только dirty-изменений
./register-submodules.sh --ignore=dirty

# 3. Установить ignore только для конкретного подмодуля
./register-submodules.sh --ignore-submodule tools/cam:dirty

# 4. Удалить все настройки игнорирования
./register-submodules.sh --remove-ignore

# 5. Комбинация: регистрация + игнорирование
./register-submodules.sh --ignore=all --verbose

# 6. Только обновить ignore для существующих подмодулей
./register-submodules.sh --ignore=dirty --dry-run
```

---

## 📊 Пример вывода

```
============================================================
📦 Регистрация вложенных репозиториев как подмодулей
============================================================

🔧 Режим игнорирования для ВСЕХ подмодулей: all
   → полностью скрывает изменения в подмодулях

▶ Поиск вложенных репозиториев...
 Найдено 15 вложенных репозиториев

▶ Регистрация подмодулей...

 Регистрация: diadoc.ext.rhana
   URL: https://git.p7net.ru/1c/diadoc.ext.rhana.git
 Подмодуль зарегистрирован: diadoc.ext.rhana
 Установлен ignore=all для diadoc.ext.rhana

 Регистрация: tools/cam
   URL: https://git.p7net.ru/tools/cam.git
 Подмодуль зарегистрирован: tools/cam
 Установлен ignore=all для tools/cam

...

============================================================
📊 Статистика
============================================================
   Всего найдено:     15
   Зарегистрировано:  12
   Пропущено:         2
   Без URL:           1

🔧 Режим игнорирования: all
   Файл .gitmodules обновлён

 Подмодули зарегистрированы!

Следующие шаги:
  1. Проверьте изменения:   git status
  2. Посмотрите подмодули:  git submodule status
  3. Закоммитьте изменения: git commit -m "Зарегистрированы все подмодули"
  4. Отправьте на сервер:   git push
============================================================
```

---

## 📄 Структура `.gitmodules` после настройки

```ini
[submodule "diadoc.ext.rhana"]
    path = diadoc.ext.rhana
    url = https://git.p7net.ru/1c/diadoc.ext.rhana.git
    ignore = all

[submodule "tools/cam"]
    path = tools/cam
    url = https://git.p7net.ru/tools/cam.git
    ignore = all
```

Теперь скрипт полностью управляет подмодулями, включая настройку игнорирования их состояния в основном репозитории! 🚀
2026-07-19 08:33:14 +00:00

566 lines
21 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# ============================================================
# register-submodules.sh - Регистрация всех вложенных репозиториев как подмодулей
#
# Автор: Michael BAG <mk@p7net.ru>
# Репозиторий: https://git.p7net.ru/tools/git_man
#
# Использование:
# ./register-submodules.sh [--help] [--dry-run] [--force] [--ignore=all|dirty|untracked|none]
#
# Опции:
# --help, -h Показать эту справку
# --dry-run Только показать, что будет сделано (без изменений)
# --force, -f Принудительно перерегистрировать подмодули
# --ignore=MODE Установить режим игнорирования для всех подмодулей
# all - игнорировать всё (не показывать изменения)
# dirty - игнорировать только изменения в файлах
# untracked - игнорировать только неотслеживаемые файлы
# none - показывать все изменения (по умолчанию)
# --ignore-submodule PATH Установить игнорирование для конкретного подмодуля
# --verbose, -v Подробный вывод
# --quiet, -q Минимальный вывод (только ошибки)
#
# Описание:
# Скрипт находит все вложенные репозитории (папки с .git),
# определяет их URL и регистрирует как подмодули в .gitmodules.
# Также позволяет настроить игнорирование состояния подмодулей.
# ============================================================
set -e # Остановка при ошибке
# ============================================================
# Функция показа справки
# ============================================================
show_help() {
cat << 'EOF'
============================================================
📦 register-submodules.sh - Регистрация вложенных репозиториев
============================================================
ИСПОЛЬЗОВАНИЕ:
./register-submodules.sh [ОПЦИИ]
ОПЦИИ:
--help, -h Показать эту справку
--dry-run Только показать, что будет сделано (без изменений)
--force, -f Принудительно перерегистрировать подмодули
(удаляет существующие и создаёт заново)
--ignore=MODE Установить режим игнорирования для ВСЕХ подмодулей
all - игнорировать всё (полностью скрыть изменения)
dirty - игнорировать только изменения в файлах
untracked - игнорировать только неотслеживаемые файлы
none - показывать все изменения (по умолчанию)
--ignore-submodule PATH:MODE Установить режим для конкретного подмодуля
Пример: --ignore-submodule tools/cam:dirty
--remove-ignore Удалить все настройки игнорирования из .gitmodules
--verbose, -v Подробный вывод
--quiet, -q Минимальный вывод (только ошибки)
ПРИМЕРЫ:
# Базовая регистрация
./register-submodules.sh
# Регистрация с игнорированием всех изменений в подмодулях
./register-submodules.sh --ignore=all
# Регистрация с игнорированием только dirty-изменений
./register-submodules.sh --ignore=dirty
# Удалить все настройки игнорирования
./register-submodules.sh --remove-ignore
# Установить ignore только для конкретного подмодуля
./register-submodules.sh --ignore-submodule tools/cam:dirty
# Просмотр без изменений
./register-submodules.sh --dry-run --ignore=all
============================================================
EOF
exit 0
}
# ============================================================
# Инициализация переменных
# ============================================================
DRY_RUN=false
FORCE=false
VERBOSE=false
QUIET=false
REMOVE_IGNORE=false
IGNORE_MODE=""
IGNORE_SUBMODULE=""
# ============================================================
# Разбор аргументов командной строки
# ============================================================
while [[ $# -gt 0 ]]; do
case $1 in
--help|-h)
show_help
;;
--dry-run)
DRY_RUN=true
shift
;;
--force|-f)
FORCE=true
shift
;;
--verbose|-v)
VERBOSE=true
shift
;;
--quiet|-q)
QUIET=true
shift
;;
--remove-ignore)
REMOVE_IGNORE=true
shift
;;
--ignore=*)
IGNORE_MODE="${1#*=}"
shift
;;
--ignore-submodule=*)
IGNORE_SUBMODULE="${1#*=}"
shift
;;
*)
echo -e "\033[0;31m❌ Неизвестная опция: $1\033[0m"
echo " Используйте --help для справки"
exit 1
;;
esac
done
# ============================================================
# Настройка вывода
# ============================================================
if [ "$QUIET" = true ]; then
exec 3>&1
exec >/dev/null 2>&1
fi
# Цвета для вывода
if [ "$QUIET" != true ]; then
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
MAGENTA='\033[0;35m'
NC='\033[0m'
else
RED=''; GREEN=''; YELLOW=''; BLUE=''; CYAN=''; MAGENTA=''; NC=''
fi
# Функции логирования
log_info() {
if [ "$QUIET" != true ]; then
echo -e "${CYAN}$1${NC}"
fi
}
log_success() {
if [ "$QUIET" != true ]; then
echo -e "${GREEN}$1${NC}"
fi
}
log_warning() {
if [ "$QUIET" != true ]; then
echo -e "${YELLOW}⚠️ $1${NC}"
fi
}
log_error() {
echo -e "${RED}$1${NC}" >&2
}
log_debug() {
if [ "$VERBOSE" = true ] && [ "$QUIET" != true ]; then
echo -e "${BLUE}🔍 $1${NC}"
fi
}
log_step() {
if [ "$QUIET" != true ]; then
echo -e "${MAGENTA}$1${NC}"
fi
}
# ============================================================
# Проверка окружения
# ============================================================
log_step "Проверка окружения..."
if [ ! -d ".git" ]; then
log_error "Текущая папка не является Git-репозиторием"
echo " Запустите скрипт из корня основного репозитория" >&2
exit 1
fi
if ! command -v git &> /dev/null; then
log_error "Git не установлен"
exit 1
fi
log_success "Окружение проверено"
# ============================================================
# Функция установки ignore для подмодуля
# ============================================================
set_submodule_ignore() {
local path="$1"
local mode="$2"
if [ "$DRY_RUN" = true ]; then
echo " [DRY-RUN] git config --file .gitmodules submodule.$path.ignore $mode"
return 0
fi
git config --file .gitmodules "submodule.$path.ignore" "$mode" 2>/dev/null
return $?
}
# ============================================================
# Функция удаления ignore для подмодуля
# ============================================================
remove_submodule_ignore() {
local path="$1"
if [ "$DRY_RUN" = true ]; then
echo " [DRY-RUN] git config --file .gitmodules --unset submodule.$path.ignore"
return 0
fi
git config --file .gitmodules --unset "submodule.$path.ignore" 2>/dev/null
return $?
}
# ============================================================
# Функция регистрации подмодуля
# ============================================================
register_submodule() {
local repo="$1"
local url="$2"
if [ "$DRY_RUN" = true ]; then
echo " [DRY-RUN] git submodule add $url $repo"
return 0
fi
if [ "$FORCE" = true ]; then
git config --remove-section "submodule.$repo" 2>/dev/null || true
git config --file .gitmodules --remove-section "submodule.$repo" 2>/dev/null || true
if [ -d "$repo" ] && [ -z "$(ls -A "$repo" 2>/dev/null)" ]; then
rm -rf "$repo"
fi
fi
if git config --file .gitmodules --get "submodule.$repo.url" >/dev/null 2>&1; then
log_debug "Подмодуль $repo уже зарегистрирован"
return 2
fi
git submodule add "$url" "$repo" 2>/dev/null
return $?
}
# ============================================================
# Информация о режиме работы
# ============================================================
if [ "$QUIET" != true ]; then
echo ""
echo "============================================================"
echo "📦 Регистрация вложенных репозиториев как подмодулей"
echo "============================================================"
echo ""
if [ "$DRY_RUN" = true ]; then
echo -e "${YELLOW}⚠️ РЕЖИМ ПРОСМОТРА (--dry-run) — изменения НЕ будут применены${NC}"
echo ""
fi
if [ "$FORCE" = true ]; then
echo -e "${YELLOW}⚠️ РЕЖИМ ПРИНУДИТЕЛЬНОЙ ПЕРЕРЕГИСТРАЦИИ (--force)${NC}"
echo ""
fi
if [ -n "$IGNORE_MODE" ]; then
echo -e "${CYAN}🔧 Режим игнорирования для ВСЕХ подмодулей: ${MAGENTA}$IGNORE_MODE${NC}"
case "$IGNORE_MODE" in
all) echo " → полностью скрывает изменения в подмодулях" ;;
dirty) echo " → скрывает только изменения в файлах" ;;
untracked) echo " → скрывает только неотслеживаемые файлы" ;;
none) echo " → показывает все изменения (по умолчанию)" ;;
*) log_warning "Неизвестный режим: $IGNORE_MODE. Используйте: all, dirty, untracked, none" ;;
esac
echo ""
fi
if [ -n "$IGNORE_SUBMODULE" ]; then
echo -e "${CYAN}🔧 Режим игнорирования для конкретного подмодуля: ${MAGENTA}$IGNORE_SUBMODULE${NC}"
echo ""
fi
if [ "$REMOVE_IGNORE" = true ]; then
echo -e "${YELLOW}🔧 Удаление всех настроек игнорирования из .gitmodules${NC}"
echo ""
fi
fi
# ============================================================
# Удаление настроек игнорирования (если указано)
# ============================================================
if [ "$REMOVE_IGNORE" = true ]; then
log_step "Удаление настроек игнорирования..."
if [ -f ".gitmodules" ]; then
# Найти все секции подмодулей
sections=$(git config --file .gitmodules --name-only --get-regexp "submodule\..*\.ignore" 2>/dev/null | cut -d. -f1-2 | sort -u)
if [ -n "$sections" ]; then
for section in $sections; do
if [ "$DRY_RUN" = true ]; then
echo " [DRY-RUN] git config --file .gitmodules --unset $section.ignore"
else
git config --file .gitmodules --unset "$section.ignore" 2>/dev/null
log_success "Удалён ignore для: $section"
fi
done
else
log_info "Нет настроек игнорирования для удаления"
fi
if [ "$DRY_RUN" = false ] && [ -s ".gitmodules" ]; then
git add .gitmodules 2>/dev/null || true
log_success "Изменения добавлены в индекс"
fi
else
log_warning "Файл .gitmodules не существует"
fi
if [ "$QUIET" != true ]; then
echo ""
echo -e "${GREEN}✅ Настройки игнорирования удалены${NC}"
echo ""
fi
# Если только удаление — выходим
if [ "$IGNORE_MODE" = "" ] && [ "$IGNORE_SUBMODULE" = "" ] && [ "$FORCE" = false ]; then
exit 0
fi
fi
# ============================================================
# Поиск вложенных репозиториев
# ============================================================
log_step "Поиск вложенных репозиториев..."
TEMP_FILE=$(mktemp)
find . -type d -name ".git" -exec dirname {} \; 2>/dev/null | sort > "$TEMP_FILE"
sed -i '/^\.$/d' "$TEMP_FILE" 2>/dev/null || true
if [ ! -s "$TEMP_FILE" ]; then
log_warning "Вложенные репозитории не найдены"
rm -f "$TEMP_FILE"
exit 0
fi
TOTAL=$(wc -l < "$TEMP_FILE" | tr -d ' ')
log_success "Найдено $TOTAL вложенных репозиториев"
if [ "$VERBOSE" = true ]; then
echo ""
echo -e "${CYAN}📋 Список найденных репозиториев:${NC}"
cat "$TEMP_FILE" | while read repo; do
echo " 📁 $repo"
done
echo ""
fi
# ============================================================
# Основной цикл регистрации
# ============================================================
log_step "Регистрация подмодулей..."
REGISTERED=0
SKIPPED=0
ERRORS=0
NO_URL=0
while read repo; do
[ -z "$repo" ] && continue
log_debug "Обработка: $repo"
if [ -d "$repo" ]; then
cd "$repo" 2>/dev/null
if [ $? -ne 0 ]; then
log_error "Не удалось перейти в папку: $repo"
ERRORS=$((ERRORS + 1))
cd - > /dev/null 2>/dev/null || true
continue
fi
url=$(git remote get-url origin 2>/dev/null)
cd - > /dev/null 2>/dev/null || true
if [ -z "$url" ]; then
if [ "$VERBOSE" = true ] || [ "$QUIET" != true ]; then
log_warning "Не удалось определить URL для: $repo (нет remote 'origin')"
fi
NO_URL=$((NO_URL + 1))
continue
fi
else
log_warning "Папка не существует: $repo"
ERRORS=$((ERRORS + 1))
continue
fi
if [ "$QUIET" != true ]; then
echo -e "${GREEN} Регистрация:${NC} $repo"
echo -e " ${CYAN}URL:${NC} $url"
fi
register_submodule "$repo" "$url"
result=$?
case $result in
0)
log_success "Подмодуль зарегистрирован: $repo"
REGISTERED=$((REGISTERED + 1))
# Если задан режим игнорирования для всех подмодулей
if [ -n "$IGNORE_MODE" ]; then
set_submodule_ignore "$repo" "$IGNORE_MODE"
if [ $? -eq 0 ]; then
log_debug "Установлен ignore=$IGNORE_MODE для $repo"
fi
fi
;;
2)
log_debug "Пропущен (уже зарегистрирован): $repo"
SKIPPED=$((SKIPPED + 1))
;;
*)
log_error "Ошибка при регистрации: $repo"
ERRORS=$((ERRORS + 1))
;;
esac
echo ""
done < "$TEMP_FILE"
# ============================================================
# Настройка игнорирования для конкретного подмодуля
# ============================================================
if [ -n "$IGNORE_SUBMODULE" ]; then
# Формат: path:mode
if [[ "$IGNORE_SUBMODULE" =~ ^([^:]+):(.+)$ ]]; then
SUBMODULE_PATH="${BASH_REMATCH[1]}"
SUBMODULE_MODE="${BASH_REMATCH[2]}"
log_step "Настройка игнорирования для: $SUBMODULE_PATH (режим: $SUBMODULE_MODE)"
# Проверить, существует ли такой подмодуль
if git config --file .gitmodules --get "submodule.$SUBMODULE_PATH.url" >/dev/null 2>&1; then
set_submodule_ignore "$SUBMODULE_PATH" "$SUBMODULE_MODE"
if [ $? -eq 0 ]; then
log_success "Установлен ignore=$SUBMODULE_MODE для $SUBMODULE_PATH"
else
log_error "Не удалось установить ignore для $SUBMODULE_PATH"
ERRORS=$((ERRORS + 1))
fi
else
log_warning "Подмодуль $SUBMODULE_PATH не найден в .gitmodules"
fi
else
log_error "Неверный формат для --ignore-submodule. Используйте: path:mode"
log_error "Пример: --ignore-submodule tools/cam:dirty"
ERRORS=$((ERRORS + 1))
fi
echo ""
fi
# ============================================================
# Очистка
# ============================================================
rm -f "$TEMP_FILE"
# ============================================================
# Итоговый вывод
# ============================================================
if [ "$QUIET" != true ]; then
echo ""
echo "============================================================"
echo -e "${CYAN}📊 Статистика${NC}"
echo "============================================================"
echo -e " ${BLUE}Всего найдено:${NC} $TOTAL"
echo -e " ${GREEN}Зарегистрировано:${NC} $REGISTERED"
echo -e " ${YELLOW}Пропущено:${NC} $SKIPPED"
echo -e " ${YELLOW}Без URL:${NC} $NO_URL"
if [ $ERRORS -gt 0 ]; then
echo -e " ${RED}Ошибок:${NC} $ERRORS"
fi
if [ -n "$IGNORE_MODE" ]; then
echo ""
echo -e "${CYAN}🔧 Режим игнорирования:${NC} $IGNORE_MODE"
echo " Файл .gitmodules обновлён"
fi
if [ "$DRY_RUN" = true ]; then
echo ""
echo -e "${YELLOW}⚠️ Это был просмотр (--dry-run). Изменения НЕ применены.${NC}"
echo " Уберите --dry-run для выполнения."
fi
echo ""
fi
# ============================================================
# Следующие шаги
# ============================================================
if [ "$DRY_RUN" = false ] && [ $REGISTERED -gt 0 ]; then
if [ "$QUIET" != true ]; then
echo -e "${GREEN}✅ Подмодули зарегистрированы!${NC}"
echo ""
echo -e "${CYAN}Следующие шаги:${NC}"
echo " 1. Проверьте изменения: git status"
echo " 2. Посмотрите подмодули: git submodule status"
echo " 3. Закоммитьте изменения: git commit -m \"Зарегистрированы все подмодули\""
echo " 4. Отправьте на сервер: git push"
echo ""
echo -e "${YELLOW}⚠️ При первом клонировании выполните:${NC}"
echo " git submodule update --init --recursive"
echo ""
fi
elif [ "$DRY_RUN" = false ] && [ -n "$IGNORE_MODE" ]; then
if [ "$QUIET" != true ]; then
echo -e "${GREEN}✅ Настройки игнорирования обновлены!${NC}"
echo ""
echo -e "${CYAN}Следующие шаги:${NC}"
echo " 1. Проверьте изменения: git status"
echo " 2. Закоммитьте изменения: git commit -m \"Настроен ignore для подмодулей\""
echo " 3. Отправьте на сервер: git push"
echo ""
fi
fi
if [ "$QUIET" != true ]; then
echo "============================================================"
echo ""
fi
exit 0