# ============================================================ # setup-1c-repo.ps1 - Настройка Git-репозитория под выгрузку 1С (конфигуратор) # # Версия: 1.2.2 # Автор: Michael BAG # Репозиторий: https://git.p7net.ru/tools/git_man # # Платформа: Windows (PowerShell 5.1+ / PowerShell 7+) # Для Linux/macOS используйте setup-1c-repo.sh # # Использование: # .\setup-1c-repo.ps1 -Path DIR [-DryRun] [-Force] [-Init] [-Renormalize] # [-NoGitignore] [-Verbose] [-Quiet] [-Help] [-Version] # # Описание: # Включает локальные настройки Git в указанной папке (-Path / -Repo; # обязательный параметр) для проектов с выгрузкой из конфигуратора 1С: # - UTF-8 с BOM (как у конфигуратора; BOM хранится как часть содержимого) # - CRLF в рабочей копии для *.bsl / *.xml и др. текстовых файлов выгрузки # - корректное отображение кириллических путей (core.quotepath=false) # - длинные пути (core.longpaths=true) # - создаёт/обновляет .gitattributes и .gitignore # ============================================================ [CmdletBinding()] param( [Parameter()] [Alias('Repo', 'RepoPath')] [string]$Path, [switch]$DryRun, [Alias('f')] [switch]$Force, [switch]$Init, [switch]$Renormalize, [switch]$NoGitignore, [Alias('q')] [switch]$Quiet, [Alias('h')] [switch]$Help, [Alias('V')] [switch]$Version ) $ErrorActionPreference = 'Stop' $ScriptVersion = '1.2.2' function Show-Help { @" ============================================================ 📦 setup-1c-repo.ps1 v$ScriptVersion — настройка репозитория под 1С ============================================================ ОПИСАНИЕ: Настраивает локальный Git-репозиторий под выгрузку из конфигуратора 1С (UTF-8 BOM + CRLF). Путь к репозиторию обязателен: -Path / -Repo. ИСПОЛЬЗОВАНИЕ: .\setup-1c-repo.ps1 -Path DIR [ОПЦИИ] .\setup-1c-repo.cmd -Path DIR [ОПЦИИ] ОПЦИИ: -Help, -h Показать эту справку -Version, -V Показать версию скрипта -Path, -Repo DIR Папка репозитория для настройки (обязательно) -DryRun Только показать, что будет сделано -Force, -f Перезаписать существующие .gitattributes / .gitignore -Init Выполнить git init, если папка ещё не репозиторий (создаёт каталог, если его нет) -Renormalize После настройки: git add --renormalize . -NoGitignore Не создавать/не менять .gitignore -Verbose, -v Подробный вывод -Quiet, -q Минимальный вывод (только ошибки) ПРИМЕРЫ: .\setup-1c-repo.ps1 -Path D:\projects\uas_ep -Force .\setup-1c-repo.ps1 -Repo ..\my-1c-dump -Init .\setup-1c-repo.ps1 -Path . -Force -Renormalize .\setup-1c-repo.ps1 -Path C:\tmp\new-1c -Init -DryRun ============================================================ "@ | Write-Host exit 0 } function Show-Version { Write-Host "setup-1c-repo.ps1 $ScriptVersion" exit 0 } if ($Help) { Show-Help } if ($Version) { Show-Version } function Write-Info([string]$Message) { if (-not $Quiet) { Write-Host "ℹ️ $Message" -ForegroundColor Cyan } } function Write-Success([string]$Message) { if (-not $Quiet) { Write-Host "✅ $Message" -ForegroundColor Green } } function Write-WarnMsg([string]$Message) { if (-not $Quiet) { Write-Host "⚠️ $Message" -ForegroundColor Yellow } } function Write-ErrMsg([string]$Message) { Write-Host "❌ $Message" -ForegroundColor Red } function Write-DebugMsg([string]$Message) { if ($VerbosePreference -ne 'SilentlyContinue' -and -not $Quiet) { Write-Host "🔍 $Message" -ForegroundColor Blue } } function Write-Step([string]$Message) { if (-not $Quiet) { Write-Host "▶ $Message" -ForegroundColor Magenta } } $GitAttributesContent = @' # .gitattributes — выгрузка конфигуратора 1С (UTF-8 BOM + CRLF) # Создано setup-1c-repo.ps1 (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 '@ $GitIgnoreContent = @' # .gitignore — типовые исключения для проектов 1С (конфигуратор) # Создано setup-1c-repo.ps1 (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 '@ function Test-GitAvailable { try { $null = Get-Command git -ErrorAction Stop return $true } catch { return $false } } function Write-Utf8File { param( [string]$FilePath, [string]$Content, [string]$BaseDir ) # UTF-8 без BOM: для .gitattributes/.gitignore достаточно; BOM у *.bsl # — содержимое выгрузки конфигуратора, не этих служебных файлов. $normalized = $Content -replace "`r`n", "`n" -replace "`r", "`n" $normalized = $normalized.TrimEnd("`n") + "`n" $encoding = New-Object System.Text.UTF8Encoding($false) $fullPath = Join-Path $BaseDir $FilePath [System.IO.File]::WriteAllText($fullPath, $normalized, $encoding) } function Write-FileSafe { param( [string]$FilePath, [string]$Content, [string]$Label, [string]$BaseDir ) $fullPath = Join-Path $BaseDir $FilePath if ((Test-Path -LiteralPath $fullPath) -and -not $Force) { Write-WarnMsg "$Label уже существует — пропуск (используйте -Force)" return } if ($DryRun) { if (Test-Path -LiteralPath $fullPath) { Write-Host " [DRY-RUN] перезаписать $fullPath (бэкап $FilePath.bak)" } else { Write-Host " [DRY-RUN] создать $fullPath" } return } if (Test-Path -LiteralPath $fullPath) { Copy-Item -LiteralPath $fullPath -Destination "$fullPath.bak" -Force Write-Info "Бэкап: $FilePath.bak" } Write-Utf8File -FilePath $FilePath -Content $Content -BaseDir $BaseDir Write-Success "Записан $FilePath" } function Set-LocalGitConfig { param( [string]$Key, [string]$Value, [string]$WorkTree ) if ($DryRun) { Write-Host " [DRY-RUN] git -C `"$WorkTree`" config --local $Key $Value" return } & git -C $WorkTree config --local $Key $Value if ($LASTEXITCODE -ne 0) { throw "Не удалось установить git config $Key=$Value" } Write-DebugMsg "config $Key=$Value" } # ============================================================ # Целевой каталог # ============================================================ if ([string]::IsNullOrWhiteSpace($Path)) { Write-ErrMsg "Не указан путь к репозиторию" Write-Host " Обязательно: -Path DIR или -Repo DIR" -ForegroundColor Red Write-Host " Справка: .\setup-1c-repo.ps1 -Help" -ForegroundColor Red exit 1 } $TargetDir = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($Path) # ============================================================ # Основной ход # ============================================================ Write-Step "Проверка окружения (ОС: Windows)..." Write-Info "Целевой каталог: $TargetDir" if (-not (Test-GitAvailable)) { Write-ErrMsg "Git не установлен или недоступен в PATH" exit 1 } $repoReady = $false if (-not (Test-Path -LiteralPath $TargetDir -PathType Container)) { if ($Init) { if ($DryRun) { Write-Host " [DRY-RUN] New-Item -ItemType Directory `"$TargetDir`"" Write-Host " [DRY-RUN] git -C `"$TargetDir`" init" } else { New-Item -ItemType Directory -Path $TargetDir -Force | Out-Null Write-Success "Создан каталог: $TargetDir" & git -C $TargetDir init if ($LASTEXITCODE -ne 0) { throw "git init завершился с ошибкой" } Write-Success "Выполнен git init" $repoReady = $true } } else { Write-ErrMsg "Папка не существует: $TargetDir" Write-Host " Укажите существующий путь или добавьте -Init" -ForegroundColor Red exit 1 } } else { $gitMarker = Join-Path $TargetDir '.git' if (Test-Path -LiteralPath $gitMarker) { $repoReady = $true } elseif ($Init) { if ($DryRun) { Write-Host " [DRY-RUN] git -C `"$TargetDir`" init" } else { & git -C $TargetDir init if ($LASTEXITCODE -ne 0) { throw "git init завершился с ошибкой" } Write-Success "Выполнен git init" $repoReady = $true } } else { Write-ErrMsg "Папка не является Git-репозиторием: $TargetDir" Write-Host " Укажите корень репозитория (-Path) или добавьте -Init" -ForegroundColor Red exit 1 } } # В dry-run без реального каталога дальше только показываем действия if (-not $DryRun -and -not $repoReady -and -not (Test-Path -LiteralPath (Join-Path $TargetDir '.git'))) { Write-ErrMsg "Репозиторий не готов: $TargetDir" exit 1 } Write-Success "Окружение проверено" Write-Step "Локальные настройки Git..." # Кириллические пути без \320\... Set-LocalGitConfig -Key 'core.quotepath' -Value 'false' -WorkTree $TargetDir # Длинные пути Windows / глубокие деревья метаданных 1С Set-LocalGitConfig -Key 'core.longpaths' -Value 'true' -WorkTree $TargetDir # Кодировки UI и коммитов Set-LocalGitConfig -Key 'gui.encoding' -Value 'utf-8' -WorkTree $TargetDir Set-LocalGitConfig -Key 'i18n.commitEncoding' -Value 'utf-8' -WorkTree $TargetDir # EOL полностью через .gitattributes Set-LocalGitConfig -Key 'core.autocrlf' -Value 'false' -WorkTree $TargetDir Set-LocalGitConfig -Key 'core.safecrlf' -Value 'warn' -WorkTree $TargetDir # Рекомендации 1С:ГитКонвертер для крупных деревьев метаданных Set-LocalGitConfig -Key 'diff.renames' -Value 'false' -WorkTree $TargetDir Set-LocalGitConfig -Key 'diff.renameLimit' -Value '1' -WorkTree $TargetDir if ($DryRun) { Write-Info "Локальный git config (dry-run)" } else { Write-Success "Локальный git config применён" } Write-Step "Файл .gitattributes..." Write-FileSafe -FilePath '.gitattributes' -Content $GitAttributesContent -Label '.gitattributes' -BaseDir $TargetDir if (-not $NoGitignore) { Write-Step "Файл .gitignore..." Write-FileSafe -FilePath '.gitignore' -Content $GitIgnoreContent -Label '.gitignore' -BaseDir $TargetDir } else { Write-Info "Пропуск .gitignore (-NoGitignore)" } if ($Renormalize) { Write-Step "Нормализация индекса (git add --renormalize .)..." if ($DryRun) { Write-Host " [DRY-RUN] git -C `"$TargetDir`" add --renormalize ." } else { & git -C $TargetDir add --renormalize . if ($LASTEXITCODE -ne 0) { throw "git add --renormalize завершился с ошибкой" } Write-Success "Индекс перенормализован" Write-WarnMsg "Проверьте git status — возможны массовые изменения EOL" } } if (-not $Quiet) { Write-Host "" Write-Host "============================================================" Write-Host "📊 Итог настройки под выгрузку конфигуратора 1С" -ForegroundColor Cyan Write-Host "============================================================" Write-Host " ОС: Windows" Write-Host " Каталог: $TargetDir" Write-Host " Encoding: UTF-8 (BOM сохраняется в содержимом файлов)" Write-Host " EOL (выгрузка): CRLF в рабочей копии (*.bsl, *.xml, …)" Write-Host " core.autocrlf: false (управляет .gitattributes)" Write-Host " core.quotepath: false" Write-Host " core.longpaths: true" if ($DryRun) { Write-Host "" Write-Host "⚠️ Режим -DryRun: изменения НЕ применены" -ForegroundColor Yellow } else { Write-Host "" Write-Host "✅ Готово" -ForegroundColor Green Write-Host "" Write-Host "Следующие шаги:" -ForegroundColor Cyan Write-Host " 1. git -C `"$TargetDir`" status" Write-Host " 2. git -C `"$TargetDir`" add .gitattributes .gitignore" Write-Host ' 3. git commit -m "Настройки Git для выгрузки конфигуратора 1С"' if (-not $Renormalize) { Write-Host " 4. При необходимости нормализовать EOL:" Write-Host " .\setup-1c-repo.ps1 -Path `"$TargetDir`" -Renormalize" Write-Host " или: git -C `"$TargetDir`" add --renormalize ." } } Write-Host "============================================================" Write-Host "" } exit 0