Files
git_man/register-submodules.sh
T
2026-07-19 11:23:24 +03:00

436 lines
15 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 - Регистрация всех вложенных репозиториев как подмодулей
#
# Использование:
# ./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