11//! Utilities for graph-walking specifically.
2- use std:: { collections:: BTreeSet , ops:: Deref } ;
3-
4- use anyhow:: { Context , bail} ;
5- use but_core:: { RefMetadata , ref_metadata} ;
6- use gix:: { hashtable:: hash_map:: Entry , reference:: Category , traverse:: commit:: Either } ;
7- use petgraph:: Direction ;
8-
92use crate :: {
103 Commit , CommitFlags , CommitIndex , Edge , Graph , Segment , SegmentIndex , SegmentMetadata ,
4+ Worktree ,
115 init:: {
126 Goals , PetGraph ,
137 overlay:: { OverlayMetadata , OverlayRepo } ,
@@ -16,6 +10,14 @@ use crate::{
1610 } ,
1711 is_workspace_ref_name,
1812} ;
13+ use anyhow:: { Context , bail} ;
14+ use bstr:: { BStr , BString } ;
15+ use but_core:: { RefMetadata , ref_metadata} ;
16+ use gix:: { hashtable:: hash_map:: Entry , reference:: Category , traverse:: commit:: Either } ;
17+ use petgraph:: Direction ;
18+ use std:: collections:: BTreeMap ;
19+ use std:: path:: PathBuf ;
20+ use std:: { collections:: BTreeSet , ops:: Deref } ;
1921
2022pub ( crate ) type RefsById = gix:: hashtable:: HashMap < gix:: ObjectId , Vec < gix:: refs:: FullName > > ;
2123
@@ -941,3 +943,49 @@ pub fn prune_integrated_tips(graph: &mut Graph, next: &mut Queue) -> anyhow::Res
941943 } ) ;
942944 Ok ( ( ) )
943945}
946+
947+ type WorktreeByBranch = BTreeMap < gix:: refs:: FullName , Vec < Worktree > > ;
948+
949+ pub fn worktree_branches ( repo : & gix:: Repository ) -> anyhow:: Result < WorktreeByBranch > {
950+ fn maybe_insert_head (
951+ head : Option < gix:: Head < ' _ > > ,
952+ out : & mut WorktreeByBranch ,
953+ ) -> anyhow:: Result < ( ) > {
954+ let Some ( ( head, wd) ) = head. and_then ( |head| {
955+ head. repo . worktree ( ) . map ( |wt| {
956+ (
957+ head,
958+ match wt. id ( ) {
959+ None => Worktree :: Main ,
960+ Some ( id) => Worktree :: LinkedId ( id. to_owned ( ) ) ,
961+ } ,
962+ )
963+ } )
964+ } ) else {
965+ return Ok ( ( ) ) ;
966+ } ;
967+
968+ out. entry ( "HEAD" . try_into ( ) . expect ( "valid" ) )
969+ . or_default ( )
970+ . push ( wd. to_owned ( ) ) ;
971+ let mut ref_chain = Vec :: new ( ) ;
972+ let mut cursor = head. try_into_referent ( ) ;
973+ while let Some ( ref_) = cursor {
974+ ref_chain. push ( ref_. name ( ) . to_owned ( ) ) ;
975+ cursor = ref_. follow ( ) . transpose ( ) ?;
976+ }
977+ for name in ref_chain {
978+ out. entry ( name) . or_default ( ) . push ( wd. to_owned ( ) ) ;
979+ }
980+
981+ Ok ( ( ) )
982+ }
983+
984+ let mut map = BTreeMap :: new ( ) ;
985+ maybe_insert_head ( repo. head ( ) . ok ( ) , & mut map) ?;
986+ for proxy in repo. worktrees ( ) ? {
987+ let repo = proxy. into_repo_with_possibly_inaccessible_worktree ( ) ?;
988+ maybe_insert_head ( repo. head ( ) . ok ( ) , & mut map) ?;
989+ }
990+ Ok ( map)
991+ }
0 commit comments