|
7 | 7 | import * as pathLib from 'path'; |
8 | 8 | import * as vscode from 'vscode'; |
9 | 9 | import { Repository } from './api/api'; |
10 | | -import { GitErrorCodes } from './api/api1'; |
| 10 | +import { GitErrorCodes, Status } from './api/api1'; |
11 | 11 | import { CommentReply, findActiveHandler, resolveCommentHandler } from './commentHandlerResolver'; |
12 | 12 | import { commands } from './common/executeCommands'; |
13 | 13 | import Logger from './common/logger'; |
| 14 | +import * as PersistentState from './common/persistentState'; |
14 | 15 | import { FILE_LIST_LAYOUT, PR_SETTINGS_NAMESPACE } from './common/settingKeys'; |
15 | 16 | import { editQuery } from './common/settingsUtils'; |
16 | 17 | import { ITelemetry } from './common/telemetry'; |
@@ -52,50 +53,69 @@ import { RepositoryChangesNode } from './view/treeNodes/repositoryChangesNode'; |
52 | 53 | // Modal dialog options for handling uncommitted changes during PR checkout |
53 | 54 | const STASH_CHANGES = vscode.l10n.t('Stash changes'); |
54 | 55 | const DISCARD_CHANGES = vscode.l10n.t('Discard changes'); |
| 56 | +const DONT_SHOW_AGAIN = vscode.l10n.t('Try to checkout anyway and don\'t show again'); |
| 57 | + |
| 58 | +// Constants for persistent state storage |
| 59 | +const UNCOMMITTED_CHANGES_SCOPE = vscode.l10n.t('uncommitted changes warning'); |
| 60 | +const UNCOMMITTED_CHANGES_STORAGE_KEY = 'showWarning'; |
55 | 61 |
|
56 | 62 | /** |
57 | 63 | * Shows a modal dialog when there are uncommitted changes during PR checkout |
58 | 64 | * @param repository The git repository with uncommitted changes |
59 | 65 | * @returns Promise<boolean> true if user chose to proceed (after staging/discarding), false if cancelled |
60 | 66 | */ |
61 | 67 | async function handleUncommittedChanges(repository: Repository): Promise<boolean> { |
62 | | - const hasWorkingTreeChanges = repository.state.workingTreeChanges.length > 0; |
| 68 | + // Check if user has disabled the warning using persistent state |
| 69 | + if (PersistentState.fetch(UNCOMMITTED_CHANGES_SCOPE, UNCOMMITTED_CHANGES_STORAGE_KEY) === false) { |
| 70 | + return true; // User has disabled warnings, proceed without showing dialog |
| 71 | + } |
| 72 | + |
| 73 | + // Filter out untracked files as they typically don't conflict with PR checkout |
| 74 | + const trackedWorkingTreeChanges = repository.state.workingTreeChanges.filter(change => change.status !== Status.UNTRACKED); |
| 75 | + const hasTrackedWorkingTreeChanges = trackedWorkingTreeChanges.length > 0; |
63 | 76 | const hasIndexChanges = repository.state.indexChanges.length > 0; |
64 | 77 |
|
65 | | - if (!hasWorkingTreeChanges && !hasIndexChanges) { |
66 | | - return true; // No uncommitted changes, proceed |
| 78 | + if (!hasTrackedWorkingTreeChanges && !hasIndexChanges) { |
| 79 | + return true; // No tracked uncommitted changes, proceed |
67 | 80 | } |
68 | 81 |
|
69 | 82 | const modalResult = await vscode.window.showInformationMessage( |
70 | | - vscode.l10n.t('You have uncommitted changes that would be overwritten by checking out this pull request.'), |
| 83 | + vscode.l10n.t('You have uncommitted changes that might be overwritten by checking out this pull request.'), |
71 | 84 | { |
72 | 85 | modal: true, |
73 | 86 | detail: vscode.l10n.t('Choose how to handle your uncommitted changes before checking out the pull request.'), |
74 | 87 | }, |
75 | 88 | STASH_CHANGES, |
76 | 89 | DISCARD_CHANGES, |
| 90 | + DONT_SHOW_AGAIN, |
77 | 91 | ); |
78 | 92 |
|
79 | 93 | if (!modalResult) { |
80 | 94 | return false; // User cancelled |
81 | 95 | } |
82 | 96 |
|
| 97 | + if (modalResult === DONT_SHOW_AGAIN) { |
| 98 | + // Store preference to never show this dialog again using persistent state |
| 99 | + PersistentState.store(UNCOMMITTED_CHANGES_SCOPE, UNCOMMITTED_CHANGES_STORAGE_KEY, false); |
| 100 | + return true; // Proceed with checkout |
| 101 | + } |
| 102 | + |
83 | 103 | try { |
84 | 104 | if (modalResult === STASH_CHANGES) { |
85 | 105 | // Stash all changes (working tree changes + any unstaged changes) |
86 | 106 | const allChangedFiles = [ |
87 | | - ...repository.state.workingTreeChanges.map(change => change.uri.fsPath), |
| 107 | + ...trackedWorkingTreeChanges.map(change => change.uri.fsPath), |
88 | 108 | ...repository.state.indexChanges.map(change => change.uri.fsPath), |
89 | 109 | ]; |
90 | 110 | if (allChangedFiles.length > 0) { |
91 | 111 | await repository.add(allChangedFiles); |
92 | 112 | await vscode.commands.executeCommand('git.stash', repository); |
93 | 113 | } |
94 | 114 | } else if (modalResult === DISCARD_CHANGES) { |
95 | | - // Discard all working tree changes |
96 | | - const workingTreeFiles = repository.state.workingTreeChanges.map(change => change.uri.fsPath); |
97 | | - if (workingTreeFiles.length > 0) { |
98 | | - await repository.clean(workingTreeFiles); |
| 115 | + // Discard all tracked working tree changes |
| 116 | + const trackedWorkingTreeFiles = trackedWorkingTreeChanges.map(change => change.uri.fsPath); |
| 117 | + if (trackedWorkingTreeFiles.length > 0) { |
| 118 | + await repository.clean(trackedWorkingTreeFiles); |
99 | 119 | } |
100 | 120 | } |
101 | 121 | return true; // Successfully handled changes, proceed with checkout |
|
0 commit comments