Skip to content

Commit 0460ed7

Browse files
committed
Auto-stage resolved conflicts when switching branches
Fixes #86
1 parent b15173d commit 0460ed7

2 files changed

Lines changed: 43 additions & 0 deletions

File tree

app/src/lib/git/stage.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,37 @@ export async function stageManualConflictResolution(
6161
assertNever(chosen, 'unaccounted for git status entry possibility')
6262
}
6363
}
64+
65+
/**
66+
* Stages all resolved conflict files before a checkout operation to prevent
67+
* "error: you need to resolve your current index first" from git.
68+
*
69+
* Handles two kinds of resolved conflicts:
70+
* - Text conflicts resolved in an external editor (conflictMarkerCount === 0)
71+
* - Manual conflicts where the user chose ours/theirs in the Desktop UI
72+
*/
73+
export async function stageResolvedConflictFiles(
74+
repository: Repository,
75+
files: ReadonlyArray<WorkingDirectoryFileChange>,
76+
manualResolutions: ReadonlyMap<string, ManualConflictResolution>
77+
): Promise<void> {
78+
for (const file of files) {
79+
const { status } = file
80+
if (!isConflictedFileStatus(status)) {
81+
continue
82+
}
83+
84+
const manualResolution = manualResolutions.get(file.path)
85+
86+
if (manualResolution !== undefined) {
87+
// Binary/manual conflict resolved via Desktop UI — stage it
88+
await stageManualConflictResolution(repository, file, manualResolution)
89+
} else if (
90+
isConflictWithMarkers(status) &&
91+
status.conflictMarkerCount === 0
92+
) {
93+
// Text conflict resolved in external editor — stage it
94+
await addConflictedFile(repository, file)
95+
}
96+
}
97+
}

app/src/lib/stores/app-store.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ import {
286286
import { determineMergeability } from '../git/merge-tree'
287287
import { reorder } from '../git/reorder'
288288
import { squash } from '../git/squash'
289+
import { stageResolvedConflictFiles } from '../git/stage'
289290
import {
290291
createDesktopStashEntry,
291292
dropDesktopStashEntry,
@@ -4428,6 +4429,14 @@ export class AppStore extends TypedBaseStore<IAppState> {
44284429
}
44294430
}
44304431

4432+
// Auto-stage resolved conflict files before checkout to prevent
4433+
// "error: you need to resolve your current index first"
4434+
await stageResolvedConflictFiles(
4435+
repository,
4436+
changesState.workingDirectory.files,
4437+
changesState.conflictState?.manualResolutions ?? new Map()
4438+
)
4439+
44314440
return this.withRefreshedGitHubRepository(repository, repository => {
44324441
// We always want to end with refreshing the repository regardless of
44334442
// whether the checkout succeeded or not in order to present the most

0 commit comments

Comments
 (0)