Merge pull request #1704 from gitbutlerapp/add-support-for-stash-ref

Add support for stash ref
This commit is contained in:
Nikita Galaiko 2023-11-24 10:09:21 +01:00 committed by GitHub
commit 6f43d7623e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 36 additions and 25 deletions

View File

@ -19,6 +19,7 @@ use crate::git;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Refname {
HEAD,
STASH,
Tag(TagRefname),
Remote(RemoteRefname),
Local(LocalRefname),
@ -64,7 +65,7 @@ impl From<&LocalRefname> for Refname {
impl Refname {
pub fn branch(&self) -> Option<&str> {
match self {
Self::HEAD | Self::Tag(_) => None,
Self::HEAD | Self::Tag(_) | Self::STASH => None,
Self::Remote(remote) => Some(remote.branch()),
Self::Local(local) => Some(local.branch()),
Self::Virtual(r#virtual) => Some(r#virtual.branch()),
@ -76,20 +77,14 @@ impl FromStr for Refname {
type Err = Error;
fn from_str(value: &str) -> Result<Self, Self::Err> {
if value == "HEAD" {
Ok(Self::HEAD)
} else if value.starts_with("refs") {
if value.starts_with("refs/remotes/") {
Ok(Self::Remote(value.parse()?))
} else if value.starts_with("refs/heads/") {
Ok(Self::Local(value.parse()?))
} else if value.starts_with("refs/gitbutler/") {
Ok(Self::Virtual(value.parse()?))
} else {
Err(Error::InvalidName(value.to_string()))
}
} else {
Ok(Self::Local(value.parse()?))
match value {
"HEAD" => Ok(Self::HEAD),
"refs/stash" => Ok(Self::STASH),
value if value.starts_with("refs/tags/") => Ok(Self::Tag(value.parse()?)),
value if value.starts_with("refs/remotes/") => Ok(Self::Remote(value.parse()?)),
value if value.starts_with("refs/heads/") => Ok(Self::Local(value.parse()?)),
value if value.starts_with("refs/gitbutler/") => Ok(Self::Virtual(value.parse()?)),
_ => Err(Error::InvalidName(value.to_string())),
}
}
}
@ -110,6 +105,7 @@ impl fmt::Display for Refname {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::HEAD => write!(f, "HEAD"),
Self::STASH => write!(f, "refs/stash"),
Self::Tag(tag) => tag.fmt(f),
Self::Remote(remote) => remote.fmt(f),
Self::Local(local) => local.fmt(f),
@ -121,6 +117,7 @@ impl fmt::Display for Refname {
impl Serialize for Refname {
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
match self {
Self::STASH => serializer.serialize_str("refs/stash"),
Self::HEAD => serializer.serialize_str("HEAD"),
Self::Tag(tag) => tag.serialize(serializer),
Self::Remote(remote) => remote.serialize(serializer),

View File

@ -330,6 +330,7 @@ impl Repository {
.find_branch(
&match name {
Refname::HEAD => "HEAD".to_string(),
Refname::STASH => "stash".to_string(),
Refname::Tag(tag) => tag.tag().to_string(),
Refname::Virtual(virtual_refname) => virtual_refname.branch().to_string(),
Refname::Local(local) => local.branch().to_string(),
@ -338,9 +339,11 @@ impl Repository {
}
},
match name {
Refname::HEAD | Refname::Virtual(_) | Refname::Local(_) | Refname::Tag(_) => {
git2::BranchType::Local
}
Refname::STASH
| Refname::HEAD
| Refname::Virtual(_)
| Refname::Local(_)
| Refname::Tag(_) => git2::BranchType::Local,
Refname::Remote(_) => git2::BranchType::Remote,
},
)

View File

@ -629,8 +629,11 @@ pub fn create_virtual_branch_from_branch(
// only set upstream if it's not the default target
let upstream_branch = match upstream {
git::Refname::Virtual(_) | git::Refname::HEAD | git::Refname::Tag(_) => {
// we don't support creating virtual branches from virtual branches
git::Refname::STASH
| git::Refname::Virtual(_)
| git::Refname::HEAD
| git::Refname::Tag(_) => {
// we only support local or remote branches
return Err(errors::CreateVirtualBranchFromBranchError::BranchNotFound(
upstream.clone(),
));

View File

@ -5,7 +5,7 @@ use tauri::AppHandle;
use tokio::sync::Mutex;
use crate::{
gb_repository,
gb_repository, git,
paths::DataDir,
project_repository,
projects::{self, CodePushState, ProjectId},
@ -144,10 +144,16 @@ impl HandlerInner {
Err(err) => return Err(err).context("failed to push"),
};
let refs = gb_refs(&project_repository)?;
let refnames = gb_refs(&project_repository)?;
let all_refs = refs
let all_refs = refnames
.iter()
.filter(|r| {
matches!(
r,
git::Refname::Remote(_) | git::Refname::Virtual(_) | git::Refname::Local(_)
)
})
.map(|r| format!("+{}:{}", r, r))
.collect::<Vec<_>>();
@ -169,11 +175,13 @@ impl HandlerInner {
}
}
fn gb_refs(project_repository: &project_repository::Repository) -> anyhow::Result<Vec<String>> {
fn gb_refs(
project_repository: &project_repository::Repository,
) -> anyhow::Result<Vec<git::Refname>> {
Ok(project_repository
.git_repository
.references_glob("refs/*")?
.flatten()
.filter_map(|r| r.name().map(|name| name.to_string()))
.filter_map(|r| r.name())
.collect::<Vec<_>>())
}