From 63e449fca9d002041f50f54b3ac2f86a6b1d31c3 Mon Sep 17 00:00:00 2001 From: Stephan Dilly Date: Fri, 12 Jun 2020 22:37:53 +0200 Subject: [PATCH] indicate what branch we are on (closes #115) --- CHANGELOG.md | 1 + asyncgit/src/error.rs | 3 ++ asyncgit/src/sync/branch.rs | 57 ++++++++++++++++++++++++++++++++++++ asyncgit/src/sync/hunks.rs | 5 +++- asyncgit/src/sync/mod.rs | 2 ++ src/components/changes.rs | 11 +++++++ src/components/commitlist.rs | 13 +++++++- src/components/filetree.rs | 2 +- src/tabs/revlog.rs | 4 +++ 9 files changed, 95 insertions(+), 3 deletions(-) create mode 100644 asyncgit/src/sync/branch.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index d5f63d93..08c15668 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - file trees: `arrow-right` on expanded folder moves down into folder - better scrolling in diff ([#52](https://github.com/extrawurst/gitui/issues/52)) +- display current branch in status/log ([#115](https://github.com/extrawurst/gitui/issues/115)) ### Fixed - reset file inside folder failed when running `gitui` in a subfolder too ([#118](https://github.com/extrawurst/gitui/issues/118)) diff --git a/asyncgit/src/error.rs b/asyncgit/src/error.rs index 7312932a..f00f587b 100644 --- a/asyncgit/src/error.rs +++ b/asyncgit/src/error.rs @@ -5,6 +5,9 @@ pub enum Error { #[error("`{0}`")] Generic(String), + #[error("git: no head found")] + NoHead, + #[error("io error:{0}")] Io(#[from] std::io::Error), diff --git a/asyncgit/src/sync/branch.rs b/asyncgit/src/sync/branch.rs new file mode 100644 index 00000000..16df76f7 --- /dev/null +++ b/asyncgit/src/sync/branch.rs @@ -0,0 +1,57 @@ +//! + +use crate::{ + error::{Error, Result}, + sync::utils, +}; +use scopetime::scope_time; + +/// returns the branch-name head is currently pointing to +pub fn get_branch_name(repo_path: &str) -> Result { + scope_time!("get_branch_name"); + + let repo = utils::repo(repo_path)?; + + let iter = repo.branches(None)?; + + for b in iter { + let b = b?; + + if b.0.is_head() { + let name = b.0.name()?.unwrap_or(""); + return Ok(name.into()); + } + } + + Err(Error::NoHead) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::sync::tests::{repo_init, repo_init_empty}; + + #[test] + fn test_smoke() { + let (_td, repo) = repo_init().unwrap(); + let root = repo.path().parent().unwrap(); + let repo_path = root.as_os_str().to_str().unwrap(); + + assert_eq!( + get_branch_name(repo_path).unwrap().as_str(), + "master" + ); + } + + #[test] + fn test_empty_repo() { + let (_td, repo) = repo_init_empty().unwrap(); + let root = repo.path().parent().unwrap(); + let repo_path = root.as_os_str().to_str().unwrap(); + + assert!(matches!( + get_branch_name(repo_path), + Err(Error::NoHead) + )); + } +} diff --git a/asyncgit/src/sync/hunks.rs b/asyncgit/src/sync/hunks.rs index 8fb9af47..6a54c06d 100644 --- a/asyncgit/src/sync/hunks.rs +++ b/asyncgit/src/sync/hunks.rs @@ -2,7 +2,10 @@ use super::{ diff::{get_diff_raw, HunkHeader}, utils::repo, }; -use crate::{error::Error, error::Result, hash}; +use crate::{ + error::{Error, Result}, + hash, +}; use git2::{ApplyLocation, ApplyOptions, Diff}; use scopetime::scope_time; diff --git a/asyncgit/src/sync/mod.rs b/asyncgit/src/sync/mod.rs index aa8538ed..bf97b41e 100644 --- a/asyncgit/src/sync/mod.rs +++ b/asyncgit/src/sync/mod.rs @@ -1,5 +1,6 @@ //! sync git api +mod branch; mod commit_details; mod commit_files; mod commits_info; @@ -14,6 +15,7 @@ pub mod status; mod tags; pub mod utils; +pub use branch::get_branch_name; pub use commit_details::{get_commit_details, CommitDetails}; pub use commit_files::get_commit_files; pub use commits_info::{get_commits_info, CommitId, CommitInfo}; diff --git a/src/components/changes.rs b/src/components/changes.rs index 1b7089c4..9d0c2c59 100644 --- a/src/components/changes.rs +++ b/src/components/changes.rs @@ -35,6 +35,7 @@ macro_rules! try_or_popup { /// pub struct ChangesComponent { + title: String, files: FileTreeComponent, is_working_dir: bool, queue: Queue, @@ -50,6 +51,7 @@ impl ChangesComponent { theme: &Theme, ) -> Self { Self { + title: title.into(), files: FileTreeComponent::new( title, focus, @@ -63,6 +65,15 @@ impl ChangesComponent { /// pub fn update(&mut self, list: &[StatusItem]) -> Result<()> { + if self.is_working_dir { + if let Ok(branch_name) = sync::get_branch_name(CWD) { + self.files.set_title(format!( + "{} - {{{}}}", + &self.title, branch_name, + )) + } + } + self.files.update(list)?; Ok(()) diff --git a/src/components/commitlist.rs b/src/components/commitlist.rs index 60bc8a61..b2574dfa 100644 --- a/src/components/commitlist.rs +++ b/src/components/commitlist.rs @@ -27,6 +27,7 @@ const ELEMENTS_PER_LINE: usize = 10; pub struct CommitList { title: String, selection: usize, + branch: Option, count_total: usize, items: ItemBatch, scroll_state: (Instant, f32), @@ -42,6 +43,7 @@ impl CommitList { Self { items: ItemBatch::default(), selection: 0, + branch: None, count_total: 0, scroll_state: (Instant::now(), 0_f32), tags: None, @@ -57,6 +59,11 @@ impl CommitList { &mut self.items } + /// + pub fn set_branch(&mut self, name: Option) { + self.branch = name; + } + /// pub const fn selection(&self) -> usize { self.selection @@ -282,11 +289,15 @@ impl DrawableComponent for CommitList { selection, ); + let branch_post_fix = + self.branch.as_ref().map(|b| format!("- {{{}}}", b)); + let title = format!( - "{} {}/{}", + "{} {}/{} {}", self.title, self.count_total.saturating_sub(self.selection), self.count_total, + branch_post_fix.as_deref().unwrap_or(""), ); f.render_widget( diff --git a/src/components/filetree.rs b/src/components/filetree.rs index 32e31d48..06549f7b 100644 --- a/src/components/filetree.rs +++ b/src/components/filetree.rs @@ -251,7 +251,7 @@ impl DrawableComponent for FileTreeComponent { ui::draw_list( f, r, - &self.title.to_string(), + self.title.as_str(), items, self.tree.selection.map(|idx| idx - selection_offset), self.focused, diff --git a/src/tabs/revlog.rs b/src/tabs/revlog.rs index bf9355bd..a07cf3cd 100644 --- a/src/tabs/revlog.rs +++ b/src/tabs/revlog.rs @@ -76,6 +76,10 @@ impl Revlog { self.list.set_tags(sync::get_tags(CWD)?); } + self.list.set_branch( + sync::get_branch_name(CWD).map(Some).unwrap_or(None), + ); + if self.commit_details.is_visible() { self.commit_details.set_commit( self.selected_commit(),