#!/bin/bash # ============================================================ # register-submodules.sh - Регистрация всех вложенных репозиториев как подмодулей # # Использование: # ./register-submodules.sh [--help] [--dry-run] [--force] # # Опции: # --help Показать эту справку # --dry-run Только показать, что будет сделано (без изменений) # --force Принудительно перерегистрировать подмодули # --verbose Подробный вывод # # Описание: # Скрипт находит все вложенные репозитории (папки с .git), # определяет их URL и регистрирует как подмодули в .gitmodules. # ============================================================ set -e # Остановка при ошибке # ============================================================ # Функция показа справки # ============================================================ show_help() { cat << 'EOF' ============================================================ 📦 register-submodules.sh - Регистрация вложенных репозиториев ============================================================ ИСПОЛЬЗОВАНИЕ: ./register-submodules.sh [ОПЦИИ] ОПЦИИ: --help Показать эту справку --dry-run Только показать, что будет сделано (без изменений) --force Принудительно перерегистрировать подмодули (удаляет существующие и создаёт заново) --verbose Подробный вывод (показывает все действия) --quiet Минимальный вывод (только ошибки) ОПИСАНИЕ: Скрипт находит все вложенные репозитории (папки с .git), определяет их URL и регистрирует как подмодули в .gitmodules. Вложенные репозитории — это папки, которые являются самостоятельными Git-репозиториями внутри основного. ПРИМЕРЫ: # Базовая регистрация ./register-submodules.sh # Просмотр того, что будет сделано ./register-submodules.sh --dry-run # Принудительная перерегистрация всех подмодулей ./register-submodules.sh --force --verbose # Тихий режим (только ошибки) ./register-submodules.sh --quiet ПОСЛЕ РЕГИСТРАЦИИ: 1. Проверьте изменения: git status 2. Посмотрите подмодули: git submodule status 3. Закоммитьте изменения: git commit -m "Зарегистрированы все подмодули" 4. Отправьте на сервер: git push ПРИ КЛОНИРОВАНИИ РЕПОЗИТОРИЯ: git clone --recursive # Или после клонирования: git submodule update --init --recursive ============================================================ EOF exit 0 } # ============================================================ # Инициализация переменных # ============================================================ DRY_RUN=false FORCE=false VERBOSE=false QUIET=false # ============================================================ # Разбор аргументов командной строки # ============================================================ 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 ;; *) echo -e "\033[0;31m❌ Неизвестная опция: $1\033[0m" echo " Используйте --help для справки" exit 1 ;; esac done # ============================================================ # Настройка вывода # ============================================================ if [ "$QUIET" = true ]; then # В тихом режиме перенаправляем всё в /dev/null, кроме ошибок exec 3>&1 # Сохраняем stdout 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' # No Color 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 "Проверка окружения..." # Проверка, что мы в корне Git-репозитория if [ ! -d ".git" ]; then log_error "Текущая папка не является Git-репозиторием" echo " Запустите скрипт из корня основного репозитория" >&2 exit 1 fi log_success "Текущая папка является Git-репозиторием" # Проверка наличия Git if ! command -v git &> /dev/null; then log_error "Git не установлен" exit 1 fi # ============================================================ # Информация о режиме работы # ============================================================ 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 " Существующие подмодули будут перезаписаны" echo "" fi if [ "$VERBOSE" = true ]; then echo -e "${BLUE}🔍 Подробный режим (--verbose)${NC}" echo "" fi fi # ============================================================ # Проверка .gitmodules # ============================================================ if [ -f ".gitmodules" ]; then if [ "$FORCE" = true ]; then log_warning "Файл .gitmodules существует — будет перезаписан (--force)" if [ "$DRY_RUN" = false ]; then git rm --cached .gitmodules 2>/dev/null || true rm -f .gitmodules fi else log_info "Файл .gitmodules уже существует" log_info "Будет выполнено обновление существующих записей" fi else log_info "Файл .gitmodules не существует — будет создан" fi # ============================================================ # Поиск вложенных репозиториев # ============================================================ log_step "Поиск вложенных репозиториев..." # Временный файл для хранения путей TEMP_FILE=$(mktemp) # Найти все папки с .git (исключая сам .git) 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 # ============================================================ # Функция регистрации подмодуля # ============================================================ 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 git config --remove-section "submodule.$repo" 2>/dev/null || true # Удаляем из .gitmodules 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 $? } # ============================================================ # Основной цикл регистрации # ============================================================ log_step "Регистрация подмодулей..." REGISTERED=0 SKIPPED=0 ERRORS=0 NO_URL=0 while read repo; do # Пропустить пустые строки [ -z "$repo" ] && continue log_debug "Обработка: $repo" # Получить URL 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)) ;; 2) log_debug "Пропущен (уже зарегистрирован): $repo" SKIPPED=$((SKIPPED + 1)) ;; *) log_error "Ошибка при регистрации: $repo" ERRORS=$((ERRORS + 1)) ;; esac echo "" done < "$TEMP_FILE" # Очистка 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 echo "" if [ "$DRY_RUN" = true ]; then echo -e "${YELLOW}⚠️ Это был просмотр (--dry-run). Изменения НЕ применены.${NC}" echo " Уберите --dry-run для выполнения." echo "" fi 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 ] && [ $REGISTERED -eq 0 ] && [ $SKIPPED -eq 0 ]; then if [ "$QUIET" != true ]; then echo -e "${YELLOW}⚠️ Не найдено подмодулей для регистрации${NC}" fi fi if [ "$QUIET" != true ]; then echo "============================================================" echo "" fi exit 0