diff --git a/CHANGELOG.md b/CHANGELOG.md index bab47c8b..d6ac886e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed +- log tab refreshes when head changes ([#78](https://github.com/extrawurst/gitui/issues/78)) + ## [0.3.0] - 2020-05-20 ### Added diff --git a/asyncgit/src/revlog.rs b/asyncgit/src/revlog.rs index 0f15383c..68ddf48c 100644 --- a/asyncgit/src/revlog.rs +++ b/asyncgit/src/revlog.rs @@ -1,6 +1,11 @@ -use crate::{error::Result, sync, AsyncNotification, CWD}; +use crate::{ + error::Result, + sync::{utils::repo, LogWalker}, + AsyncNotification, CWD, +}; use crossbeam_channel::Sender; use git2::Oid; +use log::debug; use scopetime::scope_time; use std::{ iter::FromIterator, @@ -9,7 +14,6 @@ use std::{ Arc, Mutex, }, }; -use sync::{utils::repo, LogWalker}; /// pub struct AsyncLog { @@ -54,23 +58,46 @@ impl AsyncLog { self.pending.load(Ordering::Relaxed) } + /// + fn current_head(&self) -> Result { + Ok(self.current.lock()?.first().map_or(Oid::zero(), |f| *f)) + } + + /// + fn head_changed(&self) -> Result { + if let Ok(head) = repo(CWD)?.head() { + if let Some(head) = head.target() { + debug!( + "repo head vs current log head: {} vs. {}", + head, + self.current_head()? + ); + return Ok(head != self.current_head()?); + } + } + Ok(false) + } + /// pub fn fetch(&mut self) -> Result<()> { if !self.is_pending() { - self.clear()?; + if self.head_changed()? { + self.clear()?; - let arc_current = Arc::clone(&self.current); - let sender = self.sender.clone(); - let arc_pending = Arc::clone(&self.pending); + let arc_current = Arc::clone(&self.current); + let sender = self.sender.clone(); + let arc_pending = Arc::clone(&self.pending); - rayon_core::spawn(move || { - scope_time!("async::revlog"); - arc_pending.store(true, Ordering::Relaxed); - AsyncLog::fetch_helper(arc_current, &sender) - .expect("failed to fetch"); - arc_pending.store(false, Ordering::Relaxed); - Self::notify(&sender); - }); + rayon_core::spawn(move || { + scope_time!("async::revlog"); + + arc_pending.store(true, Ordering::Relaxed); + AsyncLog::fetch_helper(arc_current, &sender) + .expect("failed to fetch"); + arc_pending.store(false, Ordering::Relaxed); + Self::notify(&sender); + }); + } } Ok(()) } diff --git a/src/app.rs b/src/app.rs index 13df31d7..5c18c64f 100644 --- a/src/app.rs +++ b/src/app.rs @@ -137,10 +137,11 @@ impl App { } //TODO: do we need this? - /// + /// forward ticking to components that require it pub fn update(&mut self) { trace!("update"); self.status_tab.update(); + self.revlog.update(); } /// diff --git a/src/tabs/revlog/mod.rs b/src/tabs/revlog/mod.rs index c7e1a88b..836ac651 100644 --- a/src/tabs/revlog/mod.rs +++ b/src/tabs/revlog/mod.rs @@ -72,9 +72,15 @@ impl Revlog { /// pub fn update(&mut self) { + if self.visible { + self.git_log.fetch().unwrap(); + } + + let old_total = self.count_total; self.count_total = self.git_log.count().unwrap(); if self.items.needs_data(self.selection, self.selection_max()) + || old_total != self.count_total { self.fetch_commits(); }