Skip to content

Commit

Permalink
feat(revset): allow branches() to accept a text pattern
Browse files Browse the repository at this point in the history
  • Loading branch information
claytonrcarter committed Nov 9, 2023
1 parent 2691260 commit 8ff04b6
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 14 deletions.
62 changes: 56 additions & 6 deletions git-branchless-revset/src/builtins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ use eden_dag::nameset::hints::Hints;

use lib::core::dag::CommitSet;
use lib::core::eventlog::{EventLogDb, EventReplayer};
use lib::core::repo_ext::RepoExt;
use lib::core::rewrite::find_rewrite_target;
use lib::git::{
get_latest_test_command_path, get_test_tree_dir, Commit, MaybeZeroOid, Repo,
SerializedNonZeroOid, SerializedTestResult, TEST_ABORT_EXIT_CODE, TEST_INDETERMINATE_EXIT_CODE,
TEST_SUCCESS_EXIT_CODE,
get_latest_test_command_path, get_test_tree_dir, CategorizedReferenceName, Commit,
MaybeZeroOid, Repo, SerializedNonZeroOid, SerializedTestResult, TEST_ABORT_EXIT_CODE,
TEST_INDETERMINATE_EXIT_CODE, TEST_SUCCESS_EXIT_CODE,
};
use std::borrow::Cow;
use std::collections::HashMap;
use std::collections::{HashMap, HashSet};
use std::convert::TryFrom;
use tracing::{instrument, warn};

Expand Down Expand Up @@ -179,8 +180,57 @@ fn fn_heads(ctx: &mut Context, name: &str, args: &[Expr]) -> EvalResult {

#[instrument]
fn fn_branches(ctx: &mut Context, name: &str, args: &[Expr]) -> EvalResult {
eval0(ctx, name, args)?;
Ok(ctx.dag.branch_commits.clone())
let pattern = match eval0_or_1_pattern(ctx, name, args)? {
Some(pattern) => pattern,
None => return Ok(ctx.dag.branch_commits.clone()),
};

let all_branch_commits: HashSet<_> = ctx
.dag
.commit_set_to_vec(&ctx.dag.branch_commits)
.map_err(EvalError::OtherError)?
.into_iter()
.collect();
let branch_commits = make_pattern_matcher(
ctx,
name,
args,
Box::new(move |repo: &Repo, commit: &Commit| {
if !all_branch_commits.contains(&commit.get_oid()) {
return Ok(false);
}

let branch_oid_to_names = match repo.get_references_snapshot() {
Ok(snapshot) => snapshot.branch_oid_to_names,
Err(err) => {
warn!(?repo, ?err, "Could not get references snapshot for repo");
return Ok(false);
}
};
let branches_at_commit = match branch_oid_to_names.get(&commit.get_oid()) {
Some(branches) => branches,
None => return Ok(false),
};

let result = branches_at_commit
.iter()
.filter_map(
|branch_name| match CategorizedReferenceName::new(branch_name) {
name @ CategorizedReferenceName::LocalBranch { .. } => {
Some(name.render_suffix())
}
// we only care about local branches
CategorizedReferenceName::RemoteBranch { .. }
| CategorizedReferenceName::OtherRef { .. } => None,
},
)
.any(|branch_name| pattern.matches_text(branch_name.as_str()));

Ok(result)
}),
)?;

Ok(branch_commits)
}

#[instrument]
Expand Down
89 changes: 81 additions & 8 deletions git-branchless-revset/src/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1216,10 +1216,7 @@ mod tests {
)?;

{
let expr = Expr::FunctionCall(
Cow::Borrowed("merges"),
vec![]
);
let expr = Expr::FunctionCall(Cow::Borrowed("merges"), vec![]);
insta::assert_debug_snapshot!(eval_and_sort(&effects, &repo, &mut dag, &expr), @r###"
Ok(
[
Expand All @@ -1241,10 +1238,7 @@ mod tests {

let expr = Expr::FunctionCall(
Cow::Borrowed("not"),
vec![Expr::FunctionCall(
Cow::Borrowed("merges"),
vec![]
)],
vec![Expr::FunctionCall(Cow::Borrowed("merges"), vec![])],
);
insta::assert_debug_snapshot!(eval_and_sort(&effects, &repo, &mut dag, &expr), @r###"
Ok(
Expand Down Expand Up @@ -1274,6 +1268,85 @@ mod tests {
Ok(())
}

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

git.detach_head()?;
git.commit_file("test1", 1)?;
git.run(&["branch", "test-1"])?;
git.commit_file("test2", 2)?;
git.run(&["branch", "test-2"])?;

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("branches"), 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",
},
},
],
)
"###);

let expr = Expr::FunctionCall(
Cow::Borrowed("branches"),
vec![Expr::Name(Cow::Borrowed("glob:test*"))],
);
insta::assert_debug_snapshot!(eval_and_sort(&effects, &repo, &mut dag, &expr), @r###"
Ok(
[
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 8ff04b6

Please sign in to comment.