mirror of
https://github.com/martinvonz/jj.git
synced 2025-02-04 18:56:49 +00:00
new: extract out ensure_no_commit_loop
function
This commit is contained in:
parent
256a51f835
commit
bbadc6f14f
1 changed files with 29 additions and 13 deletions
|
@ -14,11 +14,12 @@
|
||||||
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use jj_lib::backend::CommitId;
|
use jj_lib::backend::CommitId;
|
||||||
use jj_lib::commit::CommitIteratorExt;
|
use jj_lib::commit::CommitIteratorExt;
|
||||||
use jj_lib::repo::Repo;
|
use jj_lib::repo::{ReadonlyRepo, Repo};
|
||||||
use jj_lib::revset::{RevsetExpression, RevsetIteratorExt};
|
use jj_lib::revset::{RevsetExpression, RevsetIteratorExt};
|
||||||
use jj_lib::rewrite::{merge_commit_trees, rebase_commit};
|
use jj_lib::rewrite::{merge_commit_trees, rebase_commit};
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
@ -111,18 +112,11 @@ Please use `jj new 'all:x|y'` instead of `jj new --allow-large-revsets x y`.",
|
||||||
let children_commit_ids = children_commits.iter().ids().cloned().collect();
|
let children_commit_ids = children_commits.iter().ids().cloned().collect();
|
||||||
let children_expression = RevsetExpression::commits(children_commit_ids);
|
let children_expression = RevsetExpression::commits(children_commit_ids);
|
||||||
let parents_expression = children_expression.parents();
|
let parents_expression = children_expression.parents();
|
||||||
if let Some(commit_id) = children_expression
|
ensure_no_commit_loop(
|
||||||
.dag_range_to(&parents_expression)
|
workspace_command.repo(),
|
||||||
.evaluate_programmatic(workspace_command.repo().as_ref())?
|
&children_expression,
|
||||||
.iter()
|
&parents_expression,
|
||||||
.next()
|
)?;
|
||||||
{
|
|
||||||
return Err(user_error(format!(
|
|
||||||
"Refusing to create a loop: commit {} would be both an ancestor and a descendant \
|
|
||||||
of the new commit",
|
|
||||||
short_commit_hash(&commit_id),
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
// Manually collect the parent commit IDs to preserve the order of parents.
|
// Manually collect the parent commit IDs to preserve the order of parents.
|
||||||
parent_commit_ids = children_commits
|
parent_commit_ids = children_commits
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -220,3 +214,25 @@ Please use `jj new 'all:x|y'` instead of `jj new --allow-large-revsets x y`.",
|
||||||
tx.finish(ui, "new empty commit")?;
|
tx.finish(ui, "new empty commit")?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Ensure that there is no possible cycle between the potential children and
|
||||||
|
/// parents of the new commit.
|
||||||
|
fn ensure_no_commit_loop(
|
||||||
|
repo: &ReadonlyRepo,
|
||||||
|
children_expression: &Rc<RevsetExpression>,
|
||||||
|
parents_expression: &Rc<RevsetExpression>,
|
||||||
|
) -> Result<(), CommandError> {
|
||||||
|
if let Some(commit_id) = children_expression
|
||||||
|
.dag_range_to(parents_expression)
|
||||||
|
.evaluate_programmatic(repo)?
|
||||||
|
.iter()
|
||||||
|
.next()
|
||||||
|
{
|
||||||
|
return Err(user_error(format!(
|
||||||
|
"Refusing to create a loop: commit {} would be both an ancestor and a descendant of \
|
||||||
|
the new commit",
|
||||||
|
short_commit_hash(&commit_id),
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue