UNPKG

sourcecontrol

Version:

A modern TypeScript CLI application for source control

122 lines 5.73 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.WorkingDirectoryManager = void 0; const index_1 = require("../../core/index"); const utils_1 = require("../../utils"); const path_1 = __importDefault(require("path")); const internal_1 = require("./internal"); class WorkingDirectoryManager { constructor(repository) { this.workingDirectory = repository.workingDirectory().fullpath(); this.indexPath = path_1.default.join(repository.gitDirectory().fullpath(), index_1.IndexManager.INDEX_FILE_NAME); this.fileService = new internal_1.FileOperationService(repository, this.workingDirectory); this.treeAnalyzer = new internal_1.TreeAnalyzer(repository); this.validator = new internal_1.WorkingDirectoryValidator(this.workingDirectory); this.atomicManager = new internal_1.AtomicOperationManager(this.fileService); this.indexUpdater = new internal_1.IndexUpdater(this.workingDirectory, this.indexPath); } async updateToCommit(commitSha, options = {}) { utils_1.logger.debug(`Updating working directory to commit ${commitSha}`); try { if (!options.force) { await this.performSafetyChecks(); } const { operations, targetFiles } = await this.analyzeRequiredChanges(commitSha); if (operations.length === 0) { utils_1.logger.info('Working directory is already up to date'); return { success: true, filesChanged: 0, operationResult: { success: true, operationsApplied: 0, totalOperations: 0 }, error: null, }; } if (options.dryRun) { return await this.performDryRun(operations); } const operationResult = await this.atomicManager.executeAtomically(operations); if (!operationResult.success) { return { success: false, filesChanged: operationResult.operationsApplied, error: operationResult.error ? operationResult.error : null, operationResult, }; } const indexUpdateResult = await this.indexUpdater.updateToMatch(targetFiles); if (!indexUpdateResult.success) { utils_1.logger.error('File operations succeeded but index update failed:', indexUpdateResult.errors); } utils_1.logger.info(`Successfully updated ${operationResult.operationsApplied} files`); return { success: true, filesChanged: operationResult.operationsApplied, operationResult, indexUpdateResult, error: null, }; } catch (error) { utils_1.logger.error('Failed to update working directory:', error); return { success: false, filesChanged: 0, operationResult: { success: false, operationsApplied: 0, totalOperations: 0 }, error: error, }; } } async isClean() { const index = await index_1.GitIndex.read(this.indexPath); return await this.validator.validateCleanState(index); } async analyzeRequiredChanges(commitSha) { const targetFiles = await this.treeAnalyzer.getCommitFiles(commitSha); const currentIndex = await index_1.GitIndex.read(this.indexPath); const indexFiles = this.treeAnalyzer.getIndexFiles(currentIndex); const { operations, summary } = this.treeAnalyzer.analyzeChanges(indexFiles, targetFiles); return { operations, targetFiles, summary, }; } async performSafetyChecks() { const status = await this.isClean(); if (!status.clean) { const filesList = status.modifiedFiles.slice(0, 10).join('\n '); const moreFiles = status.modifiedFiles.length > 10 ? `\n ... and ${status.modifiedFiles.length - 10} more files` : ''; throw new Error(`error: Your local changes to the following files would be overwritten by checkout:\n` + ` ${filesList}${moreFiles}\n` + `Please commit your changes or stash them before you switch branches.\n` + `Aborting`); } } async performDryRun(operations) { const dryRunResult = await this.atomicManager.dryRun(operations); utils_1.logger.info('Dry run results:'); utils_1.logger.info(` Would create: ${dryRunResult.analysis.willCreate.length} files`); utils_1.logger.info(` Would modify: ${dryRunResult.analysis.willModify.length} files`); utils_1.logger.info(` Would delete: ${dryRunResult.analysis.willDelete.length} files`); if (dryRunResult.analysis.conflicts.length > 0) { utils_1.logger.warn(' Conflicts:', dryRunResult.analysis.conflicts); } return { success: dryRunResult.valid, filesChanged: 0, operationResult: { success: dryRunResult.valid, operationsApplied: 0, totalOperations: operations.length, }, error: dryRunResult.valid ? null : new Error(`Conflicts: ${dryRunResult.errors.join(', ')}`), }; } } exports.WorkingDirectoryManager = WorkingDirectoryManager; //# sourceMappingURL=work-dir-manager.js.map