Sebastian Thielreview646f8b24 months agoHistory
90 lines · 2.4 KB · Rust
RawDownload
use anyhow::bail;use gix::prelude::ObjectIdExt;use unicode_width::UnicodeWidthStr; use crate::OutputFormat; pub fn list(repo: gix::Repository, out: &mut dyn std::io::Write, format: OutputFormat) -> anyhow::Result<()> {    if format != OutputFormat::Human {        bail!("JSON output isn't implemented yet");    }    let main_repo = repo.main_repo()?;    let mut worktrees = Vec::new();     if let Some(worktree) = main_repo.worktree() {        worktrees.push(create_worktree_info(&main_repo, gix::path::realpath(worktree.base())?)?);    }     for proxy in main_repo.worktrees()? {        let base = gix::path::realpath(proxy.base()?)?;         match proxy.into_repo() {            Ok(worktree_repo) => {                worktrees.push(create_worktree_info(&worktree_repo, base)?);            }            Err(_) => {                worktrees.push(create_inaccessible_worktree_info(&repo, base));            }        }    }     let path_width = worktrees        .iter()        .map(|worktree| UnicodeWidthStr::width(worktree.base.as_str()))        .max()        .unwrap_or(0);     for worktree in worktrees {        worktree.write(out, path_width)?;    }     Ok(())} struct WorktreeInfo {    base: String,    head: String,    branch: String,} impl WorktreeInfo {    fn write(&self, out: &mut dyn std::io::Write, path_width: usize) -> std::io::Result<()> {        writeln!(            out,            "{}{} {} [{}]",            self.base,            " ".repeat(path_width.saturating_sub(UnicodeWidthStr::width(self.base.as_str()))),            self.head,            self.branch,        )    }} fn create_worktree_info(repo: &gix::Repository, base: std::path::PathBuf) -> anyhow::Result<WorktreeInfo> {    let head = repo        .head_id()        .map_or_else(            |_| repo.object_hash().null().attach(repo).shorten_or_id(),            |id| id.shorten_or_id(),        )        .to_string();     let branch = repo.head_name()?.map_or_else(        || "<detached>".to_string(),        |name| name.shorten().to_owned().to_string(),    );     Ok(WorktreeInfo {        base: base.display().to_string(),        head,        branch,    })} fn create_inaccessible_worktree_info(repo: &gix::Repository, base: std::path::PathBuf) -> WorktreeInfo {    WorktreeInfo {        base: base.display().to_string(),        head: repo.object_hash().null().attach(repo).shorten_or_id().to_string(),        branch: "<unknown>".to_string(),    }}