Skip to content

Commit

Permalink
feat(revset): add merges() revset
Browse files Browse the repository at this point in the history
This returns merge commits in the given set, or all merge commits.
  • Loading branch information
claytonrcarter committed Nov 8, 2023
1 parent 024542d commit e77d2e4
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 0 deletions.
32 changes: 32 additions & 0 deletions git-branchless-revset/src/builtins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ lazy_static! {
("committer.date", &fn_committer_date),
("exactly", &fn_exactly),
("current", &fn_current),
("merges", &fn_merges),
("tests.passed", &fn_tests_passed),
("tests.failed", &fn_tests_failed),
("tests.fixable", &fn_tests_fixable),
Expand Down Expand Up @@ -513,6 +514,37 @@ fn fn_current(ctx: &mut Context, name: &str, args: &[Expr]) -> EvalResult {
Ok(result.into_iter().collect::<CommitSet>())
}

#[instrument]
fn fn_merges(ctx: &mut Context, name: &str, args: &[Expr]) -> EvalResult {
let arg = eval0_or_1(ctx, name, args)?;
let arg = match arg {
Some(arg) => arg,
None => {
let visible_heads = ctx
.dag
.query_visible_heads()
.map_err(EvalError::OtherError)?;
let visible_commits = ctx.dag.query_ancestors(visible_heads.clone())?;
ctx.dag
.filter_visible_commits(visible_commits)
.map_err(EvalError::OtherError)?
}
};

let commit_oids = ctx
.dag
.commit_set_to_vec(&arg)
.map_err(EvalError::OtherError)?;
let mut result = Vec::new();
for commit_oid in commit_oids {
if ctx.dag.query_parent_names(commit_oid)?.len() > 1 {
result.push(commit_oid)
}
}

Ok(result.into_iter().collect::<CommitSet>())
}

fn read_all_test_results(repo: &Repo, commit: &Commit) -> Option<Vec<SerializedTestResult>> {
let commit_test_dir = get_test_tree_dir(repo, commit).ok()?;
let mut all_results = Vec::new();
Expand Down
86 changes: 86 additions & 0 deletions git-branchless-revset/src/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1188,6 +1188,92 @@ mod tests {
Ok(())
}

#[test]
fn test_eval_merges() -> eyre::Result<()> {
let git = make_git()?;
git.init_repo()?;

git.detach_head()?;
let test1_oid = git.commit_file("test1", 1)?;
let test2_oid = git.commit_file("test2", 2)?;
git.run(&["checkout", "HEAD~2"])?;
git.run(&["merge", "--no-ff", &test1_oid.to_string()])?;
git.run(&["merge", "--no-ff", &test2_oid.to_string()])?;

let effects = Effects::new_suppress_for_test(Glyphs::text());
let repo = git.get_repo()?;
let conn = repo.get_db_conn()?;
let event_log_db = EventLogDb::new(&conn)?;
let event_replayer = EventReplayer::from_event_log_db(&effects, &repo, &event_log_db)?;
let event_cursor = event_replayer.make_default_cursor();
let references_snapshot = repo.get_references_snapshot()?;
let mut dag = Dag::open_and_sync(
&effects,
&repo,
&event_replayer,
event_cursor,
&references_snapshot,
)?;

{
let expr = Expr::FunctionCall(
Cow::Borrowed("merges"),
vec![]
);
insta::assert_debug_snapshot!(eval_and_sort(&effects, &repo, &mut dag, &expr), @r###"
Ok(
[
Commit {
inner: Commit {
id: f486a8b756cd3a928241576aa87827284f3e14d1,
summary: "Merge commit '62fc20d2a290daea0d52bdc2ed2ad4be6491010e' into HEAD",
},
},
Commit {
inner: Commit {
id: 0b75bdca271fdc188e68bca6e054013bbc2a373c,
summary: "Merge commit '96d1c37a3d4363611c49f7e52186e189a04c531f' into HEAD",
},
},
],
)
"###);

let expr = Expr::FunctionCall(
Cow::Borrowed("not"),
vec![Expr::FunctionCall(
Cow::Borrowed("merges"),
vec![]
)],
);
insta::assert_debug_snapshot!(eval_and_sort(&effects, &repo, &mut dag, &expr), @r###"
Ok(
[
Commit {
inner: Commit {
id: f777ecc9b0db5ed372b2615695191a8a17f79f24,
summary: "create initial.txt",
},
},
Commit {
inner: Commit {
id: 62fc20d2a290daea0d52bdc2ed2ad4be6491010e,
summary: "create test1.txt",
},
},
Commit {
inner: Commit {
id: 96d1c37a3d4363611c49f7e52186e189a04c531f,
summary: "create test2.txt",
},
},
],
)
"###);
}
Ok(())
}

#[test]
fn test_eval_aliases() -> eyre::Result<()> {
let git = make_git()?;
Expand Down

0 comments on commit e77d2e4

Please sign in to comment.