From c58298f48f66e48900716349730f654111ea1d62 Mon Sep 17 00:00:00 2001 From: Nikita Galaiko Date: Fri, 24 Nov 2023 09:56:42 +0100 Subject: [PATCH 1/2] support stash ref --- .../tauri/src/git/reference/refname/mod.rs | 27 +++++++++---------- packages/tauri/src/git/repository.rs | 9 ++++--- packages/tauri/src/virtual_branches/base.rs | 7 +++-- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/packages/tauri/src/git/reference/refname/mod.rs b/packages/tauri/src/git/reference/refname/mod.rs index f9169d0f5..e02718176 100644 --- a/packages/tauri/src/git/reference/refname/mod.rs +++ b/packages/tauri/src/git/reference/refname/mod.rs @@ -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 { - 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(&self, serializer: S) -> Result { 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), diff --git a/packages/tauri/src/git/repository.rs b/packages/tauri/src/git/repository.rs index fea3693a6..81e3a4f8d 100644 --- a/packages/tauri/src/git/repository.rs +++ b/packages/tauri/src/git/repository.rs @@ -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, }, ) diff --git a/packages/tauri/src/virtual_branches/base.rs b/packages/tauri/src/virtual_branches/base.rs index 798822ea1..9eb4a0119 100644 --- a/packages/tauri/src/virtual_branches/base.rs +++ b/packages/tauri/src/virtual_branches/base.rs @@ -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(), )); From 07a2d01e837f58645b3d88c9fad8b8922e8d18bb Mon Sep 17 00:00:00 2001 From: Nikita Galaiko Date: Fri, 24 Nov 2023 10:03:04 +0100 Subject: [PATCH 2/2] filter pushable references by type --- .../handlers/push_project_to_gitbutler.rs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/packages/tauri/src/watcher/handlers/push_project_to_gitbutler.rs b/packages/tauri/src/watcher/handlers/push_project_to_gitbutler.rs index 90896a208..a8561a1e7 100644 --- a/packages/tauri/src/watcher/handlers/push_project_to_gitbutler.rs +++ b/packages/tauri/src/watcher/handlers/push_project_to_gitbutler.rs @@ -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::>(); @@ -169,11 +175,13 @@ impl HandlerInner { } } -fn gb_refs(project_repository: &project_repository::Repository) -> anyhow::Result> { +fn gb_refs( + project_repository: &project_repository::Repository, +) -> anyhow::Result> { 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::>()) }