Skip to content

Commit 19cf8c2

Browse files
committed
Instead of filtering, take any conflicting file and surface it.
Merges might fail in files that weren't touched.
1 parent b98ea20 commit 19cf8c2

File tree

2 files changed

+29
-17
lines changed
  • crates/but-workspace/src/commit_engine
  • packages/mcp/src/shared/entities

2 files changed

+29
-17
lines changed

crates/but-workspace/src/commit_engine/mod.rs

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,9 @@ pub enum RejectionReason {
148148
CherryPickMergeConflict,
149149
/// The final merge of the workspace commit failed with a conflict.
150150
WorkspaceMergeConflict,
151+
/// The final merge of the workspace commit failed with a conflict,
152+
/// but the involved file wasn't anything the user provided as diff-spec.
153+
WorkspaceMergeConflictOfUnrelatedFile,
151154
/// This is just a theoretical possibility that *could* happen if somebody deletes a file that was there before *right after* we checked its
152155
/// metadata and found that it still exists.
153156
/// So if you see this, you could also have won the lottery.
@@ -444,23 +447,31 @@ pub fn create_commit_and_update_refs(
444447
conflicts: &[BString],
445448
changes: &[DiffSpec],
446449
) -> anyhow::Result<()> {
447-
outcome.rejected_specs.extend(conflicts.iter().filter_map(
448-
|conflicting_rela_path| {
449-
changes.iter().find_map(|spec| {
450-
(spec.path == *conflicting_rela_path
451-
|| spec.previous_path.as_ref() == Some(conflicting_rela_path))
452-
.then_some((
453-
RejectionReason::WorkspaceMergeConflict,
454-
spec.to_owned(),
455-
))
456-
})
457-
},
458-
));
459-
if outcome.rejected_specs.is_empty() {
460-
bail!(
461-
"BUG: should have found a tree-change for each conflicting path, but came up with nothing"
462-
)
463-
}
450+
outcome
451+
.rejected_specs
452+
.extend(conflicts.iter().map(|conflicting_rela_path| {
453+
changes
454+
.iter()
455+
.find_map(|spec| {
456+
(spec.path == *conflicting_rela_path
457+
|| spec.previous_path.as_ref()
458+
== Some(conflicting_rela_path))
459+
.then_some((
460+
RejectionReason::WorkspaceMergeConflict,
461+
spec.to_owned(),
462+
))
463+
})
464+
.unwrap_or_else(|| {
465+
(
466+
RejectionReason::WorkspaceMergeConflictOfUnrelatedFile,
467+
DiffSpec {
468+
previous_path: None,
469+
path: conflicting_rela_path.to_owned(),
470+
hunk_headers: vec![],
471+
},
472+
)
473+
})
474+
}));
464475
outcome.new_commit = None;
465476
outcome.changed_tree_pre_cherry_pick = None;
466477
Ok(())

packages/mcp/src/shared/entities/stacks.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ export const RejectedChangesSchema = z.tuple([
9292
'NoEffectiveChanges',
9393
'CherryPickMergeConflict',
9494
'WorkspaceMergeConflict',
95+
'WorkspaceMergeConflictOfUnrelatedFile',
9596
'WorktreeFileMissingForObjectConversion',
9697
'FileToLargeOrBinary',
9798
'PathNotFoundInBaseTree',

0 commit comments

Comments
 (0)