Skip to content

Commit f17726a

Browse files
id: make IdDb::new use non-legacy Context
1 parent 55ca722 commit f17726a

File tree

2 files changed

+67
-61
lines changed

2 files changed

+67
-61
lines changed

crates/but/src/id.rs

Lines changed: 58 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,74 @@
11
use std::{collections::HashMap, fmt::Display};
22

3-
use bstr::ByteSlice;
3+
use bstr::{BString, ByteSlice};
44
use but_core::ref_metadata::StackId;
55
use but_ctx::Context;
66
use but_hunk_assignment::HunkAssignment;
77
use gitbutler_command_context::CommandContext;
88

9+
fn branch_names(ctx: &Context) -> anyhow::Result<Vec<BString>> {
10+
let guard = ctx.shared_worktree_access();
11+
let meta = ctx.meta(guard.read_permission())?;
12+
let head_info = but_workspace::head_info(&ctx.repo, &meta, Default::default())?;
13+
let mut branch_names: Vec<BString> = Vec::new();
14+
for stack in head_info.stacks {
15+
for segment in stack.segments {
16+
if let Some(ref_info) = segment.ref_info {
17+
branch_names.push(ref_info.ref_name.shorten().to_owned());
18+
}
19+
}
20+
}
21+
Ok(branch_names)
22+
}
23+
924
pub struct IdDb {
1025
branch_name_to_cli_id: HashMap<String, CliId>,
1126
unassigned: CliId,
1227
}
1328

1429
impl IdDb {
15-
pub fn new(ctx: &CommandContext) -> anyhow::Result<Self> {
30+
pub fn new(ctx: &Context) -> anyhow::Result<Self> {
1631
let mut max_zero_count = 1; // Ensure at least two "0" in ID.
17-
let stacks = crate::utils::commits::stacks(ctx)?;
32+
let branch_names = branch_names(ctx)?;
1833
let mut pairs_to_count: HashMap<u16, u8> = HashMap::new();
1934
fn u8_pair_to_u16(two: [u8; 2]) -> u16 {
2035
two[0] as u16 * 256 + two[1] as u16
2136
}
22-
for stack in &stacks {
23-
for head in &stack.heads {
24-
for pair in head.name.windows(2) {
25-
let pair: [u8; 2] = pair.try_into()?;
26-
if !pair[0].is_ascii_alphanumeric() || !pair[1].is_ascii_alphanumeric() {
27-
continue;
28-
}
29-
let could_collide_with_commits =
30-
pair[0].is_ascii_hexdigit() && pair[1].is_ascii_hexdigit();
31-
if could_collide_with_commits {
32-
continue;
33-
}
34-
let u16pair = u8_pair_to_u16(pair);
35-
pairs_to_count
36-
.entry(u16pair)
37-
.and_modify(|count| *count = count.saturating_add(1))
38-
.or_insert(1);
37+
for branch_name in &branch_names {
38+
for pair in branch_name.windows(2) {
39+
let pair: [u8; 2] = pair.try_into()?;
40+
if !pair[0].is_ascii_alphanumeric() || !pair[1].is_ascii_alphanumeric() {
41+
continue;
3942
}
40-
for field in head.name.fields_with(|c| c != '0') {
41-
max_zero_count = std::cmp::max(field.len(), max_zero_count);
43+
let could_collide_with_commits =
44+
pair[0].is_ascii_hexdigit() && pair[1].is_ascii_hexdigit();
45+
if could_collide_with_commits {
46+
continue;
4247
}
48+
let u16pair = u8_pair_to_u16(pair);
49+
pairs_to_count
50+
.entry(u16pair)
51+
.and_modify(|count| *count = count.saturating_add(1))
52+
.or_insert(1);
53+
}
54+
for field in branch_name.fields_with(|c| c != '0') {
55+
max_zero_count = std::cmp::max(field.len(), max_zero_count);
4356
}
4457
}
4558

4659
let mut branch_name_to_cli_id: HashMap<String, CliId> = HashMap::new();
47-
for stack in stacks {
48-
'head: for head in &stack.heads {
49-
// Find first non-conflicting pair and use it as CliId.
50-
for pair in head.name.windows(2) {
51-
let pair: [u8; 2] = pair.try_into()?;
52-
let u16pair = u8_pair_to_u16(pair);
53-
if let Some(1) = pairs_to_count.get(&u16pair) {
54-
let name = head.name.to_string();
55-
let id = str::from_utf8(&pair)
56-
.expect("if we stored it, it's ascii-alphanum")
57-
.to_owned();
58-
branch_name_to_cli_id.insert(name.clone(), CliId::Branch { name, id });
59-
continue 'head;
60-
}
60+
'branch_name: for branch_name in &branch_names {
61+
// Find first non-conflicting pair and use it as CliId.
62+
for pair in branch_name.windows(2) {
63+
let pair: [u8; 2] = pair.try_into()?;
64+
let u16pair = u8_pair_to_u16(pair);
65+
if let Some(1) = pairs_to_count.get(&u16pair) {
66+
let name = branch_name.to_string();
67+
let id = str::from_utf8(&pair)
68+
.expect("if we stored it, it's ascii-alphanum")
69+
.to_owned();
70+
branch_name_to_cli_id.insert(name.clone(), CliId::Branch { name, id });
71+
continue 'branch_name;
6172
}
6273
}
6374
}
@@ -69,21 +80,15 @@ impl IdDb {
6980
})
7081
}
7182

72-
fn find_branches_by_name(
73-
&mut self,
74-
ctx: &CommandContext,
75-
name: &str,
76-
) -> anyhow::Result<Vec<CliId>> {
77-
let stacks = crate::utils::commits::stacks(ctx)?;
83+
fn find_branches_by_name(&mut self, ctx: &Context, name: &str) -> anyhow::Result<Vec<CliId>> {
84+
let branch_names = branch_names(ctx)?;
7885
let mut matches = Vec::new();
7986

80-
for stack in stacks {
81-
for head in &stack.heads {
82-
let branch_name = head.name.to_string();
83-
// Exact match or partial match
84-
if branch_name == name || branch_name.contains(name) {
85-
matches.push(self.branch(&branch_name).clone())
86-
}
87+
for branch_name in branch_names {
88+
let branch_name = branch_name.to_string();
89+
// Exact match or partial match
90+
if branch_name == name || branch_name.contains(name) {
91+
matches.push(self.branch(&branch_name).clone())
8792
}
8893
}
8994

@@ -204,12 +209,12 @@ impl CliId {
204209
}
205210

206211
// TODO: make callers of this function pass IdDb instead
207-
let mut id_db = IdDb::new(&ctx.legacy_ctx()?)?;
212+
let mut id_db = IdDb::new(ctx)?;
208213

209214
let mut matches = Vec::new();
210215

211216
// First, try exact branch name match
212-
if let Ok(branch_matches) = id_db.find_branches_by_name(&ctx.legacy_ctx()?, s) {
217+
if let Ok(branch_matches) = id_db.find_branches_by_name(ctx, s) {
213218
matches.extend(branch_matches);
214219
}
215220

@@ -230,7 +235,7 @@ impl CliId {
230235
.into_iter()
231236
.filter(|id| id.matches_prefix(s))
232237
.for_each(|id| cli_matches.push(id));
233-
crate::status::all_branches(&ctx.legacy_ctx()?)?
238+
crate::status::all_branches(ctx)?
234239
.into_iter()
235240
.filter(|id| id.matches_prefix(s))
236241
.for_each(|id| cli_matches.push(id));
@@ -253,7 +258,7 @@ impl CliId {
253258
.into_iter()
254259
.filter(|id| id.matches(s))
255260
.for_each(|id| cli_matches.push(id));
256-
crate::status::all_branches(&ctx.legacy_ctx()?)?
261+
crate::status::all_branches(ctx)?
257262
.into_iter()
258263
.filter(|id| id.matches(s))
259264
.for_each(|id| cli_matches.push(id));

crates/but/src/status/mod.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ pub(crate) async fn worktree(
104104

105105
let unassigned = assignment::filter_by_stack_id(assignments_by_file.values(), &None);
106106
stack_details.push((None, (None, unassigned)));
107-
let mut id_db = IdDb::new(&legacy_ctx)?;
107+
let mut id_db = IdDb::new(ctx)?;
108108

109109
// For JSON output, we'll need the original StackDetails to avoid redundant conversions
110110
let mut original_stack_details: Vec<(Option<gitbutler_stack::StackId>, Option<StackDetails>)> =
@@ -236,7 +236,7 @@ pub(crate) async fn worktree(
236236
verbose,
237237
review,
238238
&mut stack_mark,
239-
&mut legacy_ctx,
239+
ctx,
240240
i == stack_details_len - 1,
241241
i == 0,
242242
&review_map,
@@ -373,7 +373,7 @@ pub fn print_group(
373373
verbose: bool,
374374
show_url: bool,
375375
stack_mark: &mut Option<ColoredString>,
376-
ctx: &mut CommandContext,
376+
ctx: &Context,
377377
_last: bool,
378378
first: bool,
379379
review_map: &std::collections::HashMap<String, Vec<but_forge::ForgeReview>>,
@@ -436,7 +436,7 @@ pub fn print_group(
436436
let dot = "●".yellow();
437437
print_commit(
438438
commit.id,
439-
created_at_of_commit(ctx, commit.id)?,
439+
created_at_of_commit(&ctx.legacy_ctx()?, commit.id)?,
440440
commit.message.to_string(),
441441
commit.author.name.clone(),
442442
dot,
@@ -453,7 +453,8 @@ pub fn print_group(
453453
for cli_commit in &branch.commits {
454454
let commit = &cli_commit;
455455
let marked =
456-
crate::mark::commit_marked(ctx, commit.id.to_string()).unwrap_or_default();
456+
crate::mark::commit_marked(&mut ctx.legacy_ctx()?, commit.id.to_string())
457+
.unwrap_or_default();
457458
let dot = match commit.state {
458459
but_workspace::ui::CommitState::LocalOnly => "●".normal(),
459460
but_workspace::ui::CommitState::LocalAndRemote(object_id) => {
@@ -467,7 +468,7 @@ pub fn print_group(
467468
};
468469
print_commit(
469470
commit.id,
470-
created_at_of_commit(ctx, commit.id)?,
471+
created_at_of_commit(&ctx.legacy_ctx()?, commit.id)?,
471472
commit.message.to_string(),
472473
commit.author.name.clone(),
473474
dot,
@@ -543,9 +544,9 @@ pub(crate) fn all_files(ctx: &mut CommandContext) -> anyhow::Result<Vec<CliId>>
543544
Ok(out)
544545
}
545546

546-
pub(crate) fn all_branches(ctx: &CommandContext) -> anyhow::Result<Vec<CliId>> {
547+
pub(crate) fn all_branches(ctx: &Context) -> anyhow::Result<Vec<CliId>> {
547548
let mut id_db = IdDb::new(ctx)?;
548-
let stacks = crate::utils::commits::stacks(ctx)?;
549+
let stacks = crate::utils::commits::stacks(&ctx.legacy_ctx()?)?;
549550
let mut branches = Vec::new();
550551
for stack in stacks {
551552
for head in stack.heads {

0 commit comments

Comments
 (0)