436 lines
15 KiB
Bash
Executable File
436 lines
15 KiB
Bash
Executable File
#!/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 <URL>
|
||
# Или после клонирования:
|
||
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
|
||
|
||
|