Skip to content

Commit

Permalink
support fetching branch_infos async
Browse files Browse the repository at this point in the history
  • Loading branch information
extrawurst committed Nov 21, 2022
1 parent 3fee481 commit 92f63d1
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 17 deletions.
77 changes: 77 additions & 0 deletions asyncgit/src/branches.rs
@@ -0,0 +1,77 @@
use crate::{
asyncjob::{AsyncJob, RunParams},
error::Result,
sync::{branch::get_branches_info, BranchInfo, RepoPath},
AsyncGitNotification,
};
use std::sync::{Arc, Mutex};

enum JobState {
Request {
local_branches: bool,
repo: RepoPath,
},
Response(Result<Vec<BranchInfo>>),
}

///
#[derive(Clone, Default)]
pub struct AsyncBranchesJob {
state: Arc<Mutex<Option<JobState>>>,
}

///
impl AsyncBranchesJob {
///
pub fn new(repo: RepoPath, local_branches: bool) -> Self {
Self {
state: Arc::new(Mutex::new(Some(JobState::Request {
repo,
local_branches,
}))),
}
}

///
pub fn result(&self) -> Option<Result<Vec<BranchInfo>>> {
if let Ok(mut state) = self.state.lock() {
if let Some(state) = state.take() {
return match state {
JobState::Request { .. } => None,
JobState::Response(result) => Some(result),
};
}
}

None
}
}

impl AsyncJob for AsyncBranchesJob {
type Notification = AsyncGitNotification;
type Progress = ();

fn run(
&mut self,
_params: RunParams<Self::Notification, Self::Progress>,
) -> Result<Self::Notification> {
if let Ok(mut state) = self.state.lock() {
*state = state.take().map(|state| match state {
JobState::Request {
local_branches,
repo,
} => {
let branches =
get_branches_info(&repo, local_branches);

JobState::Response(branches)
}
JobState::Response(result) => {
JobState::Response(result)
}
});
}

Ok(AsyncGitNotification::Branches)
}
}
4 changes: 4 additions & 0 deletions asyncgit/src/lib.rs
Expand Up @@ -24,6 +24,7 @@

pub mod asyncjob;
mod blame;
mod branches;
pub mod cached;
mod commit_files;
mod diff;
Expand All @@ -42,6 +43,7 @@ mod tags;

pub use crate::{
blame::{AsyncBlame, BlameParams},
branches::AsyncBranchesJob,
commit_files::{AsyncCommitFiles, CommitFilesParams},
diff::{AsyncDiff, DiffParams, DiffType},
error::{Error, Result},
Expand Down Expand Up @@ -95,6 +97,8 @@ pub enum AsyncGitNotification {
RemoteTags,
///
Fetch,
///
Branches,
}

/// helper function to calculate the hash of an arbitrary type that implements the `Hash` trait
Expand Down
2 changes: 1 addition & 1 deletion src/components/branchlist.rs
Expand Up @@ -364,7 +364,7 @@ impl BranchListComponent {
}

fn check_remotes(&mut self) {
if !self.local {
if !self.local && self.visible {
self.has_remotes =
get_branches_info(&self.repo.borrow(), false)
.map(|branches| !branches.is_empty())
Expand Down
36 changes: 28 additions & 8 deletions src/tabs/revlog.rs
Expand Up @@ -12,9 +12,10 @@ use crate::{
};
use anyhow::Result;
use asyncgit::{
sync::{self, get_branches_info, CommitId, RepoPathRef},
AsyncGitNotification, AsyncLog, AsyncTags, CommitFilesParams,
FetchStatus,
asyncjob::AsyncSingleJob,
sync::{self, CommitId, RepoPathRef},
AsyncBranchesJob, AsyncGitNotification, AsyncLog, AsyncTags,
CommitFilesParams, FetchStatus,
};
use crossbeam_channel::Sender;
use crossterm::event::Event;
Expand All @@ -35,6 +36,7 @@ pub struct Revlog {
list: CommitList,
git_log: AsyncLog,
git_tags: AsyncTags,
git_branches: AsyncSingleJob<AsyncBranchesJob>,
queue: Queue,
visible: bool,
key_config: SharedKeyConfig,
Expand Down Expand Up @@ -71,6 +73,7 @@ impl Revlog {
None,
),
git_tags: AsyncTags::new(repo.borrow().clone(), sender),
git_branches: AsyncSingleJob::new(sender.clone()),
visible: false,
key_config,
}
Expand All @@ -80,6 +83,7 @@ impl Revlog {
pub fn any_work_pending(&self) -> bool {
self.git_log.is_pending()
|| self.git_tags.is_pending()
|| self.git_branches.is_pending()
|| self.commit_details.any_work_pending()
}

Expand All @@ -101,11 +105,6 @@ impl Revlog {

self.git_tags.request(Duration::from_secs(3), false)?;

self.list.set_branches(get_branches_info(
&self.repo.borrow(),
true,
)?);

if self.commit_details.is_visible() {
let commit = self.selected_commit();
let tags = self.selected_commit_tags(&commit);
Expand Down Expand Up @@ -135,6 +134,21 @@ impl Revlog {
self.update()?;
}
}
AsyncGitNotification::Branches => {
if let Some(branches) =
self.git_branches.take_last()
{
if let Some(Ok(branches)) = branches.result()
{
log::info!(
"branches: {}",
branches.len()
);
self.list.set_branches(branches);
self.update()?;
}
}
}
_ => (),
}
}
Expand Down Expand Up @@ -447,6 +461,12 @@ impl Component for Revlog {
fn show(&mut self) -> Result<()> {
self.visible = true;
self.list.clear();

self.git_branches.spawn(AsyncBranchesJob::new(
self.repo.borrow().clone(),
true,
));

self.update()?;

Ok(())
Expand Down
27 changes: 19 additions & 8 deletions src/tabs/status.rs
Expand Up @@ -14,13 +14,14 @@ use crate::{
};
use anyhow::Result;
use asyncgit::{
asyncjob::AsyncSingleJob,
cached,
sync::{
self, status::StatusType, RepoPath, RepoPathRef, RepoState,
},
sync::{BranchCompare, CommitId},
AsyncDiff, AsyncGitNotification, AsyncStatus, DiffParams,
DiffType, PushType, StatusParams,
AsyncBranchesJob, AsyncDiff, AsyncGitNotification, AsyncStatus,
DiffParams, DiffType, PushType, StatusParams,
};
use crossbeam_channel::Sender;
use crossterm::event::Event;
Expand Down Expand Up @@ -73,6 +74,7 @@ pub struct Status {
git_status_stage: AsyncStatus,
git_branch_state: Option<BranchCompare>,
git_branch_name: cached::BranchName,
git_branches: AsyncSingleJob<AsyncBranchesJob>,
queue: Queue,
git_action_executed: bool,
options: SharedOptions,
Expand Down Expand Up @@ -203,6 +205,7 @@ impl Status {
repo_clone,
sender.clone(),
),
git_branches: AsyncSingleJob::new(sender.clone()),
git_action_executed: false,
git_branch_state: None,
git_branch_name: cached::BranchName::new(repo.clone()),
Expand Down Expand Up @@ -424,14 +427,22 @@ impl Status {
self.git_diff.is_pending()
|| self.git_status_stage.is_pending()
|| self.git_status_workdir.is_pending()
|| self.git_branches.is_pending()
}

fn check_remotes(&mut self) {
//TODO: make get_branches_info async
self.has_remotes =
sync::get_branches_info(&self.repo.borrow(), false)
.map(|branches| !branches.is_empty())
.unwrap_or(false);
self.has_remotes = false;

if let Some(result) = self.git_branches.take_last() {
if let Some(Ok(branches)) = result.result() {
self.has_remotes = !branches.is_empty();
}
} else {
self.git_branches.spawn(AsyncBranchesJob::new(
self.repo.borrow().clone(),
false,
));
}
}

///
Expand All @@ -442,6 +453,7 @@ impl Status {
match ev {
AsyncGitNotification::Diff => self.update_diff()?,
AsyncGitNotification::Status => self.update_status()?,
AsyncGitNotification::Branches => self.check_remotes(),
AsyncGitNotification::Push
| AsyncGitNotification::Pull
| AsyncGitNotification::CommitFiles => {
Expand All @@ -461,7 +473,6 @@ impl Status {
self.index_wd.set_items(&workdir_status.items)?;

self.update_diff()?;
self.check_remotes();

if self.git_action_executed {
self.git_action_executed = false;
Expand Down

0 comments on commit 92f63d1

Please sign in to comment.