Skip to content

Commit 3ab9b9e

Browse files
committed
refactor(smartlog): Improvements for sparse smartlog
1 parent b02f2ca commit 3ab9b9e

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
@@ -117,7 +117,6 @@ pub struct Dag {
117117
visible_heads: OnceCell<CommitSet>,
118118
visible_commits: OnceCell<CommitSet>,
119119
draft_commits: OnceCell<CommitSet>,
120-
default_smartlog_commits: OnceCell<CommitSet>,
121120
}
122121

123122
impl Dag {
@@ -198,7 +197,6 @@ impl Dag {
198197
visible_heads: Default::default(),
199198
visible_commits: Default::default(),
200199
draft_commits: Default::default(),
201-
default_smartlog_commits: Default::default(),
202200
})
203201
}
204202

@@ -434,24 +432,6 @@ impl Dag {
434432
})
435433
}
436434

437-
/// Determine the default set of commits that is shown in the smartlog when
438-
/// no revset is passed.
439-
pub fn query_default_smartlog_commits(&self) -> eyre::Result<&CommitSet> {
440-
self.default_smartlog_commits.get_or_try_init(|| {
441-
let public_commits = self.query_public_commits_slow()?;
442-
let active_commits = self.observed_commits.clone();
443-
let active_heads = self.query().heads(active_commits)?;
444-
let active_heads = active_heads.difference(public_commits);
445-
446-
let active_heads = active_heads
447-
.union(&self.head_commit)
448-
.union(&self.branch_commits)
449-
.union(&self.main_branch_commit);
450-
451-
Ok(active_heads)
452-
})
453-
}
454-
455435
/// Given a CommitSet, return a list of CommitSets, each representing a
456436
/// connected component of the set.
457437
///

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};
@@ -542,21 +543,22 @@ pub fn switch(
542543
let event_tx_id = event_log_db.make_transaction_id(now, "checkout")?;
543544
let event_replayer = EventReplayer::from_event_log_db(effects, &repo, &event_log_db)?;
544545
let event_cursor = event_replayer.make_default_cursor();
545-
let dag = Dag::open_and_sync(
546+
let mut dag = Dag::open_and_sync(
546547
effects,
547548
&repo,
548549
&event_replayer,
549550
event_cursor,
550551
&references_snapshot,
551552
)?;
552553

554+
let commits = resolve_default_smartlog_commits(effects, &repo, &mut dag)?;
553555
let graph = make_smartlog_graph(
554556
effects,
555557
&repo,
556558
&dag,
557559
&event_replayer,
558560
event_cursor,
559-
dag.query_default_smartlog_commits()?,
561+
&commits,
560562
)?;
561563

562564
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
@@ -349,16 +349,7 @@ mod render {
349349
let mut root_commit_oids: Vec<NonZeroOid> = graph
350350
.nodes
351351
.iter()
352-
.filter(|(_oid, node)| {
353-
// Common case: on main w/ no parents in graph, eg a merge base
354-
node.parent.is_none() && node.is_main ||
355-
// Pathological cases: orphaned, garbage collected, etc
356-
node.parent.is_none()
357-
&& !node.is_main
358-
&& node.children.is_empty()
359-
&& node.descendants.is_empty()
360-
&& !node.has_ancestors
361-
})
352+
.filter(|(_oid, node)| node.parent.is_none() && !node.has_ancestors)
362353
.map(|(oid, _node)| oid)
363354
.copied()
364355
.collect();
@@ -631,9 +622,7 @@ mod render {
631622
fn default() -> Self {
632623
Self {
633624
event_id: Default::default(),
634-
revset: Revset(
635-
"((draft() | branches() | @) % main()) | branches() | @".to_string(),
636-
),
625+
revset: Revset::default_smartlog_revset(),
637626
resolve_revset_options: Default::default(),
638627
}
639628
}

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)