mirror of
https://github.com/martinvonz/jj.git
synced 2024-11-24 06:19:42 +00:00
merged_tree: propagate errors from conflict iterator
Some checks are pending
binaries / Build binary artifacts (push) Waiting to run
nix / flake check (push) Waiting to run
build / build (, macos-13) (push) Waiting to run
build / build (, macos-14) (push) Waiting to run
build / build (, ubuntu-latest) (push) Waiting to run
build / build (, windows-latest) (push) Waiting to run
build / build (--all-features, ubuntu-latest) (push) Waiting to run
build / Build jj-lib without Git support (push) Waiting to run
build / Check protos (push) Waiting to run
build / Check formatting (push) Waiting to run
build / Check that MkDocs can build the docs (push) Waiting to run
build / Check that MkDocs can build the docs with latest Python and uv (push) Waiting to run
build / cargo-deny (advisories) (push) Waiting to run
build / cargo-deny (bans licenses sources) (push) Waiting to run
build / Clippy check (push) Waiting to run
Codespell / Codespell (push) Waiting to run
website / prerelease-docs-build-deploy (ubuntu-latest) (push) Waiting to run
Scorecards supply-chain security / Scorecards analysis (push) Waiting to run
Some checks are pending
binaries / Build binary artifacts (push) Waiting to run
nix / flake check (push) Waiting to run
build / build (, macos-13) (push) Waiting to run
build / build (, macos-14) (push) Waiting to run
build / build (, ubuntu-latest) (push) Waiting to run
build / build (, windows-latest) (push) Waiting to run
build / build (--all-features, ubuntu-latest) (push) Waiting to run
build / Build jj-lib without Git support (push) Waiting to run
build / Check protos (push) Waiting to run
build / Check formatting (push) Waiting to run
build / Check that MkDocs can build the docs (push) Waiting to run
build / Check that MkDocs can build the docs with latest Python and uv (push) Waiting to run
build / cargo-deny (advisories) (push) Waiting to run
build / cargo-deny (bans licenses sources) (push) Waiting to run
build / Clippy check (push) Waiting to run
Codespell / Codespell (push) Waiting to run
website / prerelease-docs-build-deploy (ubuntu-latest) (push) Waiting to run
Scorecards supply-chain security / Scorecards analysis (push) Waiting to run
This commit is contained in:
parent
9ec216a2bb
commit
10c90a5099
3 changed files with 33 additions and 16 deletions
|
@ -51,6 +51,7 @@ use clap_complete::ArgValueCandidates;
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use indexmap::IndexSet;
|
use indexmap::IndexSet;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
use jj_lib::backend::BackendResult;
|
||||||
use jj_lib::backend::ChangeId;
|
use jj_lib::backend::ChangeId;
|
||||||
use jj_lib::backend::CommitId;
|
use jj_lib::backend::CommitId;
|
||||||
use jj_lib::backend::MergedTreeId;
|
use jj_lib::backend::MergedTreeId;
|
||||||
|
@ -2467,7 +2468,7 @@ fn update_stale_working_copy(
|
||||||
|
|
||||||
#[instrument(skip_all)]
|
#[instrument(skip_all)]
|
||||||
pub fn print_conflicted_paths(
|
pub fn print_conflicted_paths(
|
||||||
conflicts: Vec<(RepoPathBuf, MergedTreeValue)>,
|
conflicts: Vec<(RepoPathBuf, BackendResult<MergedTreeValue>)>,
|
||||||
formatter: &mut dyn Formatter,
|
formatter: &mut dyn Formatter,
|
||||||
workspace_command: &WorkspaceCommandHelper,
|
workspace_command: &WorkspaceCommandHelper,
|
||||||
) -> Result<(), CommandError> {
|
) -> Result<(), CommandError> {
|
||||||
|
@ -2481,7 +2482,9 @@ pub fn print_conflicted_paths(
|
||||||
.map(|p| format!("{:width$}", p, width = max_path_len.min(32) + 3));
|
.map(|p| format!("{:width$}", p, width = max_path_len.min(32) + 3));
|
||||||
|
|
||||||
for ((_, conflict), formatted_path) in std::iter::zip(conflicts, formatted_paths) {
|
for ((_, conflict), formatted_path) in std::iter::zip(conflicts, formatted_paths) {
|
||||||
let conflict = conflict.simplify();
|
// TODO: Display the error for the path instead of failing the whole command if
|
||||||
|
// `conflict` is an error?
|
||||||
|
let conflict = conflict?.simplify();
|
||||||
let sides = conflict.num_sides();
|
let sides = conflict.num_sides();
|
||||||
let n_adds = conflict.adds().flatten().count();
|
let n_adds = conflict.adds().flatten().count();
|
||||||
let deletions = sides - n_adds;
|
let deletions = sides - n_adds;
|
||||||
|
|
|
@ -182,7 +182,7 @@ impl MergedTree {
|
||||||
/// all sides are trees, so tree/file conflicts will be reported as a single
|
/// all sides are trees, so tree/file conflicts will be reported as a single
|
||||||
/// conflict, not one for each path in the tree.
|
/// conflict, not one for each path in the tree.
|
||||||
// TODO: Restrict this by a matcher (or add a separate method for that).
|
// TODO: Restrict this by a matcher (or add a separate method for that).
|
||||||
pub fn conflicts(&self) -> impl Iterator<Item = (RepoPathBuf, MergedTreeValue)> {
|
pub fn conflicts(&self) -> impl Iterator<Item = (RepoPathBuf, BackendResult<MergedTreeValue>)> {
|
||||||
ConflictIterator::new(self)
|
ConflictIterator::new(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -651,20 +651,25 @@ impl ConflictIterator {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Iterator for ConflictIterator {
|
impl Iterator for ConflictIterator {
|
||||||
type Item = (RepoPathBuf, MergedTreeValue);
|
type Item = (RepoPathBuf, BackendResult<MergedTreeValue>);
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
while let Some(top) = self.stack.last_mut() {
|
while let Some(top) = self.stack.last_mut() {
|
||||||
if let Some((path, tree_values)) = top.entries.pop() {
|
if let Some((path, tree_values)) = top.entries.pop() {
|
||||||
// TODO: propagate errors
|
match tree_values.to_tree_merge(&self.store, &path) {
|
||||||
if let Some(trees) = tree_values.to_tree_merge(&self.store, &path).unwrap() {
|
Ok(Some(trees)) => {
|
||||||
// If all sides are trees or missing, descend into the merged tree
|
// If all sides are trees or missing, descend into the merged tree
|
||||||
self.stack.push(ConflictsDirItem::from(&trees));
|
self.stack.push(ConflictsDirItem::from(&trees));
|
||||||
} else {
|
}
|
||||||
// Otherwise this is a conflict between files, trees, etc. If they could
|
Ok(None) => {
|
||||||
// be automatically resolved, they should have been when the top-level
|
// Otherwise this is a conflict between files, trees, etc. If they could
|
||||||
// tree conflict was written, so we assume that they can't be.
|
// be automatically resolved, they should have been when the top-level
|
||||||
return Some((path, tree_values));
|
// tree conflict was written, so we assume that they can't be.
|
||||||
|
return Some((path, Ok(tree_values)));
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
return Some((path, Err(err)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.stack.pop();
|
self.stack.pop();
|
||||||
|
|
|
@ -638,7 +638,10 @@ fn test_conflict_iterator() {
|
||||||
vec![base1.clone()],
|
vec![base1.clone()],
|
||||||
vec![side1.clone(), side2.clone()],
|
vec![side1.clone(), side2.clone()],
|
||||||
));
|
));
|
||||||
let conflicts = tree.conflicts().collect_vec();
|
let conflicts = tree
|
||||||
|
.conflicts()
|
||||||
|
.map(|(path, conflict)| (path, conflict.unwrap()))
|
||||||
|
.collect_vec();
|
||||||
let conflict_at = |path: &RepoPath| {
|
let conflict_at = |path: &RepoPath| {
|
||||||
Merge::from_removes_adds(
|
Merge::from_removes_adds(
|
||||||
vec![base1.path_value(path).unwrap()],
|
vec![base1.path_value(path).unwrap()],
|
||||||
|
@ -672,7 +675,10 @@ fn test_conflict_iterator() {
|
||||||
|
|
||||||
// After we resolve conflicts, there are only non-trivial conflicts left
|
// After we resolve conflicts, there are only non-trivial conflicts left
|
||||||
let tree = tree.resolve().unwrap();
|
let tree = tree.resolve().unwrap();
|
||||||
let conflicts = tree.conflicts().collect_vec();
|
let conflicts = tree
|
||||||
|
.conflicts()
|
||||||
|
.map(|(path, conflict)| (path, conflict.unwrap()))
|
||||||
|
.collect_vec();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
conflicts,
|
conflicts,
|
||||||
vec![
|
vec![
|
||||||
|
@ -725,7 +731,10 @@ fn test_conflict_iterator_higher_arity() {
|
||||||
vec![base1.clone(), base2.clone()],
|
vec![base1.clone(), base2.clone()],
|
||||||
vec![side1.clone(), side2.clone(), side3.clone()],
|
vec![side1.clone(), side2.clone(), side3.clone()],
|
||||||
));
|
));
|
||||||
let conflicts = tree.conflicts().collect_vec();
|
let conflicts = tree
|
||||||
|
.conflicts()
|
||||||
|
.map(|(path, conflict)| (path, conflict.unwrap()))
|
||||||
|
.collect_vec();
|
||||||
let conflict_at = |path: &RepoPath| {
|
let conflict_at = |path: &RepoPath| {
|
||||||
Merge::from_removes_adds(
|
Merge::from_removes_adds(
|
||||||
vec![
|
vec![
|
||||||
|
|
Loading…
Reference in a new issue