diff --git a/register-submodules.sh b/register-submodules.sh index ce64f07..d1612c3 100755 --- a/register-submodules.sh +++ b/register-submodules.sh @@ -2,18 +2,29 @@ # ============================================================ # register-submodules.sh - Регистрация всех вложенных репозиториев как подмодулей # +# Автор: Michael BAG +# Репозиторий: https://git.p7net.ru/tools/git_man +# # Использование: -# ./register-submodules.sh [--help] [--dry-run] [--force] +# ./register-submodules.sh [--help] [--dry-run] [--force] [--ignore=all|dirty|untracked|none] # # Опции: -# --help Показать эту справку -# --dry-run Только показать, что будет сделано (без изменений) -# --force Принудительно перерегистрировать подмодули -# --verbose Подробный вывод +# --help, -h Показать эту справку +# --dry-run Только показать, что будет сделано (без изменений) +# --force, -f Принудительно перерегистрировать подмодули +# --ignore=MODE Установить режим игнорирования для всех подмодулей +# all - игнорировать всё (не показывать изменения) +# dirty - игнорировать только изменения в файлах +# untracked - игнорировать только неотслеживаемые файлы +# none - показывать все изменения (по умолчанию) +# --ignore-submodule PATH Установить игнорирование для конкретного подмодуля +# --verbose, -v Подробный вывод +# --quiet, -q Минимальный вывод (только ошибки) # # Описание: # Скрипт находит все вложенные репозитории (папки с .git), # определяет их URL и регистрирует как подмодули в .gitmodules. +# Также позволяет настроить игнорирование состояния подмодулей. # ============================================================ set -e # Остановка при ошибке @@ -31,43 +42,43 @@ show_help() { ./register-submodules.sh [ОПЦИИ] ОПЦИИ: - --help Показать эту справку - --dry-run Только показать, что будет сделано (без изменений) - --force Принудительно перерегистрировать подмодули - (удаляет существующие и создаёт заново) - --verbose Подробный вывод (показывает все действия) - --quiet Минимальный вывод (только ошибки) - -ОПИСАНИЕ: - Скрипт находит все вложенные репозитории (папки с .git), - определяет их URL и регистрирует как подмодули в .gitmodules. - - Вложенные репозитории — это папки, которые являются - самостоятельными Git-репозиториями внутри основного. + --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 --dry-run + # Регистрация с игнорированием всех изменений в подмодулях + ./register-submodules.sh --ignore=all - # Принудительная перерегистрация всех подмодулей - ./register-submodules.sh --force --verbose + # Регистрация с игнорированием только dirty-изменений + ./register-submodules.sh --ignore=dirty - # Тихий режим (только ошибки) - ./register-submodules.sh --quiet + # Удалить все настройки игнорирования + ./register-submodules.sh --remove-ignore -ПОСЛЕ РЕГИСТРАЦИИ: - 1. Проверьте изменения: git status - 2. Посмотрите подмодули: git submodule status - 3. Закоммитьте изменения: git commit -m "Зарегистрированы все подмодули" - 4. Отправьте на сервер: git push + # Установить ignore только для конкретного подмодуля + ./register-submodules.sh --ignore-submodule tools/cam:dirty -ПРИ КЛОНИРОВАНИИ РЕПОЗИТОРИЯ: - git clone --recursive - # Или после клонирования: - git submodule update --init --recursive + # Просмотр без изменений + ./register-submodules.sh --dry-run --ignore=all ============================================================ EOF @@ -81,6 +92,9 @@ DRY_RUN=false FORCE=false VERBOSE=false QUIET=false +REMOVE_IGNORE=false +IGNORE_MODE="" +IGNORE_SUBMODULE="" # ============================================================ # Разбор аргументов командной строки @@ -106,6 +120,18 @@ while [[ $# -gt 0 ]]; do 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 для справки" @@ -118,12 +144,11 @@ done # Настройка вывода # ============================================================ if [ "$QUIET" = true ]; then - # В тихом режиме перенаправляем всё в /dev/null, кроме ошибок - exec 3>&1 # Сохраняем stdout + exec 3>&1 exec >/dev/null 2>&1 fi -# Цвета для вывода (если не тихий режим) +# Цвета для вывода if [ "$QUIET" != true ]; then RED='\033[0;31m' GREEN='\033[0;32m' @@ -131,7 +156,7 @@ if [ "$QUIET" != true ]; then BLUE='\033[0;34m' CYAN='\033[0;36m' MAGENTA='\033[0;35m' - NC='\033[0m' # No Color + NC='\033[0m' else RED=''; GREEN=''; YELLOW=''; BLUE=''; CYAN=''; MAGENTA=''; NC='' fi @@ -176,21 +201,79 @@ log_step() { # ============================================================ 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 +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 $? +} + # ============================================================ # Информация о режиме работы # ============================================================ @@ -208,32 +291,73 @@ if [ "$QUIET" != true ]; then if [ "$FORCE" = true ]; then echo -e "${YELLOW}⚠️ РЕЖИМ ПРИНУДИТЕЛЬНОЙ ПЕРЕРЕГИСТРАЦИИ (--force)${NC}" - echo " Существующие подмодули будут перезаписаны" echo "" fi - if [ "$VERBOSE" = true ]; then - echo -e "${BLUE}🔍 Подробный режим (--verbose)${NC}" + 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 # ============================================================ -# Проверка .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 +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_info "Файл .gitmodules уже существует" - log_info "Будет выполнено обновление существующих записей" + 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 -else - log_info "Файл .gitmodules не существует — будет создан" fi # ============================================================ @@ -241,23 +365,16 @@ 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 вложенных репозиториев" @@ -270,41 +387,6 @@ if [ "$VERBOSE" = true ]; then 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 $? -} - # ============================================================ # Основной цикл регистрации # ============================================================ @@ -316,12 +398,10 @@ 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 @@ -347,7 +427,6 @@ while read repo; do continue fi - # Регистрация if [ "$QUIET" != true ]; then echo -e "${GREEN}➕ Регистрация:${NC} $repo" echo -e " ${CYAN}URL:${NC} $url" @@ -360,6 +439,14 @@ while read repo; do 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" @@ -375,7 +462,40 @@ while read repo; do 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" # ============================================================ @@ -393,13 +513,19 @@ if [ "$QUIET" != true ]; then if [ $ERRORS -gt 0 ]; then echo -e " ${RED}Ошибок:${NC} $ERRORS" fi - echo "" + + 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 для выполнения." - echo "" fi + echo "" fi # ============================================================ @@ -407,7 +533,7 @@ fi # ============================================================ if [ "$DRY_RUN" = false ] && [ $REGISTERED -gt 0 ]; then if [ "$QUIET" != true ]; then - echo -e "${GREEN}✅ Все подмодули зарегистрированы!${NC}" + echo -e "${GREEN}✅ Подмодули зарегистрированы!${NC}" echo "" echo -e "${CYAN}Следующие шаги:${NC}" echo " 1. Проверьте изменения: git status" @@ -415,13 +541,19 @@ if [ "$DRY_RUN" = false ] && [ $REGISTERED -gt 0 ]; then echo " 3. Закоммитьте изменения: git commit -m \"Зарегистрированы все подмодули\"" echo " 4. Отправьте на сервер: git push" echo "" - echo -e "${YELLOW}⚠️ Внимание:${NC} При первом клонировании выполните:" + echo -e "${YELLOW}⚠️ При первом клонировании выполните:${NC}" echo " git submodule update --init --recursive" echo "" fi -elif [ "$DRY_RUN" = false ] && [ $REGISTERED -eq 0 ] && [ $SKIPPED -eq 0 ]; then +elif [ "$DRY_RUN" = false ] && [ -n "$IGNORE_MODE" ]; then if [ "$QUIET" != true ]; then - echo -e "${YELLOW}⚠️ Не найдено подмодулей для регистрации${NC}" + 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 @@ -431,5 +563,3 @@ if [ "$QUIET" != true ]; then fi exit 0 - -