WIP
This commit is contained in:
parent
4bee06e507
commit
231a348e69
6 changed files with 106 additions and 1 deletions
|
@ -3,6 +3,7 @@ pub mod commit;
|
|||
mod hosting_provider;
|
||||
mod remote;
|
||||
pub mod repository;
|
||||
pub mod stash;
|
||||
pub mod status;
|
||||
|
||||
pub use crate::hosting_provider::*;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::commit::parse_git_diff_name_status;
|
||||
use crate::stash::GitStash;
|
||||
use crate::status::{GitStatus, StatusCode};
|
||||
use crate::{Oid, SHORT_SHA_LENGTH};
|
||||
use anyhow::{Context as _, Result, anyhow, bail};
|
||||
|
@ -338,6 +339,8 @@ pub trait GitRepository: Send + Sync {
|
|||
|
||||
fn status(&self, path_prefixes: &[RepoPath]) -> Task<Result<GitStatus>>;
|
||||
|
||||
fn stash_entries(&self) -> BoxFuture<'_, Result<GitStash>>;
|
||||
|
||||
fn branches(&self) -> BoxFuture<'_, Result<Vec<Branch>>>;
|
||||
|
||||
fn change_branch(&self, name: String) -> BoxFuture<'_, Result<()>>;
|
||||
|
@ -974,6 +977,26 @@ impl GitRepository for RealGitRepository {
|
|||
})
|
||||
}
|
||||
|
||||
fn stash_entries(&self) -> BoxFuture<'_, Result<GitStash>> {
|
||||
let git_binary_path = self.git_binary_path.clone();
|
||||
let working_directory = self.working_directory();
|
||||
self.executor
|
||||
.spawn(async move {
|
||||
let output = new_std_command(&git_binary_path)
|
||||
.current_dir(working_directory?)
|
||||
.args(&["stash", "list", "--pretty=%gd:%H:%s"])
|
||||
.output()?;
|
||||
if output.status.success() {
|
||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||
stdout.parse()
|
||||
} else {
|
||||
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||
anyhow::bail!("git status failed: {stderr}");
|
||||
}
|
||||
})
|
||||
.boxed()
|
||||
}
|
||||
|
||||
fn branches(&self) -> BoxFuture<'_, Result<Vec<Branch>>> {
|
||||
let working_directory = self.working_directory();
|
||||
let git_binary_path = self.git_binary_path.clone();
|
||||
|
|
56
crates/git/src/stash.rs
Normal file
56
crates/git/src/stash.rs
Normal file
|
@ -0,0 +1,56 @@
|
|||
use crate::Oid;
|
||||
use anyhow::Result;
|
||||
use std::{str::FromStr, sync::Arc};
|
||||
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||
pub struct StashEntry {
|
||||
pub index: usize,
|
||||
pub oid: Oid,
|
||||
pub message: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)]
|
||||
pub struct GitStash {
|
||||
pub entries: Arc<[StashEntry]>,
|
||||
}
|
||||
|
||||
impl FromStr for GitStash {
|
||||
type Err = anyhow::Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self> {
|
||||
// git stash list --pretty=%gd:%H:%s
|
||||
let entries = s
|
||||
.split('\n')
|
||||
.filter_map(|entry| {
|
||||
let mut parts = entry.splitn(3, ':');
|
||||
let raw_idx = parts.next().and_then(|i| {
|
||||
let trimmed = i.trim();
|
||||
if trimmed.starts_with("stash@{") && trimmed.ends_with('}') {
|
||||
trimmed
|
||||
.strip_prefix("stash@{")
|
||||
.and_then(|s| s.strip_suffix('}'))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
let raw_oid = parts.next();
|
||||
let message = parts.next();
|
||||
|
||||
if let (Some(raw_idx), Some(raw_oid), Some(message)) = (raw_idx, raw_oid, message) {
|
||||
let index = raw_idx.parse::<usize>().ok()?;
|
||||
let oid = Oid::from_str(raw_oid).ok()?;
|
||||
let entry = StashEntry {
|
||||
index,
|
||||
oid,
|
||||
message: message.to_string(),
|
||||
};
|
||||
return Some(entry);
|
||||
}
|
||||
None
|
||||
})
|
||||
.collect::<Arc<[StashEntry]>>();
|
||||
Ok(Self {
|
||||
entries: entries.clone(),
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue