Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

### Fixes
* fix extremely slow status loading in large repositories by replacing time-based cache invalidation with generation counter [[@DannyStoll1](https://github.com/DannyStoll1)] ([#2823](https://github.com/gitui-org/gitui/issues/2823))
* fix panic when renaming or updating remote URL with no remotes configured [[@xvchris](https://github.com/xvchris)] ([#2868](https://github.com/gitui-org/gitui/issues/2868))

### Changed
* rust msrv bumped to `1.88`

### Fixed
* fix panic when renaming or updating remote URL with no remotes configured [[@xvchris](https://github.com/xvchris)] ([#2868](https://github.com/gitui-org/gitui/issues/2868))

## [0.28.0] - 2025-12-14

**discard changes on checkout**
Expand Down
26 changes: 12 additions & 14 deletions asyncgit/src/status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,11 @@ use crossbeam_channel::Sender;
use std::{
hash::Hash,
sync::{
atomic::{AtomicUsize, Ordering},
atomic::{AtomicU64, AtomicUsize, Ordering},
Arc, Mutex,
},
time::{SystemTime, UNIX_EPOCH},
};

fn current_tick() -> u128 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("time before unix epoch!")
.as_millis()
}

#[derive(Default, Hash, Clone)]
pub struct Status {
pub items: Vec<StatusItem>,
Expand All @@ -31,19 +23,17 @@ pub struct Status {
///
#[derive(Default, Hash, Copy, Clone, PartialEq, Eq)]
pub struct StatusParams {
tick: u128,
status_type: StatusType,
config: Option<ShowUntrackedFilesConfig>,
}

impl StatusParams {
///
pub fn new(
pub const fn new(
status_type: StatusType,
config: Option<ShowUntrackedFilesConfig>,
) -> Self {
Self {
tick: current_tick(),
status_type,
config,
}
Expand All @@ -59,6 +49,8 @@ pub struct AsyncStatus {
sender: Sender<AsyncGitNotification>,
pending: Arc<AtomicUsize>,
repo: RepoPath,
/// Counter that increments after each completed fetch.
generation: Arc<AtomicU64>,
}

impl AsyncStatus {
Expand All @@ -73,6 +65,7 @@ impl AsyncStatus {
last: Arc::new(Mutex::new(Status::default())),
sender,
pending: Arc::new(AtomicUsize::new(0)),
generation: Arc::new(AtomicU64::new(0)),
}
}

Expand All @@ -97,12 +90,14 @@ impl AsyncStatus {
return Ok(None);
}

let hash_request = hash(&params);
let generation = self.generation.load(Ordering::Relaxed);
let hash_request = hash(&(params, generation));

log::trace!(
"request: [hash: {}] (type: {:?})",
"request: [hash: {}] (type: {:?}, gen: {})",
hash_request,
params.status_type,
generation,
);

{
Expand All @@ -118,6 +113,7 @@ impl AsyncStatus {

let arc_current = Arc::clone(&self.current);
let arc_last = Arc::clone(&self.last);
let arc_generation = Arc::clone(&self.generation);
let sender = self.sender.clone();
let arc_pending = Arc::clone(&self.pending);
let status_type = params.status_type;
Expand All @@ -138,6 +134,8 @@ impl AsyncStatus {
log::error!("fetch_helper: {e}");
}

// Increment generation to invalidate cache for next request
arc_generation.fetch_add(1, Ordering::Relaxed);
arc_pending.fetch_sub(1, Ordering::Relaxed);

sender
Expand Down
Loading