{#if show}
{ if (e.key === 'Escape') handleModalClose(); if (e.key === 'Tab') trapFocus(e); }} role="dialog" aria-modal="true" tabindex="-1" aria-label={`${$t.git?.management || 'Управление Git'}: ${dashboardTitle}`}>

{$t.git?.management || 'Управление Git'}

{dashboardTitle} · slug: {dashboardId}

{#if model.gitError} {/if}
{#if model.checkingStatus}
{:else if !model.initialized} model.handleCreateRemoteRepo()} onInit={() => model.handleInit()} /> {:else}
{#if model.commitCompleted}
{$t.git?.commit_success_banner || '✅ Изменения закоммичены.'} {$t.git?.commit_next_step || 'Следующий шаг: вкладка «Релиз» для продвижения между ветками или «Серверные операции» для Pull/Push/Deploy.'}
{/if} commit.hash === model.deploymentStatus?.environments.find((environment) => environment.stage === 'preprod')?.commit_hash) || null} hasWorkspaceChanges={model.hasWorkspaceChanges} changedFilesCount={model.changedFilesCount} validatingPreprod={model.validatingPreprod} onSync={() => model.handleSync()} onDeployPreprod={() => model.openDeployModal('PREPROD')} onValidatePreprod={() => model.validatePreprodDeployment()} onOpenRelease={() => (model.activeTab = 'release')} onCompare={async () => { const prod = model.environmentHistories.prod?.[0]; const dev = model.environmentHistories.dev?.[0]; if (!prod || !dev) return; model.selectVersion(prod.hash); model.selectVersion(dev.hash, true); const result = await model.getSelectedVersionsDiff(); if (result?.diff) { model.workspaceDiff = res.diff; model.activeTab = 'workspace'; notifications.success($t.git?.viz_diff_ready || 'Dashboard changes loaded for comparison'); } }} /> {#if model.hasWorkspaceChanges}

{$t.git?.workspace_pending_title || 'Есть несохранённые изменения'}

{($t.git?.workspace_pending_hint || '{count} файлов изменены. Они не войдут в текущую публикацию, пока вы не сохраните новую версию.').replace('{count}', String(model.changedFilesCount))}

{/if} model.openFeatureDraft(branch)} onCreate={() => { model.showCreateBranchDialog = true; }} onTransferred={async () => { await model.refreshBranches(); await model.loadWorkspace(); void model.loadEnvironmentHistories(); }} />
{$t.git?.technical_details || 'Технические детали'} {#if model.hasOriginConfigMismatch}

Привязка репозитория использует другой Git-сервер: origin — {model.originHost}, выбранный сервер — {model.configHost}. Push заблокирован до перепривязки, чтобы не отправить изменения не в тот репозиторий.

{$t.git?.git_server_mismatch_fix || 'Настроить'}
{/if}
{$t.git?.working_branch || 'Рабочая ветка'}:
model.handleBranchChanged(event)} onmerge={handleOpenMergeDialog} />
model.selectVersion(hash, secondary)} onClearSelection={() => model.clearVersionSelection()} onRequestDiff={async () => { const res = await model.getSelectedVersionsDiff(); if (res?.diff) { model.workspaceDiff = res.diff; model.activeTab = 'workspace'; notifications.success($t.git?.viz_diff_ready || 'Dashboard changes loaded for comparison'); } }} onDeployVersion={(hash) => model.openDeployModal('PREPROD', hash)} />
{#if model.activeTab === 'workspace'} model.handleSync()} onGenerateMessage={() => model.handleGenerateMessage()} onGenerateSummary={() => model.handleGenerateWorkspaceSummary(true)} onCommit={() => model.handleCommit()} /> {:else if model.activeTab === 'release'} model.createRelease()} onApprove={() => model.approveRelease()} onPublish={() => model.publishRelease()} onSavePolicy={() => model.saveReleasePolicy()} /> {:else} model.handlePull()} onPush={() => model.handlePush()} /> {/if}
{/if}
model.loadMergeRecoveryState()} onCopyCommands={() => model.handleCopyUnfinishedMergeCommands()} onOpenConflictResolver={() => model.handleOpenConflictResolver()} onAbortMerge={() => model.handleAbortUnfinishedMerge()} onContinueMerge={() => model.handleContinueUnfinishedMerge()} onClose={() => model.closeUnfinishedMergeDialog()} />
{/if} model.handleResolveConflicts(e)} /> {#if model.showDeployConfirm}
{ model.showDeployConfirm = false; }} onkeydown={(e) => { if (e.key === 'Escape') model.showDeployConfirm = false; }}>
e.stopPropagation()}>

{$t.git?.deploy || 'Deploy to Environment'}

{$t.git?.deploy_confirm_intro || 'Подтвердите деплой. Введите slug дашборда:'} {model.deployConfirmSlug}

{$t.git?.deploy_confirm_dashboard || 'Dashboard'}
{dashboardTitle || dashboardId}
{$t.git?.deploy_confirm_branch || 'Source branch'}
{model.currentBranch}
{$t.git?.deploy_confirm_stage || 'Lifecycle stage'}
{model.currentWorkflowStage}
{$t.git?.deploy_confirm_target || 'Target'}
{model.preferredDeployTargetStage || model.currentEnvStage || 'PROD'}
{$t.git?.deploy_confirm_changes || 'Changed files'}
{model.changedFilesCount}
{#if model.workspaceStatus?.last_commit_hash}
{$t.git?.deploy_confirm_last_commit || 'Last commit'}
{model.workspaceStatus.last_commit_hash.slice(0, 8)}
{/if} {#if model.workspaceStatus?.last_commit_author}
{$t.git?.deploy_confirm_author || 'Author'}
{model.workspaceStatus.last_commit_author}
{/if} {#if model.workspaceStatus?.last_commit_message}
{$t.git?.deploy_confirm_message || 'Commit message'}
{model.workspaceStatus.last_commit_message}
{/if}
{ if (e.key === 'Enter' && deployConfirmInput.trim()) model.confirmDeploy(deployConfirmInput); }} autofocus />
{/if} model.refreshBranches()} /> { await model.refreshBranches(); await model.loadWorkspace(); void model.loadEnvironmentHistories(); }} /> {#if model.showCreateRepoDialog}
{ if (e.target === e.currentTarget) model.showCreateRepoDialog = false; }} onkeydown={(e) => { if (e.key === 'Escape') model.showCreateRepoDialog = false; }} role="dialog" aria-modal="true" aria-label={$t.git?.create_repo_dialog?.title || 'Create repository'}>

{$t.git?.create_repo_dialog?.title || 'Create repository'}

{($t.git?.create_repo_dialog?.name_prompt || 'Repository name for {provider}:').replace('{provider}', model.createRepoProviderLabel)}

{ if (e.key === 'Enter' && model.pendingRepoName.trim()) model.confirmCreateRemoteRepo(); }} />
{/if}