upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/git.rs45
-rw-r--r--src/sub_commands/prs/create.rs143
-rw-r--r--src/sub_commands/prs/list.rs41
-rw-r--r--src/sub_commands/pull.rs6
-rw-r--r--src/sub_commands/push.rs18
5 files changed, 134 insertions, 119 deletions
diff --git a/src/git.rs b/src/git.rs
index e832c23..5b78b34 100644
--- a/src/git.rs
+++ b/src/git.rs
@@ -41,11 +41,11 @@ pub trait RepoActions {
41 fn get_head_commit(&self) -> Result<Sha1Hash>; 41 fn get_head_commit(&self) -> Result<Sha1Hash>;
42 fn get_commit_parent(&self, commit: &Sha1Hash) -> Result<Sha1Hash>; 42 fn get_commit_parent(&self, commit: &Sha1Hash) -> Result<Sha1Hash>;
43 fn get_commit_message(&self, commit: &Sha1Hash) -> Result<String>; 43 fn get_commit_message(&self, commit: &Sha1Hash) -> Result<String>;
44 /// returns vector ["name", "email", "unixtime"] 44 /// returns vector ["name", "email", "unixtime", "offset"]
45 /// eg ["joe bloggs", "joe@pm.me", "12176,-300"] 45 /// eg ["joe bloggs", "joe@pm.me", "12176","-300"]
46 fn get_commit_author(&self, commit: &Sha1Hash) -> Result<Vec<String>>; 46 fn get_commit_author(&self, commit: &Sha1Hash) -> Result<Vec<String>>;
47 /// returns vector ["name", "email", "unixtime"] 47 /// returns vector ["name", "email", "unixtime", "offset"]
48 /// eg ["joe bloggs", "joe@pm.me", "12176,-300"] 48 /// eg ["joe bloggs", "joe@pm.me", "12176","-300"]
49 fn get_commit_comitter(&self, commit: &Sha1Hash) -> Result<Vec<String>>; 49 fn get_commit_comitter(&self, commit: &Sha1Hash) -> Result<Vec<String>>;
50 fn get_commits_ahead_behind( 50 fn get_commits_ahead_behind(
51 &self, 51 &self,
@@ -442,7 +442,8 @@ fn git_sig_to_tag_vec(sig: &git2::Signature) -> Vec<String> {
442 vec![ 442 vec![
443 sig.name().unwrap_or("").to_string(), 443 sig.name().unwrap_or("").to_string(),
444 sig.email().unwrap_or("").to_string(), 444 sig.email().unwrap_or("").to_string(),
445 format!("{},{}", sig.when().seconds(), sig.when().offset_minutes()), 445 format!("{}", sig.when().seconds()),
446 format!("{}", sig.when().offset_minutes()),
446 ] 447 ]
447} 448}
448 449
@@ -477,7 +478,7 @@ fn apply_patch(git_repo: &Repo, patch: &nostr::Event) -> Result<()> {
477 index.add_all(["."], git2::IndexAddOption::DEFAULT, None)?; 478 index.add_all(["."], git2::IndexAddOption::DEFAULT, None)?;
478 index.write()?; 479 index.write()?;
479 480
480 let pgp_sig = if let Ok(pgp_sig) = tag_value(patch, "commit-sig") { 481 let pgp_sig = if let Ok(pgp_sig) = tag_value(patch, "commit-pgp-sig") {
481 if pgp_sig.is_empty() { 482 if pgp_sig.is_empty() {
482 None 483 None
483 } else { 484 } else {
@@ -585,22 +586,15 @@ fn extract_sig_from_patch_tags<'a>(
585 .find(|t| t.as_vec()[0].eq(tag_name)) 586 .find(|t| t.as_vec()[0].eq(tag_name))
586 .context(format!("tag '{tag_name}' not present in patch"))? 587 .context(format!("tag '{tag_name}' not present in patch"))?
587 .as_vec(); 588 .as_vec();
588 if v.len() != 4 { 589 if v.len() != 5 {
589 bail!("tag '{tag_name}' is incorrectly formatted") 590 bail!("tag '{tag_name}' is incorrectly formatted")
590 } 591 }
591 let git_time: Vec<&str> = v[3].split(',').collect();
592 if git_time.len() != 2 {
593 bail!("tag '{tag_name}' time is incorrectly formatted")
594 }
595 git2::Signature::new( 592 git2::Signature::new(
596 v[1].as_str(), 593 v[1].as_str(),
597 v[2].as_str(), 594 v[2].as_str(),
598 &git2::Time::new( 595 &git2::Time::new(
599 git_time[0] 596 v[3].parse().context("tag time is incorrectly formatted")?,
600 .parse() 597 v[4].parse()
601 .context("tag time is incorrectly formatted")?,
602 git_time[1]
603 .parse()
604 .context("tag time offset is incorrectly formatted")?, 598 .context("tag time offset is incorrectly formatted")?,
605 ), 599 ),
606 ) 600 )
@@ -611,7 +605,7 @@ fn extract_sig_from_patch_tags<'a>(
611mod tests { 605mod tests {
612 use std::fs; 606 use std::fs;
613 607
614 use test_utils::git::GitTestRepo; 608 use test_utils::{generate_repo_ref_event, git::GitTestRepo, TEST_KEY_1_KEYS};
615 609
616 use super::*; 610 use super::*;
617 611
@@ -706,19 +700,22 @@ mod tests {
706 #[test] 700 #[test]
707 fn no_offset() -> Result<()> { 701 fn no_offset() -> Result<()> {
708 let res = prep(&git2::Time::new(5000, 0))?; 702 let res = prep(&git2::Time::new(5000, 0))?;
709 assert_eq!("5000,0", res[2]); 703 assert_eq!("5000", res[2]);
704 assert_eq!("0", res[3]);
710 Ok(()) 705 Ok(())
711 } 706 }
712 #[test] 707 #[test]
713 fn positive_offset() -> Result<()> { 708 fn positive_offset() -> Result<()> {
714 let res = prep(&git2::Time::new(5000, 300))?; 709 let res = prep(&git2::Time::new(5000, 300))?;
715 assert_eq!("5000,300", res[2]); 710 assert_eq!("5000", res[2]);
711 assert_eq!("300", res[3]);
716 Ok(()) 712 Ok(())
717 } 713 }
718 #[test] 714 #[test]
719 fn negative_offset() -> Result<()> { 715 fn negative_offset() -> Result<()> {
720 let res = prep(&git2::Time::new(5000, -300))?; 716 let res = prep(&git2::Time::new(5000, -300))?;
721 assert_eq!("5000,-300", res[2]); 717 assert_eq!("5000", res[2]);
718 assert_eq!("-300", res[3]);
722 Ok(()) 719 Ok(())
723 } 720 }
724 } 721 }
@@ -1205,10 +1202,9 @@ mod tests {
1205 } 1202 }
1206 1203
1207 mod apply_patch { 1204 mod apply_patch {
1208 use test_utils::TEST_KEY_1_KEYS;
1209 1205
1210 use super::*; 1206 use super::*;
1211 use crate::sub_commands::prs::create::generate_patch_event; 1207 use crate::{repo_ref::RepoRef, sub_commands::prs::create::generate_patch_event};
1212 1208
1213 fn generate_patch_from_head_commit(test_repo: &GitTestRepo) -> Result<nostr::Event> { 1209 fn generate_patch_from_head_commit(test_repo: &GitTestRepo) -> Result<nostr::Event> {
1214 let original_oid = test_repo.git_repo.head()?.peel_to_commit()?.id(); 1210 let original_oid = test_repo.git_repo.head()?.peel_to_commit()?.id();
@@ -1219,6 +1215,8 @@ mod tests {
1219 &oid_to_sha1(&original_oid), 1215 &oid_to_sha1(&original_oid),
1220 nostr::EventId::all_zeros(), 1216 nostr::EventId::all_zeros(),
1221 &TEST_KEY_1_KEYS, 1217 &TEST_KEY_1_KEYS,
1218 &RepoRef::try_from(generate_repo_ref_event()).unwrap(),
1219 None,
1222 ) 1220 )
1223 } 1221 }
1224 fn test_patch_applies_to_repository(patch_event: nostr::Event) -> Result<()> { 1222 fn test_patch_applies_to_repository(patch_event: nostr::Event) -> Result<()> {
@@ -1358,7 +1356,7 @@ mod tests {
1358 use test_utils::TEST_KEY_1_KEYS; 1356 use test_utils::TEST_KEY_1_KEYS;
1359 1357
1360 use super::*; 1358 use super::*;
1361 use crate::sub_commands::prs::create::generate_pr_and_patch_events; 1359 use crate::{repo_ref::RepoRef, sub_commands::prs::create::generate_pr_and_patch_events};
1362 1360
1363 static BRANCH_NAME: &str = "add-example-feature"; 1361 static BRANCH_NAME: &str = "add-example-feature";
1364 // returns original_repo, pr_event, patch_events 1362 // returns original_repo, pr_event, patch_events
@@ -1378,6 +1376,7 @@ mod tests {
1378 &git_repo, 1376 &git_repo,
1379 &vec![oid_to_sha1(&oid1), oid_to_sha1(&oid2), oid_to_sha1(&oid3)], 1377 &vec![oid_to_sha1(&oid1), oid_to_sha1(&oid2), oid_to_sha1(&oid3)],
1380 &TEST_KEY_1_KEYS, 1378 &TEST_KEY_1_KEYS,
1379 &RepoRef::try_from(generate_repo_ref_event()).unwrap(),
1381 )?; 1380 )?;
1382 1381
1383 events.reverse(); 1382 events.reverse();
diff --git a/src/sub_commands/prs/create.rs b/src/sub_commands/prs/create.rs
index ad6a61a..0f7cbda 100644
--- a/src/sub_commands/prs/create.rs
+++ b/src/sub_commands/prs/create.rs
@@ -13,7 +13,9 @@ use crate::{
13 cli_interactor::{Interactor, InteractorPrompt, PromptConfirmParms, PromptInputParms}, 13 cli_interactor::{Interactor, InteractorPrompt, PromptConfirmParms, PromptInputParms},
14 client::Connect, 14 client::Connect,
15 git::{Repo, RepoActions}, 15 git::{Repo, RepoActions},
16 login, repo_ref, Cli, 16 login,
17 repo_ref::{self, RepoRef, REPO_REF_KIND},
18 Cli,
17}; 19};
18 20
19#[derive(Debug, clap::Args)] 21#[derive(Debug, clap::Args)]
@@ -96,9 +98,6 @@ pub async fn launch(
96 98
97 client.set_keys(&keys).await; 99 client.set_keys(&keys).await;
98 100
99 let events =
100 generate_pr_and_patch_events(&title, &description, &to_branch, &git_repo, &ahead, &keys)?;
101
102 let repo_ref = repo_ref::fetch( 101 let repo_ref = repo_ref::fetch(
103 &git_repo, 102 &git_repo,
104 git_repo 103 git_repo
@@ -110,6 +109,16 @@ pub async fn launch(
110 ) 109 )
111 .await?; 110 .await?;
112 111
112 let events = generate_pr_and_patch_events(
113 &title,
114 &description,
115 &to_branch,
116 &git_repo,
117 &ahead,
118 &keys,
119 &repo_ref,
120 )?;
121
113 println!( 122 println!(
114 "posting 1 pull request with {} commits...", 123 "posting 1 pull request with {} commits...",
115 events.len() - 1 124 events.len() - 1
@@ -299,7 +308,7 @@ mod tests_unique_and_duplicate {
299} 308}
300 309
301pub static PR_KIND: u64 = 318; 310pub static PR_KIND: u64 = 318;
302pub static PATCH_KIND: u64 = 317; 311pub static PATCH_KIND: u64 = 1617;
303 312
304pub fn generate_pr_and_patch_events( 313pub fn generate_pr_and_patch_events(
305 title: &str, 314 title: &str,
@@ -308,6 +317,7 @@ pub fn generate_pr_and_patch_events(
308 git_repo: &Repo, 317 git_repo: &Repo,
309 commits: &Vec<Sha1Hash>, 318 commits: &Vec<Sha1Hash>,
310 keys: &nostr::Keys, 319 keys: &nostr::Keys,
320 repo_ref: &RepoRef,
311) -> Result<Vec<nostr::Event>> { 321) -> Result<Vec<nostr::Event>> {
312 let root_commit = git_repo 322 let root_commit = git_repo
313 .get_root_commit(to_branch) 323 .get_root_commit(to_branch)
@@ -342,8 +352,16 @@ pub fn generate_pr_and_patch_events(
342 let mut events = vec![pr_event]; 352 let mut events = vec![pr_event];
343 for commit in commits { 353 for commit in commits {
344 events.push( 354 events.push(
345 generate_patch_event(git_repo, &root_commit, commit, pr_event_id, keys) 355 generate_patch_event(
346 .context("failed to generate patch event")?, 356 git_repo,
357 &root_commit,
358 commit,
359 pr_event_id,
360 keys,
361 repo_ref,
362 events.last().map(nostr::Event::id),
363 )
364 .context("failed to generate patch event")?,
347 ); 365 );
348 } 366 }
349 Ok(events) 367 Ok(events)
@@ -353,55 +371,92 @@ pub fn generate_patch_event(
353 git_repo: &Repo, 371 git_repo: &Repo,
354 root_commit: &Sha1Hash, 372 root_commit: &Sha1Hash,
355 commit: &Sha1Hash, 373 commit: &Sha1Hash,
356 pr_event_id: nostr::EventId, 374 thread_event_id: nostr::EventId,
357 keys: &nostr::Keys, 375 keys: &nostr::Keys,
376 repo_ref: &RepoRef,
377 parent_patch_event_id: Option<nostr::EventId>,
358) -> Result<nostr::Event> { 378) -> Result<nostr::Event> {
359 let commit_parent = git_repo 379 let commit_parent = git_repo
360 .get_commit_parent(commit) 380 .get_commit_parent(commit)
361 .context("failed to get parent commit")?; 381 .context("failed to get parent commit")?;
382 let relay_hint = repo_ref.relays.first().map(nostr::UncheckedUrl::from);
362 EventBuilder::new( 383 EventBuilder::new(
363 nostr::event::Kind::Custom(PATCH_KIND), 384 nostr::event::Kind::Custom(PATCH_KIND),
364 git_repo 385 git_repo
365 .make_patch_from_commit(commit) 386 .make_patch_from_commit(commit)
366 .context(format!("cannot make patch for commit {commit}"))?, 387 .context(format!("cannot make patch for commit {commit}"))?,
367 [ 388 [
368 Tag::Reference(format!("r-{root_commit}")), 389 vec![
369 Tag::Reference(commit.to_string()), 390 Tag::A {
370 Tag::Reference(commit_parent.to_string()), 391 kind: nostr::Kind::Custom(REPO_REF_KIND),
371 Tag::Event { 392 public_key: *repo_ref.maintainers.first()
372 event_id: pr_event_id, 393 .context("repo reference should always have at least one maintainer - the issuer of the repo event")
373 relay_url: None, // TODO: add relay 394 ?,
374 marker: Some(Marker::Root), 395 identifier: repo_ref.identifier.to_string(),
396 relay_url: relay_hint.clone(),
397 },
398 Tag::Reference(format!("{root_commit}")),
399 // commit id reference is a trade-off. its now
400 // unclear which one is the root commit id but it
401 // enables easier location of code comments againt
402 // code that makes it into the main branch, assuming
403 // the commit id is correct
404 Tag::Reference(commit.to_string()),
405
406 Tag::Event {
407 event_id: thread_event_id,
408 relay_url: relay_hint.clone(),
409 marker: Some(Marker::Root),
410 },
411 ],
412 if let Some(id) = parent_patch_event_id {
413 vec![Tag::Event {
414 event_id: id,
415 relay_url: relay_hint.clone(),
416 marker: Some(Marker::Reply),
417 }]
418 } else {
419 vec![]
375 }, 420 },
376 Tag::Generic( 421 // whilst it is in nip34 draft to tag the maintainers
377 TagKind::Custom("commit".to_string()), 422 // I'm not sure it is a good idea because if they are
378 vec![commit.to_string()], 423 // interested in all patches then their specialised
379 ), 424 // client should subscribe to patches tagged with the
380 Tag::Generic( 425 // repo reference. maintainers of large repos will not
381 TagKind::Custom("parent-commit".to_string()), 426 // be interested in every patch.
382 vec![commit_parent.to_string()], 427 repo_ref.maintainers
383 ), 428 .iter()
384 Tag::Generic( 429 .map(|pk| Tag::public_key(*pk))
385 TagKind::Custom("commit-sig".to_string()), 430 .collect(),
386 vec![ 431 vec![
387 git_repo 432 Tag::Generic(
388 .extract_commit_pgp_signature(commit) 433 TagKind::Custom("commit".to_string()),
389 .unwrap_or_default(), 434 vec![commit.to_string()],
390 ], 435 ),
391 ), 436 Tag::Generic(
392 Tag::Description(git_repo.get_commit_message(commit)?.to_string()), 437 TagKind::Custom("parent-commit".to_string()),
393 Tag::Generic( 438 vec![commit_parent.to_string()],
394 TagKind::Custom("author".to_string()), 439 ),
395 git_repo.get_commit_author(commit)?, 440 Tag::Generic(
396 ), 441 TagKind::Custom("commit-pgp-sig".to_string()),
397 Tag::Generic( 442 vec![
398 TagKind::Custom("committer".to_string()), 443 git_repo
399 git_repo.get_commit_comitter(commit)?, 444 .extract_commit_pgp_signature(commit)
400 ), 445 .unwrap_or_default(),
401 // TODO: add Repo event tags 446 ],
402 // TODO: people tag maintainers 447 ),
403 // TODO: add relay tags 448 Tag::Description(git_repo.get_commit_message(commit)?.to_string()),
404 ], 449 Tag::Generic(
450 TagKind::Custom("author".to_string()),
451 git_repo.get_commit_author(commit)?,
452 ),
453 Tag::Generic(
454 TagKind::Custom("committer".to_string()),
455 git_repo.get_commit_comitter(commit)?,
456 ),
457 ],
458 ]
459 .concat(),
405 ) 460 )
406 .to_event(keys) 461 .to_event(keys)
407 .context("failed to sign event") 462 .context("failed to sign event")
diff --git a/src/sub_commands/prs/list.rs b/src/sub_commands/prs/list.rs
index f0b4ad9..96004d4 100644
--- a/src/sub_commands/prs/list.rs
+++ b/src/sub_commands/prs/list.rs
@@ -115,8 +115,7 @@ pub async fn launch(
115 vec![ 115 vec![
116 nostr::Filter::default() 116 nostr::Filter::default()
117 .kind(nostr::Kind::Custom(PATCH_KIND)) 117 .kind(nostr::Kind::Custom(PATCH_KIND))
118 .event(pr_events[selected_index].id) 118 .event(pr_events[selected_index].id),
119 .reference(format!("r-{root_commit}")),
120 ], 119 ],
121 ) 120 )
122 .await? 121 .await?
@@ -127,9 +126,6 @@ pub async fn launch(
127 t.as_vec().len() > 2 126 t.as_vec().len() > 2
128 && t.as_vec()[1].eq(&pr_events[selected_index].id.to_string()) 127 && t.as_vec()[1].eq(&pr_events[selected_index].id.to_string())
129 }) 128 })
130 && e.tags
131 .iter()
132 .any(|t| t.as_vec().len() > 1 && t.as_vec()[1].eq(&format!("r-{root_commit}")))
133 }) 129 })
134 .map(std::borrow::ToOwned::to_owned) 130 .map(std::borrow::ToOwned::to_owned)
135 .collect(); 131 .collect();
@@ -154,41 +150,6 @@ pub async fn launch(
154 ); 150 );
155 } 151 }
156 152
157 // // TODO: look for mapping of existing branch
158
159 // // if latest_commit_id exists locally
160 // if local_branch_base == latest_commit_id {
161 // // TODO: check if its in the main / master branch (already merged)
162 // // TODO: check if it has any decendants and warn. maybe the user has
163 // // been working on a updates to be pushed? Suggest checking
164 // // out that branch.
165 // // we could search nostr for decendants of the commit as well?
166 // // perhaps this is overkill
167 // // TODO: check out the branch which it is the tip of. if the name of the
168 // // branch is different then ask the user if they would like to
169 // // use the existing branch or create one with the name of the PR.
170 // // TODO: if there are no decendants and its not the tip then
171 // // its an ophan commit so just make a branch from this commit.
172 // }
173 // // if commits ahead exist in a branch other than main or master
174 // // TODO: Identify probable existing branches - check remote tracker?
175 // // TODO: beind head
176 // else {
177 // // TODO: look for existing branch with same name
178 // // TODO: create remote tracker
179 // git_repo.create_branch_at_commit(&branch_name, &local_branch_base);
180 // git_repo.checkout(&branch_name)?;
181 // ahead.reverse();
182 // for event in ahead {
183 // git_repo.apply_patch(event, branch_name)?;
184 // }
185 // println!("applied!")
186 // }
187 // // TODO: check if commits in pr exist, if so look for branches with they are
188 // in // could we suggest pulling updates into that branch?
189 // //
190
191 // TODO: checkout PR branch
192 Ok(()) 153 Ok(())
193} 154}
194 155
diff --git a/src/sub_commands/pull.rs b/src/sub_commands/pull.rs
index a8f9529..342c8bb 100644
--- a/src/sub_commands/pull.rs
+++ b/src/sub_commands/pull.rs
@@ -78,8 +78,7 @@ pub async fn launch() -> Result<()> {
78 vec![ 78 vec![
79 nostr::Filter::default() 79 nostr::Filter::default()
80 .kind(nostr::Kind::Custom(PATCH_KIND)) 80 .kind(nostr::Kind::Custom(PATCH_KIND))
81 .event(pr_event.id) 81 .event(pr_event.id),
82 .reference(format!("r-{root_commit}")),
83 ], 82 ],
84 ) 83 )
85 .await? 84 .await?
@@ -89,9 +88,6 @@ pub async fn launch() -> Result<()> {
89 && e.tags 88 && e.tags
90 .iter() 89 .iter()
91 .any(|t| t.as_vec().len() > 2 && t.as_vec()[1].eq(&pr_event.id.to_string())) 90 .any(|t| t.as_vec().len() > 2 && t.as_vec()[1].eq(&pr_event.id.to_string()))
92 && e.tags
93 .iter()
94 .any(|t| t.as_vec().len() > 1 && t.as_vec()[1].eq(&format!("r-{root_commit}")))
95 }) 91 })
96 .map(std::borrow::ToOwned::to_owned) 92 .map(std::borrow::ToOwned::to_owned)
97 .collect(); 93 .collect();
diff --git a/src/sub_commands/push.rs b/src/sub_commands/push.rs
index e592cd7..fac746f 100644
--- a/src/sub_commands/push.rs
+++ b/src/sub_commands/push.rs
@@ -102,8 +102,16 @@ pub async fn launch(cli_args: &Cli) -> Result<()> {
102 let mut patch_events: Vec<nostr::Event> = vec![]; 102 let mut patch_events: Vec<nostr::Event> = vec![];
103 for commit in &ahead { 103 for commit in &ahead {
104 patch_events.push( 104 patch_events.push(
105 generate_patch_event(&git_repo, &root_commit, commit, pr_event.id, &keys) 105 generate_patch_event(
106 .context("cannot make patch event from commit")?, 106 &git_repo,
107 &root_commit,
108 commit,
109 pr_event.id,
110 &keys,
111 &repo_ref,
112 patch_events.last().map(nostr::Event::id),
113 )
114 .context("cannot make patch event from commit")?,
107 ); 115 );
108 } 116 }
109 println!("pushing {} commits", ahead.len()); 117 println!("pushing {} commits", ahead.len());
@@ -162,8 +170,7 @@ async fn fetch_pr_and_most_recent_patch_chain(
162 vec![ 170 vec![
163 nostr::Filter::default() 171 nostr::Filter::default()
164 .kind(nostr::Kind::Custom(PATCH_KIND)) 172 .kind(nostr::Kind::Custom(PATCH_KIND))
165 .event(pr_event.id) 173 .event(pr_event.id),
166 .reference(format!("r-{root_commit}")),
167 ], 174 ],
168 ) 175 )
169 .await? 176 .await?
@@ -173,9 +180,6 @@ async fn fetch_pr_and_most_recent_patch_chain(
173 && e.tags 180 && e.tags
174 .iter() 181 .iter()
175 .any(|t| t.as_vec().len() > 2 && t.as_vec()[1].eq(&pr_event.id.to_string())) 182 .any(|t| t.as_vec().len() > 2 && t.as_vec()[1].eq(&pr_event.id.to_string()))
176 && e.tags
177 .iter()
178 .any(|t| t.as_vec().len() > 1 && t.as_vec()[1].eq(&format!("r-{root_commit}")))
179 }) 183 })
180 .map(std::borrow::ToOwned::to_owned) 184 .map(std::borrow::ToOwned::to_owned)
181 .collect(); 185 .collect();