Skip to content

Commit a33db8d

Browse files
author
Stephan Dilly
committed
cache branchname lookup (closes #159)
1 parent 715c179 commit a33db8d

File tree

8 files changed

+61
-5
lines changed

8 files changed

+61
-5
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2626
- hooks ignored when running `gitui` in subfolder of workdir ([#151](https://github.com/extrawurst/gitui/issues/151))
2727
- better scrolling in file-trees [[@tisorlawan](https://github.com/tisorlawan)] ([#144](https://github.com/extrawurst/gitui/issues/144))
2828
- show untracked files in stash commit details [[@MCord](https://github.com/MCord)] ([#130](https://github.com/extrawurst/gitui/issues/130))
29+
- in some repos looking up the branch name was a bottleneck ([#159](https://github.com/extrawurst/gitui/issues/159))
2930
- some optimizations in reflog
3031

3132
## [0.7.0] - 2020-06-15

asyncgit/src/cached/branchname.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
use crate::{
2+
error::Result,
3+
sync::{self, CommitId},
4+
};
5+
6+
///
7+
pub struct BranchName {
8+
last_result: Option<(CommitId, String)>,
9+
repo_path: String,
10+
}
11+
12+
impl BranchName {
13+
///
14+
pub fn new(path: &str) -> Self {
15+
Self {
16+
repo_path: path.to_string(),
17+
last_result: None,
18+
}
19+
}
20+
21+
///
22+
pub fn lookup(&mut self) -> Result<String> {
23+
let current_head = sync::get_head(self.repo_path.as_str())?;
24+
25+
if let Some((last_head, branch_name)) =
26+
self.last_result.as_ref()
27+
{
28+
if *last_head == current_head {
29+
return Ok(branch_name.clone());
30+
}
31+
}
32+
33+
self.fetch(current_head)
34+
}
35+
36+
fn fetch(&mut self, head: CommitId) -> Result<String> {
37+
let name = sync::get_branch_name(self.repo_path.as_str())?;
38+
self.last_result = Some((head, name.clone()));
39+
Ok(name)
40+
}
41+
}

asyncgit/src/cached/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
//! cached lookups:
2+
//! parts of the sync api that might take longer
3+
//! to compute but change seldom so doing them async might be overkill
4+
5+
mod branchname;
6+
7+
pub use branchname::BranchName;

asyncgit/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#![deny(clippy::result_unwrap_used)]
77
#![deny(clippy::panic)]
88

9+
pub mod cached;
910
mod commit_files;
1011
mod diff;
1112
mod error;

asyncgit/src/sync/branch.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ use crate::{
77
use scopetime::scope_time;
88

99
/// returns the branch-name head is currently pointing to
10-
pub fn get_branch_name(repo_path: &str) -> Result<String> {
10+
/// this might be expensive, see `cached::BranchName`
11+
pub(crate) fn get_branch_name(repo_path: &str) -> Result<String> {
1112
scope_time!("get_branch_name");
1213

1314
let repo = utils::repo(repo_path)?;

asyncgit/src/sync/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ pub mod status;
1616
mod tags;
1717
pub mod utils;
1818

19-
pub use branch::get_branch_name;
19+
pub(crate) use branch::get_branch_name;
2020
pub use commit::{amend, commit};
2121
pub use commit_details::{get_commit_details, CommitDetails};
2222
pub use commit_files::get_commit_files;

src/components/changes.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::{
1111
ui::style::SharedTheme,
1212
};
1313
use anyhow::Result;
14-
use asyncgit::{sync, StatusItem, StatusItemType, CWD};
14+
use asyncgit::{cached, sync, StatusItem, StatusItemType, CWD};
1515
use crossterm::event::Event;
1616
use std::path::Path;
1717
use strings::commands;
@@ -39,6 +39,7 @@ pub struct ChangesComponent {
3939
files: FileTreeComponent,
4040
is_working_dir: bool,
4141
queue: Queue,
42+
branch_name: cached::BranchName,
4243
}
4344

4445
impl ChangesComponent {
@@ -60,13 +61,14 @@ impl ChangesComponent {
6061
),
6162
is_working_dir,
6263
queue,
64+
branch_name: cached::BranchName::new(CWD),
6365
}
6466
}
6567

6668
///
6769
pub fn update(&mut self, list: &[StatusItem]) -> Result<()> {
6870
if self.is_working_dir {
69-
if let Ok(branch_name) = sync::get_branch_name(CWD) {
71+
if let Ok(branch_name) = self.branch_name.lookup() {
7072
self.files.set_title(format!(
7173
"{} - {{{}}}",
7274
&self.title, branch_name,

src/tabs/revlog.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use crate::{
1111
};
1212
use anyhow::Result;
1313
use asyncgit::{
14+
cached,
1415
sync::{self, CommitId},
1516
AsyncLog, AsyncNotification, FetchStatus, CWD,
1617
};
@@ -31,6 +32,7 @@ pub struct Revlog {
3132
git_log: AsyncLog,
3233
queue: Queue,
3334
visible: bool,
35+
branch_name: cached::BranchName,
3436
}
3537

3638
impl Revlog {
@@ -50,6 +52,7 @@ impl Revlog {
5052
list: CommitList::new(strings::LOG_TITLE, theme),
5153
git_log: AsyncLog::new(sender),
5254
visible: false,
55+
branch_name: cached::BranchName::new(CWD),
5356
}
5457
}
5558

@@ -80,7 +83,7 @@ impl Revlog {
8083
}
8184

8285
self.list.set_branch(
83-
sync::get_branch_name(CWD).map(Some).unwrap_or(None),
86+
self.branch_name.lookup().map(Some).unwrap_or(None),
8487
);
8588

8689
if self.commit_details.is_visible() {

0 commit comments

Comments
 (0)