Skip to content

Commit b856862

Browse files
committed
wip
1 parent e246f42 commit b856862

File tree

8 files changed

+130
-24
lines changed

8 files changed

+130
-24
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
use anyhow::{Context, Result};
2+
3+
use crate::types::ReferenceName;
4+
5+
pub trait BranchExt {
6+
fn reference_name(&self) -> Result<ReferenceName>;
7+
}
8+
9+
impl<'repo> BranchExt for git2::Branch<'repo> {
10+
fn reference_name(&self) -> Result<ReferenceName> {
11+
let name = self.get().name().context("Failed to get branch name")?;
12+
13+
Ok(name.into())
14+
}
15+
}

crates/gitbutler-core/src/git/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,6 @@ pub use commit_ext::*;
1818

1919
mod commit_buffer;
2020
pub use commit_buffer::*;
21+
22+
mod branch_ext;
23+
pub use branch_ext::*;

crates/gitbutler-core/src/types/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,6 @@ pub mod default_true;
88
pub struct Sensitive<T>(pub T);
99

1010
mod sensitive;
11+
12+
mod tagged_string;
13+
pub use tagged_string::*;
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
use std::{fmt, marker::PhantomData, ops::Deref};
2+
3+
use serde::{Deserialize, Deserializer, Serialize, Serializer};
4+
5+
/// Tagged string is designed to clarify the purpose of strings when used as a return type
6+
pub struct TaggedString<T>(String, PhantomData<T>);
7+
8+
impl<T> From<String> for TaggedString<T> {
9+
fn from(value: String) -> Self {
10+
TaggedString(value, PhantomData)
11+
}
12+
}
13+
14+
impl<T> From<&str> for TaggedString<T> {
15+
fn from(value: &str) -> Self {
16+
TaggedString(value.to_string(), PhantomData)
17+
}
18+
}
19+
20+
impl<T> Deref for TaggedString<T> {
21+
type Target = String;
22+
23+
fn deref(&self) -> &Self::Target {
24+
&self.0
25+
}
26+
}
27+
28+
impl<'de, T> Deserialize<'de> for TaggedString<T> {
29+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
30+
where
31+
D: Deserializer<'de>,
32+
{
33+
String::deserialize(deserializer).map(Into::into)
34+
}
35+
}
36+
37+
impl<T> Serialize for TaggedString<T> {
38+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
39+
where
40+
S: Serializer,
41+
{
42+
self.0.serialize(serializer)
43+
}
44+
}
45+
46+
impl<T> fmt::Display for TaggedString<T> {
47+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48+
self.0.fmt(f)
49+
}
50+
}
51+
52+
impl<T> fmt::Debug for TaggedString<T> {
53+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54+
self.0.fmt(f)
55+
}
56+
}
57+
58+
pub struct _ReferenceName;
59+
/// The name of a reference ie. `refs/heads/master`
60+
pub type ReferenceName = TaggedString<_ReferenceName>;

crates/gitbutler-core/src/virtual_branches/base.rs

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use git2::Index;
55
use serde::Serialize;
66

77
use super::{
8-
branch,
8+
branch, convert_to_real_branch,
99
integration::{
1010
get_workspace_head, update_gitbutler_integration, GITBUTLER_INTEGRATION_REFERENCE,
1111
},
@@ -327,10 +327,10 @@ fn _print_tree(repo: &git2::Repository, tree: &git2::Tree) -> Result<()> {
327327
// determine if what the target branch is now pointing to is mergeable with our current working directory
328328
// merge the target branch into our current working directory
329329
// update the target sha
330-
pub fn update_base_branch(
331-
project_repository: &project_repository::Repository,
330+
pub fn update_base_branch<'repo>(
331+
project_repository: &'repo project_repository::Repository,
332332
user: Option<&users::User>,
333-
) -> anyhow::Result<Vec<branch::Branch>> {
333+
) -> anyhow::Result<Vec<git2::Branch<'repo>>> {
334334
project_repository.assure_resolved()?;
335335

336336
// look up the target and see if there is a new oid
@@ -346,10 +346,10 @@ pub fn update_base_branch(
346346
.peel_to_commit()
347347
.context(format!("failed to peel branch {} to commit", target.branch))?;
348348

349-
let mut unapplied_branches: Vec<branch::Branch> = Vec::new();
349+
let mut unapplied_branch_names: Vec<git2::Branch> = Vec::new();
350350

351351
if new_target_commit.id() == target.sha {
352-
return Ok(unapplied_branches);
352+
return Ok(unapplied_branch_names);
353353
}
354354

355355
let new_target_tree = new_target_commit
@@ -423,11 +423,13 @@ pub fn update_base_branch(
423423

424424
if branch_tree_merge_index.has_conflicts() {
425425
// branch tree conflicts with new target, unapply branch for now. we'll handle it later, when user applies it back.
426-
if branch.applied {
427-
unapplied_branches.push(branch.clone());
428-
}
429-
branch.applied = false;
430-
vb_state.set_branch(branch.clone())?;
426+
let unapplied_real_branch = convert_to_real_branch(
427+
project_repository,
428+
branch.id,
429+
Default::default(),
430+
)?;
431+
unapplied_branch_names.push(unapplied_real_branch);
432+
431433
return Ok(Some(branch));
432434
}
433435

@@ -456,11 +458,13 @@ pub fn update_base_branch(
456458
if branch_head_merge_index.has_conflicts() {
457459
// branch commits conflict with new target, make sure the branch is
458460
// unapplied. conflicts witll be dealt with when applying it back.
459-
if branch.applied {
460-
unapplied_branches.push(branch.clone());
461-
}
462-
branch.applied = false;
463-
vb_state.set_branch(branch.clone())?;
461+
let unapplied_real_branch = convert_to_real_branch(
462+
project_repository,
463+
branch.id,
464+
Default::default(),
465+
)?;
466+
unapplied_branch_names.push(unapplied_real_branch);
467+
464468
return Ok(Some(branch));
465469
}
466470

@@ -567,7 +571,7 @@ pub fn update_base_branch(
567571

568572
// Rewriting the integration commit is necessary after changing target sha.
569573
super::integration::update_gitbutler_integration(&vb_state, project_repository)?;
570-
Ok(unapplied_branches)
574+
Ok(unapplied_branch_names)
571575
}
572576

573577
pub fn target_to_base_branch(

crates/gitbutler-core/src/virtual_branches/controller.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
use crate::ops::entry::{OperationKind, SnapshotDetails};
1+
use crate::{
2+
git::BranchExt,
3+
ops::entry::{OperationKind, SnapshotDetails},
4+
types::ReferenceName,
5+
};
26
use anyhow::Result;
37
use std::{collections::HashMap, path::Path, sync::Arc};
48

@@ -7,7 +11,7 @@ use tokio::{sync::Semaphore, task::JoinHandle};
711

812
use super::{
913
branch::{BranchId, BranchOwnershipClaims},
10-
target, target_to_base_branch, BaseBranch, Branch, NameConflitResolution, RemoteBranchFile,
14+
target, target_to_base_branch, BaseBranch, NameConflitResolution, RemoteBranchFile,
1115
VirtualBranchesHandle,
1216
};
1317
use crate::{
@@ -152,7 +156,7 @@ impl Controller {
152156
.await
153157
}
154158

155-
pub async fn update_base_branch(&self, project_id: ProjectId) -> Result<Vec<Branch>> {
159+
pub async fn update_base_branch(&self, project_id: ProjectId) -> Result<Vec<ReferenceName>> {
156160
self.inner(project_id)
157161
.await
158162
.update_base_branch(project_id)
@@ -551,14 +555,21 @@ impl ControllerInner {
551555
})
552556
}
553557

554-
pub async fn update_base_branch(&self, project_id: ProjectId) -> Result<Vec<Branch>> {
558+
pub async fn update_base_branch(&self, project_id: ProjectId) -> Result<Vec<ReferenceName>> {
555559
let _permit = self.semaphore.acquire().await;
556560

557561
self.with_verify_branch(project_id, |project_repository, user| {
558562
let _ = project_repository
559563
.project()
560564
.create_snapshot(SnapshotDetails::new(OperationKind::UpdateWorkspaceBase));
561-
super::update_base_branch(project_repository, user).map_err(Into::into)
565+
super::update_base_branch(project_repository, user)
566+
.map(|unapplied_branches| {
567+
unapplied_branches
568+
.iter()
569+
.filter_map(|unapplied_branch| unapplied_branch.reference_name().ok())
570+
.collect()
571+
})
572+
.map_err(Into::into)
562573
})
563574
}
564575

crates/gitbutler-core/tests/suite/virtual_branches/update_base_branch.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,15 @@ mod applied_branch {
796796
)
797797
.unwrap();
798798

799+
let branch_count = controller
800+
.list_virtual_branches(*project_id)
801+
.await
802+
.unwrap()
803+
.0
804+
.len();
805+
806+
println!("branch count: {}", branch_count);
807+
799808
{
800809
// merge branch remotely
801810
let branch = controller
@@ -810,7 +819,7 @@ mod applied_branch {
810819
repository.fetch();
811820

812821
{
813-
controller.update_base_branch(*project_id).await.unwrap();
822+
dbg!(controller.update_base_branch(*project_id).await.unwrap());
814823

815824
// removes integrated commit, leaves non commited work as is
816825

crates/gitbutler-tauri/src/virtual_branches.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ pub mod commands {
66
error::Code,
77
git,
88
projects::{self, ProjectId},
9+
types::ReferenceName,
910
virtual_branches::{
1011
branch::{self, BranchId, BranchOwnershipClaims},
1112
controller::Controller,
@@ -154,7 +155,7 @@ pub mod commands {
154155
pub async fn update_base_branch(
155156
handle: AppHandle,
156157
project_id: ProjectId,
157-
) -> Result<Vec<branch::Branch>, Error> {
158+
) -> Result<Vec<ReferenceName>, Error> {
158159
let unapplied_branches = handle
159160
.state::<Controller>()
160161
.update_base_branch(project_id)

0 commit comments

Comments
 (0)