Skip to content

Commit 4fadf9a

Browse files
arxanasclaytonrcarter
authored andcommitted
refactor(smartlog): Improvements for sparse smartlog
1 parent ec916d2 commit 4fadf9a

File tree

9 files changed

+55
-57
lines changed

9 files changed

+55
-57
lines changed

git-branchless-lib/src/core/dag.rs

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,6 @@ pub struct Dag {
116116
public_commits: OnceCell<CommitSet>,
117117
visible_commits: OnceCell<CommitSet>,
118118
draft_commits: OnceCell<CommitSet>,
119-
default_smartlog_commits: OnceCell<CommitSet>,
120119
}
121120

122121
impl Dag {
@@ -196,7 +195,6 @@ impl Dag {
196195
public_commits: Default::default(),
197196
visible_commits: Default::default(),
198197
draft_commits: Default::default(),
199-
default_smartlog_commits: Default::default(),
200198
})
201199
}
202200

@@ -389,24 +387,6 @@ impl Dag {
389387
})
390388
}
391389

392-
/// Determine the default set of commits that is shown in the smartlog when
393-
/// no revset is passed.
394-
pub fn query_default_smartlog_commits(&self) -> eyre::Result<&CommitSet> {
395-
self.default_smartlog_commits.get_or_try_init(|| {
396-
let public_commits = self.query_public_commits()?;
397-
let active_commits = self.observed_commits.clone();
398-
let active_heads = self.query().heads(active_commits)?;
399-
let active_heads = active_heads.difference(public_commits);
400-
401-
let active_heads = active_heads
402-
.union(&self.head_commit)
403-
.union(&self.branch_commits)
404-
.union(&self.main_branch_commit);
405-
406-
Ok(active_heads)
407-
})
408-
}
409-
410390
/// Given a CommitSet, return a list of CommitSets, each representing a
411391
/// connected component of the set.
412392
///

git-branchless/src/commands/bug_report.rs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use lib::core::repo_ext::{RepoExt, RepoReferencesSnapshot};
1212
use lib::util::ExitCode;
1313

1414
use crate::commands::smartlog::{make_smartlog_graph, render_graph};
15+
use crate::revset::resolve_default_smartlog_commits;
1516
use lib::core::dag::Dag;
1617
use lib::core::effects::Effects;
1718
use lib::core::eventlog::{Event, EventCursor, EventLogDb, EventReplayer};
@@ -95,7 +96,7 @@ fn describe_event_cursor(
9596
repo: &Repo,
9697
event_log_db: &EventLogDb,
9798
event_replayer: &EventReplayer,
98-
dag: &Dag,
99+
dag: &mut Dag,
99100
head_info: &ResolvedReferenceInfo,
100101
references_snapshot: &RepoReferencesSnapshot,
101102
redactor: &Redactor,
@@ -130,14 +131,8 @@ fn describe_event_cursor(
130131

131132
let glyphs = Glyphs::text();
132133
let effects = Effects::new(glyphs.clone());
133-
let graph = make_smartlog_graph(
134-
&effects,
135-
repo,
136-
dag,
137-
event_replayer,
138-
event_cursor,
139-
dag.query_default_smartlog_commits()?,
140-
)?;
134+
let commits = resolve_default_smartlog_commits(&effects, repo, dag)?;
135+
let graph = make_smartlog_graph(&effects, repo, dag, event_replayer, event_cursor, &commits)?;
141136
let graph_lines = render_graph(
142137
&effects,
143138
repo,
@@ -176,7 +171,7 @@ fn collect_events(effects: &Effects, git_run_info: &GitRunInfo) -> eyre::Result<
176171
let event_log_db = EventLogDb::new(&conn)?;
177172
let event_replayer = EventReplayer::from_event_log_db(effects, &repo, &event_log_db)?;
178173
let event_cursor = event_replayer.make_default_cursor();
179-
let dag = Dag::open_and_sync(
174+
let mut dag = Dag::open_and_sync(
180175
effects,
181176
&repo,
182177
&event_replayer,
@@ -199,7 +194,7 @@ fn collect_events(effects: &Effects, git_run_info: &GitRunInfo) -> eyre::Result<
199194
&repo,
200195
&event_log_db,
201196
&event_replayer,
202-
&dag,
197+
&mut dag,
203198
&head_info,
204199
&references_snapshot,
205200
&redactor,

git-branchless/src/commands/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ use tracing_subscriber::EnvFilter;
4747
use crate::opts::Command;
4848
use crate::opts::Opts;
4949
use crate::opts::ResolveRevsetOptions;
50+
use crate::opts::Revset;
5051
use crate::opts::SnapshotSubcommand;
5152
use crate::opts::WrappedCommand;
5253
use crate::opts::{ColorSetting, TestSubcommand};
@@ -340,7 +341,7 @@ fn do_main_and_drop_locals() -> eyre::Result<i32> {
340341
&git_run_info,
341342
&SmartlogOptions {
342343
event_id,
343-
revset: revset.unwrap_or_else(|| SmartlogOptions::default().revset),
344+
revset: revset.unwrap_or_else(Revset::default_smartlog_revset),
344345
resolve_revset_options,
345346
},
346347
)?,

git-branchless/src/commands/navigation.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use tracing::{instrument, warn};
1616

1717
use crate::commands::smartlog::make_smartlog_graph;
1818
use crate::opts::{SwitchOptions, TraverseCommitsOptions};
19+
use crate::revset::resolve_default_smartlog_commits;
1920
use crate::tui::prompt_select_commit;
2021
use lib::core::config::get_next_interactive;
2122
use lib::core::dag::{sorted_commit_set, CommitSet, Dag};
@@ -544,21 +545,22 @@ pub fn switch(
544545
let event_tx_id = event_log_db.make_transaction_id(now, "checkout")?;
545546
let event_replayer = EventReplayer::from_event_log_db(effects, &repo, &event_log_db)?;
546547
let event_cursor = event_replayer.make_default_cursor();
547-
let dag = Dag::open_and_sync(
548+
let mut dag = Dag::open_and_sync(
548549
effects,
549550
&repo,
550551
&event_replayer,
551552
event_cursor,
552553
&references_snapshot,
553554
)?;
554555

556+
let commits = resolve_default_smartlog_commits(effects, &repo, &mut dag)?;
555557
let graph = make_smartlog_graph(
556558
effects,
557559
&repo,
558560
&dag,
559561
&event_replayer,
560562
event_cursor,
561-
dag.query_default_smartlog_commits()?,
563+
&commits,
562564
)?;
563565

564566
let initial_query = get_initial_query(switch_options);

git-branchless/src/commands/smartlog.rs

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -350,16 +350,7 @@ mod render {
350350
let mut root_commit_oids: Vec<NonZeroOid> = graph
351351
.nodes
352352
.iter()
353-
.filter(|(_oid, node)| {
354-
// Common case: on main w/ no parents in graph, eg a merge base
355-
node.parent.is_none() && node.is_main ||
356-
// Pathological cases: orphaned, garbage collected, etc
357-
node.parent.is_none()
358-
&& !node.is_main
359-
&& node.children.is_empty()
360-
&& node.descendants.is_empty()
361-
&& !node.has_ancestors
362-
})
353+
.filter(|(_oid, node)| node.parent.is_none() && !node.has_ancestors)
363354
.map(|(oid, _node)| oid)
364355
.copied()
365356
.collect();
@@ -632,9 +623,7 @@ mod render {
632623
fn default() -> Self {
633624
Self {
634625
event_id: Default::default(),
635-
revset: Revset(
636-
"((draft() | branches() | @) % main()) | branches() | @".to_string(),
637-
),
626+
revset: Revset::default_smartlog_revset(),
638627
resolve_revset_options: Default::default(),
639628
}
640629
}

git-branchless/src/commands/undo.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use tracing::instrument;
2121

2222
use crate::commands::smartlog::{make_smartlog_graph, render_graph};
2323
use crate::declare_views;
24+
use crate::revset::resolve_default_smartlog_commits;
2425
use crate::tui::{with_siv, SingletonView};
2526
use lib::core::dag::{CommitSet, Dag};
2627
use lib::core::effects::Effects;
@@ -62,14 +63,8 @@ fn render_cursor_smartlog(
6263
reference_name: None,
6364
};
6465

65-
let graph = make_smartlog_graph(
66-
effects,
67-
repo,
68-
&dag,
69-
event_replayer,
70-
event_cursor,
71-
dag.query_default_smartlog_commits()?,
72-
)?;
66+
let commits = resolve_default_smartlog_commits(effects, repo, &mut dag)?;
67+
let graph = make_smartlog_graph(effects, repo, &dag, event_replayer, event_cursor, &commits)?;
7368
let result = render_graph(
7469
effects,
7570
repo,

git-branchless/src/opts.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@ use std::str::FromStr;
1111
#[derive(Clone, Debug)]
1212
pub struct Revset(pub String);
1313

14+
impl Revset {
15+
/// The default revset to render in the smartlog if no revset is provided by the user.
16+
pub fn default_smartlog_revset() -> Self {
17+
Self("((draft() | branches() | @) % main()) | branches() | @".to_string())
18+
}
19+
}
20+
1421
impl FromStr for Revset {
1522
type Err = std::convert::Infallible;
1623

git-branchless/src/revset/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ mod resolve;
1111
pub use ast::Expr;
1212
pub use eval::eval;
1313
pub use parser::parse;
14-
pub use resolve::{check_revset_syntax, resolve_commits};
14+
pub use resolve::{check_revset_syntax, resolve_commits, resolve_default_smartlog_commits};
1515

1616
use lalrpop_util::lalrpop_mod;
1717
lalrpop_mod!(

git-branchless/src/revset/resolve.rs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
use std::fmt::Write;
22

3+
use eyre::WrapErr;
34
use lib::core::dag::{CommitSet, Dag};
45
use lib::core::effects::Effects;
56
use lib::git::Repo;
7+
use thiserror::Error;
68
use tracing::instrument;
79

810
use crate::opts::{ResolveRevsetOptions, Revset};
@@ -14,11 +16,18 @@ use super::{eval, parse};
1416

1517
/// The result of attempting to resolve commits.
1618
#[allow(clippy::enum_variant_names)]
17-
#[derive(Debug)]
19+
#[derive(Debug, Error)]
1820
pub enum ResolveError {
21+
#[error("parse error in {expr:?}: {source}")]
1922
ParseError { expr: String, source: ParseError },
23+
24+
#[error("evaluation error in {expr:?}: {source}")]
2025
EvalError { expr: String, source: EvalError },
26+
27+
#[error("DAG query error: {source}")]
2128
DagError { source: eden_dag::Error },
29+
30+
#[error(transparent)]
2231
OtherError { source: eyre::Error },
2332
}
2433

@@ -101,3 +110,23 @@ pub fn resolve_commits(
101110
}
102111
Ok(commit_sets)
103112
}
113+
114+
/// Resolve the set of commits that would appear in the smartlog by default (if
115+
/// the user doesn't specify a revset).
116+
pub fn resolve_default_smartlog_commits(
117+
effects: &Effects,
118+
repo: &Repo,
119+
dag: &mut Dag,
120+
) -> eyre::Result<CommitSet> {
121+
let revset = Revset::default_smartlog_revset();
122+
let results = resolve_commits(
123+
effects,
124+
repo,
125+
dag,
126+
&[revset],
127+
&ResolveRevsetOptions::default(),
128+
)
129+
.wrap_err("Resolving default smartlog commits")?;
130+
let commits = results.first().unwrap();
131+
Ok(commits.clone())
132+
}

0 commit comments

Comments
 (0)