Specify the correct branch to be the upstream

asdf
This commit is contained in:
Caleb Owens 2024-07-25 15:11:07 +02:00
parent 2540642aaa
commit c1c5d88303
13 changed files with 76 additions and 43 deletions

View File

@ -89,7 +89,11 @@
on:click={async () => {
isApplying = true;
try {
await branchController.createvBranchFromBranch(branch.name);
if (localBranch) {
await branchController.createvBranchFromBranch(localBranch.name, remoteBranch?.name);
} else {
await branchController.createvBranchFromBranch(remoteBranch!.name);
}
goto(`/${project.id}/board`);
} catch (e) {
const err = 'Failed to apply branch';

View File

@ -42,8 +42,6 @@
let localBranchData: BranchData | undefined;
let remoteBranchData: BranchData | undefined;
$: console.log({ localBranch, localBranchData, remoteBranch, remoteBranchData });
// The remote branch service (which needs to be renamed) is responsible for
// fetching local and remote branches.
// We must manually set the branch data to undefined as the component
@ -61,7 +59,7 @@
.getRemoteBranchData(remoteBranch.name)
.then((branchData) => (remoteBranchData = branchData));
} else {
localBranchData = undefined;
remoteBranchData = undefined;
}
$: remoteCommitShas = new Set(remoteBranchData?.commits.map((commit) => commit.id) || []);

View File

@ -276,11 +276,12 @@ You can find them in the 'Branches' sidebar in order to resolve conflicts.`;
}
}
async createvBranchFromBranch(branch: string) {
async createvBranchFromBranch(branch: string, remote: string | undefined = undefined) {
try {
await invoke<string>('create_virtual_branch_from_branch', {
projectId: this.projectId,
branch
branch,
remote
});
} catch (err) {
showError('Failed to create virtual branch', err);

View File

@ -470,12 +470,13 @@ impl VirtualBranchActions {
&self,
project: &Project,
branch: &Refname,
remote: Option<RemoteRefname>,
) -> Result<BranchId> {
let project_repository = open_with_verify(project)?;
let branch_manager = project_repository.branch_manager();
let mut guard = project.exclusive_worktree_access();
branch_manager
.create_virtual_branch_from_branch(branch, guard.write_permission())
.create_virtual_branch_from_branch(branch, remote, guard.write_permission())
.map_err(Into::into)
}
}

View File

@ -14,7 +14,7 @@ use gitbutler_commit::commit_headers::HasCommitHeaders;
use gitbutler_error::error::Marker;
use gitbutler_oplog::SnapshotExt;
use gitbutler_project::access::WorktreeWritePermission;
use gitbutler_reference::Refname;
use gitbutler_reference::{Refname, RemoteRefname};
use gitbutler_repo::{rebase::cherry_rebase, RepoActionsExt, RepositoryExt};
use gitbutler_time::time::now_since_unix_epoch_ms;
use std::borrow::Cow;
@ -126,20 +126,26 @@ impl BranchManager<'_> {
pub fn create_virtual_branch_from_branch(
&self,
upstream: &Refname,
target: &Refname,
upstream_branch: Option<RemoteRefname>,
perm: &mut WorktreeWritePermission,
) -> Result<BranchId> {
// only set upstream if it's not the default target
let upstream_branch = match upstream {
Refname::Other(_) | Refname::Virtual(_) => {
// we only support local or remote branches
bail!("branch {upstream} must be a local or remote branch");
let upstream_branch = match upstream_branch {
Some(upstream_branch) => Some(upstream_branch),
None => {
match target {
Refname::Other(_) | Refname::Virtual(_) => {
// we only support local or remote branches
bail!("branch {target} must be a local or remote branch");
}
Refname::Remote(remote) => Some(remote.clone()),
Refname::Local(local) => local.remote().cloned(),
}
}
Refname::Remote(remote) => Some(remote.clone()),
Refname::Local(local) => local.remote().cloned(),
};
let branch_name = upstream
let branch_name = target
.branch()
.expect("always a branch reference")
.to_string();
@ -153,21 +159,21 @@ impl BranchManager<'_> {
let default_target = vb_state.get_default_target()?;
if let Refname::Remote(remote_upstream) = upstream {
if let Refname::Remote(remote_upstream) = target {
if default_target.branch == *remote_upstream {
bail!("cannot create a branch from default target")
}
}
let repo = self.project_repository.repo();
let head_reference =
repo.find_reference(&upstream.to_string())
.map_err(|err| match err {
err if err.code() == git2::ErrorCode::NotFound => {
anyhow!("branch {upstream} was not found")
}
err => err.into(),
})?;
let head_reference = repo
.find_reference(&target.to_string())
.map_err(|err| match err {
err if err.code() == git2::ErrorCode::NotFound => {
anyhow!("branch {target} was not found")
}
err => err.into(),
})?;
let head_commit = head_reference
.peel_to_commit()
.context("failed to peel to commit")?;
@ -220,7 +226,7 @@ impl BranchManager<'_> {
);
let branch = if let Ok(Some(mut branch)) =
vb_state.find_by_source_refname_where_not_in_workspace(upstream)
vb_state.find_by_source_refname_where_not_in_workspace(target)
{
branch.upstream_head = upstream_branch.is_some().then_some(head_commit.id());
branch.upstream = upstream_branch;
@ -239,7 +245,7 @@ impl BranchManager<'_> {
id: BranchId::generate(),
name: branch_name.clone(),
notes: String::new(),
source_refname: Some(upstream.clone()),
source_refname: Some(target.clone()),
upstream_head: upstream_branch.is_some().then_some(head_commit.id()),
upstream: upstream_branch,
tree: head_commit_tree.id(),

View File

@ -1177,6 +1177,7 @@ fn unapply_branch() -> Result<()> {
let branch_manager = project_repository.branch_manager();
let branch1_id = branch_manager.create_virtual_branch_from_branch(
&Refname::from_str(&real_branch)?,
None,
guard.write_permission(),
)?;
let contents = std::fs::read(Path::new(&project.path).join(file_path))?;
@ -1271,6 +1272,7 @@ fn apply_unapply_added_deleted_files() -> Result<()> {
branch_manager
.create_virtual_branch_from_branch(
&Refname::from_str(&real_branch_2).unwrap(),
None,
guard.write_permission(),
)
.unwrap();
@ -1281,6 +1283,7 @@ fn apply_unapply_added_deleted_files() -> Result<()> {
branch_manager
.create_virtual_branch_from_branch(
&Refname::from_str(&real_branch_3).unwrap(),
None,
guard.write_permission(),
)
.unwrap();

View File

@ -94,7 +94,7 @@ async fn rebase_commit() {
{
// apply first vbranch again
branch1_id = controller
.create_virtual_branch_from_branch(project, &unapplied_branch)
.create_virtual_branch_from_branch(project, &unapplied_branch, None)
.await
.unwrap();
@ -192,7 +192,7 @@ async fn rebase_work() {
{
// apply first vbranch again
branch1_id = controller
.create_virtual_branch_from_branch(project, &unapplied_branch)
.create_virtual_branch_from_branch(project, &unapplied_branch, None)
.await
.unwrap();

View File

@ -92,7 +92,7 @@ async fn conflicting() {
let branch_id = {
// apply branch, it should conflict
let branch_id = controller
.create_virtual_branch_from_branch(project, &unapplied_branch)
.create_virtual_branch_from_branch(project, &unapplied_branch, None)
.await
.unwrap();

View File

@ -56,7 +56,7 @@ async fn integration() {
// checkout a existing remote branch
let branch_id = controller
.create_virtual_branch_from_branch(project, &branch_name)
.create_virtual_branch_from_branch(project, &branch_name, None)
.await
.unwrap();
@ -151,7 +151,11 @@ async fn no_conflicts() {
assert!(branches.is_empty());
let branch_id = controller
.create_virtual_branch_from_branch(project, &"refs/remotes/origin/branch".parse().unwrap())
.create_virtual_branch_from_branch(
project,
&"refs/remotes/origin/branch".parse().unwrap(),
None,
)
.await
.unwrap();
@ -197,7 +201,11 @@ async fn conflicts_with_uncommited() {
// branch should be created unapplied, because of the conflict
let new_branch_id = controller
.create_virtual_branch_from_branch(project, &"refs/remotes/origin/branch".parse().unwrap())
.create_virtual_branch_from_branch(
project,
&"refs/remotes/origin/branch".parse().unwrap(),
None,
)
.await
.unwrap();
let new_branch = controller
@ -253,7 +261,11 @@ async fn conflicts_with_commited() {
// branch should be created unapplied, because of the conflict
let new_branch_id = controller
.create_virtual_branch_from_branch(project, &"refs/remotes/origin/branch".parse().unwrap())
.create_virtual_branch_from_branch(
project,
&"refs/remotes/origin/branch".parse().unwrap(),
None,
)
.await
.unwrap();
let new_branch = controller
@ -289,6 +301,7 @@ async fn from_default_target() {
.create_virtual_branch_from_branch(
project,
&"refs/remotes/origin/master".parse().unwrap(),
None
)
.await
.unwrap_err()
@ -317,6 +330,7 @@ async fn from_non_existent_branch() {
.create_virtual_branch_from_branch(
project,
&"refs/remotes/origin/branch".parse().unwrap(),
None
)
.await
.unwrap_err()
@ -355,7 +369,11 @@ async fn from_state_remote_branch() {
.unwrap();
let branch_id = controller
.create_virtual_branch_from_branch(project, &"refs/remotes/origin/branch".parse().unwrap())
.create_virtual_branch_from_branch(
project,
&"refs/remotes/origin/branch".parse().unwrap(),
None,
)
.await
.unwrap();

View File

@ -136,7 +136,7 @@ async fn resolve_conflict_flow() {
let branch1_id = {
// when we apply conflicted branch, it has conflict
let branch1_id = controller
.create_virtual_branch_from_branch(project, &unapplied_branch)
.create_virtual_branch_from_branch(project, &unapplied_branch, None)
.await
.unwrap();

View File

@ -376,7 +376,7 @@ async fn applying_first_branch() {
.unwrap();
let unapplied_branch = Refname::from_str(&unapplied_branch).unwrap();
controller
.create_virtual_branch_from_branch(project, &unapplied_branch)
.create_virtual_branch_from_branch(project, &unapplied_branch, None)
.await
.unwrap();

View File

@ -54,7 +54,7 @@ mod applied_branch {
{
// applying the branch should produce conflict markers
controller
.create_virtual_branch_from_branch(project, &unapplied_branch)
.create_virtual_branch_from_branch(project, &unapplied_branch, None)
.await
.unwrap();
let (branches, _) = controller.list_virtual_branches(project).await.unwrap();
@ -124,7 +124,7 @@ mod applied_branch {
{
// applying the branch should produce conflict markers
controller
.create_virtual_branch_from_branch(project, &unapplied_branch)
.create_virtual_branch_from_branch(project, &unapplied_branch, None)
.await
.unwrap();
let (branches, _) = controller.list_virtual_branches(project).await.unwrap();
@ -200,7 +200,7 @@ mod applied_branch {
{
// applying the branch should produce conflict markers
controller
.create_virtual_branch_from_branch(project, &unapplied_branch)
.create_virtual_branch_from_branch(project, &unapplied_branch, None)
.await
.unwrap();
let (branches, _) = controller.list_virtual_branches(project).await.unwrap();
@ -273,7 +273,7 @@ mod applied_branch {
{
// applying the branch should produce conflict markers
controller
.create_virtual_branch_from_branch(project, &unapplied_branch)
.create_virtual_branch_from_branch(project, &unapplied_branch, None)
.await
.unwrap();
let (branches, _) = controller.list_virtual_branches(project).await.unwrap();
@ -346,7 +346,7 @@ mod applied_branch {
{
// applying the branch should produce conflict markers
controller
.create_virtual_branch_from_branch(project, &unapplied_branch)
.create_virtual_branch_from_branch(project, &unapplied_branch, None)
.await
.unwrap();
let (branches, _) = controller.list_virtual_branches(project).await.unwrap();
@ -767,6 +767,7 @@ mod applied_branch {
.create_virtual_branch_from_branch(
project,
&Refname::from_str(unapplied_refname.as_str()).unwrap(),
None,
)
.await
.unwrap();

View File

@ -83,10 +83,11 @@ pub mod commands {
projects: State<'_, projects::Controller>,
project_id: ProjectId,
branch: Refname,
remote: Option<RemoteRefname>,
) -> Result<BranchId, Error> {
let project = projects.get(project_id)?;
let branch_id = VirtualBranchActions
.create_virtual_branch_from_branch(&project, &branch)
.create_virtual_branch_from_branch(&project, &branch, remote)
.await?;
emit_vbranches(&windows, project_id).await;
Ok(branch_id)