Skip to content

Commit 56b516e

Browse files
committed
wip
1 parent ef6b09b commit 56b516e

File tree

9 files changed

+135
-27
lines changed

9 files changed

+135
-27
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: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@ 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
},
1212
target, BranchId, RemoteCommit, VirtualBranchHunk, VirtualBranchesHandle,
1313
};
14-
use crate::{git::RepositoryExt, virtual_branches::errors::Marker};
14+
use crate::{
15+
git::BranchExt, git::RepositoryExt, types::ReferenceName, virtual_branches::errors::Marker,
16+
};
1517
use crate::{
1618
git::{self, diff},
1719
project_repository::{self, LogUntil},
@@ -326,10 +328,10 @@ fn _print_tree(repo: &git2::Repository, tree: &git2::Tree) -> Result<()> {
326328
// determine if what the target branch is now pointing to is mergeable with our current working directory
327329
// merge the target branch into our current working directory
328330
// update the target sha
329-
pub fn update_base_branch(
330-
project_repository: &project_repository::Repository,
331+
pub fn update_base_branch<'repo>(
332+
project_repository: &'repo project_repository::Repository,
331333
user: Option<&users::User>,
332-
) -> anyhow::Result<Vec<branch::Branch>> {
334+
) -> anyhow::Result<Vec<git2::Branch<'repo>>> {
333335
project_repository.assure_resolved()?;
334336

335337
// look up the target and see if there is a new oid
@@ -345,10 +347,10 @@ pub fn update_base_branch(
345347
.peel_to_commit()
346348
.context(format!("failed to peel branch {} to commit", target.branch))?;
347349

348-
let mut unapplied_branches: Vec<branch::Branch> = Vec::new();
350+
let mut unapplied_branch_names: Vec<git2::Branch> = Vec::new();
349351

350352
if new_target_commit.id() == target.sha {
351-
return Ok(unapplied_branches);
353+
return Ok(unapplied_branch_names);
352354
}
353355

354356
let new_target_tree = new_target_commit
@@ -422,11 +424,13 @@ pub fn update_base_branch(
422424

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

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

@@ -566,7 +572,7 @@ pub fn update_base_branch(
566572

567573
// Rewriting the integration commit is necessary after changing target sha.
568574
super::integration::update_gitbutler_integration(&vb_state, project_repository)?;
569-
Ok(unapplied_branches)
575+
Ok(unapplied_branch_names)
570576
}
571577

572578
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
@@ -795,6 +795,15 @@ mod applied_branch {
795795
)
796796
.unwrap();
797797

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

811820
{
812-
controller.update_base_branch(*project_id).await.unwrap();
821+
dbg!(controller.update_base_branch(*project_id).await.unwrap());
813822

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

crates/gitbutler-core/tests/virtual_branches/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ use std::{
1515
use anyhow::{Context, Result};
1616
use git2::TreeEntry;
1717
use gitbutler_core::{
18-
git::{self, diff, CommitExt, RepositoryExt},
18+
git::{self, CommitExt, RepositoryExt},
1919
virtual_branches::{
2020
self,
2121
branch::{BranchCreateRequest, BranchOwnershipClaims},
2222
commit, create_virtual_branch, create_virtual_branch_from_branch,
2323
integrate_upstream_commits,
24-
integration::{update_gitbutler_integration, verify_branch},
24+
integration::verify_branch,
2525
is_remote_branch_mergeable, list_remote_branches, list_virtual_branches, unapply_ownership,
2626
update_branch,
2727
},

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)