Files
git_man/setup-1c-repo.sh
T

506 lines
18 KiB
Bash
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
# ============================================================
# setup-1c-repo.sh - Настройка Git-репозитория под выгрузку 1С (конфигуратор)
#
# Версия: 1.2.2
# Автор: Michael BAG <mk@p7net.ru>
# Репозиторий: https://git.p7net.ru/tools/git_man
#
# Платформы: Linux, macOS (на Windows используйте setup-1c-repo.ps1)
#
# Использование:
# ./setup-1c-repo.sh --path DIR [--help] [--version] [--dry-run] [--force]
# [--init] [--renormalize] [--no-gitignore]
# [--verbose] [--quiet]
#
# Описание:
# Включает локальные настройки Git в указанной папке (--path / --repo;
# обязательный параметр) для проектов с выгрузкой из конфигуратора 1С:
# - UTF-8 с BOM (как у конфигуратора; BOM хранится как часть содержимого)
# - CRLF в рабочей копии для *.bsl / *.xml и др. текстовых файлов выгрузки
# - корректное отображение кириллических путей (core.quotepath=false)
# - длинные пути (core.longpaths=true), Unicode на macOS
# - создаёт/обновляет .gitattributes и .gitignore
# ============================================================
set -e
SCRIPT_VERSION="1.2.2"
# ============================================================
# Справка
# ============================================================
show_help() {
cat << EOF
============================================================
📦 setup-1c-repo.sh v${SCRIPT_VERSION} — настройка репозитория под 1С
============================================================
ОПИСАНИЕ:
Настраивает локальный Git-репозиторий под выгрузку из
конфигуратора 1С (UTF-8 BOM + CRLF).
Путь к репозиторию обязателен: --path / --repo.
ИСПОЛЬЗОВАНИЕ:
./setup-1c-repo.sh --path DIR [ОПЦИИ]
ОПЦИИ:
--help, -h Показать эту справку
--version, -V Показать версию скрипта
--path DIR, --repo DIR
Папка репозитория для настройки (обязательно)
--dry-run Только показать, что будет сделано
--force, -f Перезаписать существующие .gitattributes / .gitignore
--init Выполнить git init, если папка ещё не репозиторий
(создаёт каталог, если его нет)
--renormalize После настройки: git add --renormalize .
--no-gitignore Не создавать/не менять .gitignore
--verbose, -v Подробный вывод
--quiet, -q Минимальный вывод (только ошибки)
ЧТО ДЕЛАЕТ:
1. Локальный git config (quotepath, encoding, autocrlf, longpaths, …)
2. Файл .gitattributes — EOL/binary для файлов выгрузки 1С
3. Файл .gitignore — типичные исключения (*.cf, *.cfe, …)
ПРИМЕРЫ:
./setup-1c-repo.sh --path /projects/uas_ep --force
./setup-1c-repo.sh --repo ../my-1c-dump --init
./setup-1c-repo.sh --path . --force --renormalize
./setup-1c-repo.sh --path /tmp/new-1c --init --dry-run
============================================================
EOF
exit 0
}
show_version() {
echo "setup-1c-repo.sh ${SCRIPT_VERSION}"
exit 0
}
# ============================================================
# Аргументы
# ============================================================
DRY_RUN=false
FORCE=false
VERBOSE=false
QUIET=false
DO_INIT=false
RENORMALIZE=false
NO_GITIGNORE=false
REPO_PATH=""
while [[ $# -gt 0 ]]; do
case $1 in
--help|-h) show_help ;;
--version|-V) show_version ;;
--path|--repo)
if [ -z "${2:-}" ] || [[ "${2:-}" == -* ]]; then
echo -e "\033[0;31m❌ Для $1 укажите путь к папке репозитория\033[0m" >&2
exit 1
fi
REPO_PATH="$2"
shift 2
;;
--path=*|--repo=*)
REPO_PATH="${1#*=}"
if [ -z "$REPO_PATH" ]; then
echo -e "\033[0;31m❌ Пустой путь в $1\033[0m" >&2
exit 1
fi
shift
;;
--dry-run) DRY_RUN=true; shift ;;
--force|-f) FORCE=true; shift ;;
--init) DO_INIT=true; shift ;;
--renormalize) RENORMALIZE=true; shift ;;
--no-gitignore) NO_GITIGNORE=true; shift ;;
--verbose|-v) VERBOSE=true; shift ;;
--quiet|-q) QUIET=true; shift ;;
*)
echo -e "\033[0;31m❌ Неизвестная опция: $1\033[0m" >&2
echo " Используйте --help для справки" >&2
exit 1
;;
esac
done
# ============================================================
# Логирование
# ============================================================
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() { [ "$QUIET" != true ] && echo -e "${CYAN}$1${NC}"; }
log_success() { [ "$QUIET" != true ] && echo -e "${GREEN}$1${NC}"; }
log_warning() { [ "$QUIET" != true ] && echo -e "${YELLOW}⚠️ $1${NC}"; }
log_error() { echo -e "${RED}$1${NC}" >&2; }
log_debug() { [ "$VERBOSE" = true ] && [ "$QUIET" != true ] && echo -e "${BLUE}🔍 $1${NC}"; }
log_step() { [ "$QUIET" != true ] && echo -e "${MAGENTA}$1${NC}"; }
# ============================================================
# Определение ОС
# ============================================================
OS_NAME="$(uname -s 2>/dev/null || echo unknown)"
case "$OS_NAME" in
Darwin*) OS_KIND="macos" ;;
Linux*) OS_KIND="linux" ;;
MINGW*|MSYS*|CYGWIN*) OS_KIND="windows-bash" ;;
*) OS_KIND="unix" ;;
esac
# ============================================================
# Шаблоны файлов
# ============================================================
# Конфигуратор 1С выгружает текстовые файлы в UTF-8 с BOM и с CRLF.
# Git хранит BOM как часть содержимого; eol=crlf даёт CRLF в рабочей копии
# на любой ОС — совпадает с повторной выгрузкой из конфигуратора.
GITATTRIBUTES_CONTENT='# .gitattributes — выгрузка конфигуратора 1С (UTF-8 BOM + CRLF)
# Создано setup-1c-repo.sh (git_man). Не удаляйте без необходимости.
#
# Правило: текстовые файлы выгрузки — text + eol=crlf (рабочая копия = CRLF,
# в объекте Git нормализуется к LF). Бинарники — binary (без конвертации EOL).
* text=auto
# --- Текстовые файлы выгрузки конфигуратора ---
*.bsl text eol=crlf
*.os text eol=crlf
*.xml text eol=crlf
*.txt text eol=crlf
*.html text eol=crlf
*.htm text eol=crlf
*.xsd text eol=crlf
*.xslt text eol=crlf
*.xsl text eol=crlf
*.Form text eol=crlf
*.Module text eol=crlf
*.max text eol=crlf
# --- Служебные / документация репозитория (LF) ---
*.md text eol=lf
*.json text eol=lf
*.yml text eol=lf
*.yaml text eol=lf
*.sh text eol=lf
*.gitignore text eol=lf
*.gitattributes text eol=lf
.editorconfig text eol=lf
# --- Скрипты Windows ---
*.bat text eol=crlf
*.cmd text eol=crlf
*.ps1 text eol=crlf
# --- Бинарные артефакты 1С и медиа ---
*.bin binary
*.cf binary
*.cfe binary
*.cfu binary
*.epf binary
*.erf binary
*.axdt binary
*.addin binary
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.bmp binary
*.ico binary
*.webp binary
*.tif binary
*.tiff binary
*.svg -text
*.zip binary
*.rar binary
*.7z binary
*.gz binary
*.xls binary
*.xlsx binary
*.xlsm binary
*.doc binary
*.docx binary
*.pdf binary
*.rtf binary
*.ttf binary
*.otf binary
*.woff binary
*.woff2 binary
*.eot binary
'
GITIGNORE_CONTENT='# .gitignore — типовые исключения для проектов 1С (конфигуратор)
# Создано setup-1c-repo.sh (git_man)
# Бинарные выгрузки конфигурации / расширений / обработок
*.cf
*.cfe
*.cfu
*.epf
*.erf
# Временные и резервные
*.tmp
*.bak
*.~*
*~
*.old
*.orig
# Логи и дампы
*.log
*.lgp
*.lgf
# ОС
Thumbs.db
ehthumbs.db
Desktop.ini
desktop.ini
.DS_Store
.AppleDouble
.LSOverride
# IDE / редакторы
.vs/
.vscode/
.idea/
*.suo
*.user
*.userosscache
*.sln.docstates
# Отладка / кэш
Debug/
debug/
cache/
*.pfl
'
# ============================================================
# Целевой каталог репозитория
# ============================================================
resolve_repo_dir() {
local raw="$1"
if command -v realpath >/dev/null 2>&1; then
# realpath -m: путь может ещё не существовать (--init)
if realpath -m "$raw" >/dev/null 2>&1; then
realpath -m "$raw"
return 0
fi
fi
# Fallback без GNU realpath (macOS)
if [ -d "$raw" ]; then
(cd "$raw" && pwd -P)
return 0
fi
local parent base
parent=$(dirname "$raw")
base=$(basename "$raw")
if [ -d "$parent" ]; then
printf '%s/%s\n' "$(cd "$parent" && pwd -P)" "$base"
return 0
fi
printf '%s\n' "$raw"
}
if [ -z "$REPO_PATH" ]; then
log_error "Не указан путь к репозиторию"
echo " Обязательно: --path DIR или --repo DIR" >&2
echo " Справка: ./setup-1c-repo.sh --help" >&2
exit 1
fi
TARGET_DIR="$(resolve_repo_dir "$REPO_PATH")"
# ============================================================
# Проверка окружения
# ============================================================
log_step "Проверка окружения (ОС: ${OS_KIND})..."
log_info "Целевой каталог: $TARGET_DIR"
if ! command -v git >/dev/null 2>&1; then
log_error "Git не установлен"
exit 1
fi
if [ ! -d "$TARGET_DIR" ]; then
if [ "$DO_INIT" = true ]; then
if [ "$DRY_RUN" = true ]; then
echo " [DRY-RUN] mkdir -p \"$TARGET_DIR\""
echo " [DRY-RUN] git -C \"$TARGET_DIR\" init"
else
mkdir -p "$TARGET_DIR"
log_success "Создан каталог: $TARGET_DIR"
git -C "$TARGET_DIR" init
log_success "Выполнен git init"
fi
else
log_error "Папка не существует: $TARGET_DIR"
echo " Укажите существующий путь или добавьте --init" >&2
exit 1
fi
else
if [ ! -d "$TARGET_DIR/.git" ] && [ ! -f "$TARGET_DIR/.git" ]; then
if [ "$DO_INIT" = true ]; then
if [ "$DRY_RUN" = true ]; then
echo " [DRY-RUN] git -C \"$TARGET_DIR\" init"
else
git -C "$TARGET_DIR" init
log_success "Выполнен git init"
fi
else
log_error "Папка не является Git-репозиторием: $TARGET_DIR"
echo " Укажите корень репозитория (--path) или добавьте --init" >&2
exit 1
fi
fi
fi
log_success "Окружение проверено"
# ============================================================
# Локальный git config
# ============================================================
set_local_config() {
local key="$1"
local value="$2"
if [ "$DRY_RUN" = true ]; then
echo " [DRY-RUN] git -C \"$TARGET_DIR\" config --local $key $value"
return 0
fi
git -C "$TARGET_DIR" config --local "$key" "$value"
log_debug "config $key=$value"
}
log_step "Локальные настройки Git..."
# Кириллические пути без \320\...
set_local_config core.quotepath false
# Длинные пути (особенно Windows / сетевые диски / глубокие деревья 1С)
set_local_config core.longpaths true
# Кодировки UI и коммитов
set_local_config gui.encoding utf-8
set_local_config i18n.commitEncoding utf-8
# EOL полностью через .gitattributes (без двойной конвертации)
set_local_config core.autocrlf false
set_local_config core.safecrlf warn
# Рекомендации 1С:ГитКонвертер для крупных деревьев метаданных
set_local_config diff.renames false
set_local_config diff.renameLimit 1
# macOS: NFD/NFC для имён файлов с кириллицей
if [ "$OS_KIND" = "macos" ]; then
set_local_config core.precomposeunicode true
log_info "macOS: core.precomposeunicode=true"
fi
if [ "$DRY_RUN" = true ]; then
log_info "Локальный git config (dry-run)"
else
log_success "Локальный git config применён"
fi
# ============================================================
# Запись файла с бэкапом
# ============================================================
write_file_safe() {
local rel="$1"
local content="$2"
local label="$3"
local path="$TARGET_DIR/$rel"
if [ -f "$path" ] && [ "$FORCE" != true ]; then
log_warning "$label уже существует — пропуск (используйте --force)"
return 0
fi
if [ "$DRY_RUN" = true ]; then
if [ -f "$path" ]; then
echo " [DRY-RUN] перезаписать $path (бэкап ${path}.bak)"
else
echo " [DRY-RUN] создать $path"
fi
return 0
fi
if [ -f "$path" ]; then
cp -f "$path" "${path}.bak"
log_info "Бэкап: ${rel}.bak"
fi
# Пишем через printf, чтобы сохранить финальный перевод строки
printf '%s\n' "$content" > "$path"
log_success "Записан $rel"
}
log_step "Файл .gitattributes..."
write_file_safe ".gitattributes" "$GITATTRIBUTES_CONTENT" ".gitattributes"
if [ "$NO_GITIGNORE" != true ]; then
log_step "Файл .gitignore..."
write_file_safe ".gitignore" "$GITIGNORE_CONTENT" ".gitignore"
else
log_info "Пропуск .gitignore (--no-gitignore)"
fi
# ============================================================
# Renormalize
# ============================================================
if [ "$RENORMALIZE" = true ]; then
log_step "Нормализация индекса (git add --renormalize .)..."
if [ "$DRY_RUN" = true ]; then
echo " [DRY-RUN] git -C \"$TARGET_DIR\" add --renormalize ."
else
git -C "$TARGET_DIR" add --renormalize .
log_success "Индекс перенормализован"
log_warning "Проверьте git status — возможны массовые изменения EOL"
fi
fi
# ============================================================
# Итог
# ============================================================
if [ "$QUIET" != true ]; then
echo ""
echo "============================================================"
echo -e "${CYAN}📊 Итог настройки под выгрузку конфигуратора 1С${NC}"
echo "============================================================"
echo " ОС: $OS_KIND ($OS_NAME)"
echo " Каталог: $TARGET_DIR"
echo " Encoding: UTF-8 (BOM сохраняется в содержимом файлов)"
echo " EOL (выгрузка): CRLF в рабочей копии (*.bsl, *.xml, …)"
echo " core.autocrlf: false (управляет .gitattributes)"
echo " core.quotepath: false"
if [ "$DRY_RUN" = true ]; then
echo ""
echo -e "${YELLOW}⚠️ Режим --dry-run: изменения НЕ применены${NC}"
else
echo ""
echo -e "${GREEN}✅ Готово${NC}"
echo ""
echo -e "${CYAN}Следующие шаги:${NC}"
echo " 1. cd \"$TARGET_DIR\" && git status"
echo " 2. git add .gitattributes .gitignore"
echo " 3. git commit -m \"Настройки Git для выгрузки конфигуратора 1С\""
if [ "$RENORMALIZE" != true ]; then
echo " 4. При необходимости нормализовать EOL:"
echo " ./setup-1c-repo.sh --path \"$TARGET_DIR\" --renormalize"
echo " или: git -C \"$TARGET_DIR\" add --renormalize ."
fi
fi
echo "============================================================"
echo ""
fi
exit 0