Skip to content

Commit

Permalink
Rework branch() to use new cherry_pick()
Browse files Browse the repository at this point in the history
Rework branch() to use new cherry_pick() so that we could simplify the
implementation and a bunch of duplication.

<!-- ps-id: 6b8c0cbe-d38f-4c5d-aed7-3117c2366513 -->
  • Loading branch information
drewdeponte committed Mar 22, 2023
1 parent 66aff7b commit 66524d0
Showing 1 changed file with 59 additions and 110 deletions.
169 changes: 59 additions & 110 deletions src/ps/public/branch.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::super::super::ps;
use super::super::private::cherry_picking;
use super::super::private::git;
use git2;
use std::result::Result;
Expand All @@ -22,6 +23,7 @@ pub enum BranchError {
GetUpstreamBranchNameFailed,
GetRemoteBranchNameFailed,
PushFailed(git::ExtForcePushError),
FailedToMapIndexesForCherryPick(cherry_picking::MapRangeForCherryPickError),
}

pub fn branch(
Expand All @@ -40,118 +42,65 @@ pub fn branch(
.peel_to_commit()
.map_err(|_| BranchError::PatchStackBaseNotFound)?;

if let Some(end_patch_index) = end_patch_index_option {
// find the patch series in the patch stack
let patches_vec =
ps::get_patch_list(&repo, &patch_stack).map_err(BranchError::GetPatchListFailed)?;
let start_patch_oid = patches_vec
.get(start_patch_index)
.ok_or(BranchError::PatchIndexNotFound)?
.oid;
let end_patch_oid = patches_vec
.get(end_patch_index)
.ok_or(BranchError::PatchIndexNotFound)?
.oid;

// translate the patch series to bounds for the cherry-pick range
let start_patch_commit = repo
.find_commit(start_patch_oid)
.map_err(BranchError::FindCommitFailed)?;
let start_patch_parent_commit = start_patch_commit
.parent(0)
.map_err(BranchError::GetCommitParentZeroFailed)?;
let start_patch_parent_oid = start_patch_parent_commit.id();

// generate the default branch name and use provided branch name or fallback
let patch_summary = start_patch_commit
.summary()
.ok_or(BranchError::PatchSummaryMissing)?;
let default_branch_name = ps::generate_branch_branch_name(patch_summary);
let branch_name = given_branch_name_option.unwrap_or(default_branch_name);

// create a branch on the base of the current patch stack
let branch = repo
.branch(branch_name.as_str(), &patch_stack_base_commit, true)
.map_err(BranchError::CreateBranchFailed)?;
let branch_ref_name = branch.get().name().ok_or(BranchError::BranchNameNotUtf8)?;

// cherry-pick the series of patches into the new branch
git::cherry_pick_no_working_copy_range(
&repo,
&config,
start_patch_parent_oid,
end_patch_oid,
let patches_vec =
ps::get_patch_list(&repo, &patch_stack).map_err(BranchError::GetPatchListFailed)?;

let start_patch_oid = patches_vec
.get(start_patch_index)
.ok_or(BranchError::PatchIndexNotFound)?
.oid;
let start_patch_commit = repo
.find_commit(start_patch_oid)
.map_err(BranchError::FindCommitFailed)?;

// generate the default branch name and use provided branch name or fallback
let patch_summary = start_patch_commit
.summary()
.ok_or(BranchError::PatchSummaryMissing)?;
let default_branch_name = ps::generate_branch_branch_name(patch_summary);
let branch_name = given_branch_name_option.unwrap_or(default_branch_name);

// create a branch on the base of the current patch stack
let branch = repo
.branch(branch_name.as_str(), &patch_stack_base_commit, true)
.map_err(BranchError::CreateBranchFailed)?;
let branch_ref_name = branch.get().name().ok_or(BranchError::BranchNameNotUtf8)?;

// cherry pick the patch or patch range onto new isolation branch
let cherry_pick_range = cherry_picking::map_range_for_cherry_pick(
&patches_vec,
start_patch_index,
end_patch_index_option,
)
.map_err(BranchError::FailedToMapIndexesForCherryPick)?;

git::cherry_pick(
&repo,
&config,
cherry_pick_range.root_oid,
cherry_pick_range.leaf_oid,
branch_ref_name,
)
.map_err(BranchError::CherryPickFailed)?;

// push branch up to remote branch
if create_remote_branch {
// get remote name of current branch (e.g. origin)
let cur_branch_name =
git::get_current_branch(&repo).ok_or(BranchError::CurrentBranchNameMissing)?;
let branch_upstream_name = git::branch_upstream_name(&repo, cur_branch_name.as_str())
.map_err(|_| BranchError::GetUpstreamBranchNameFailed)?;
let remote_name = repo
.branch_remote_name(&branch_upstream_name)
.map_err(|_| BranchError::GetRemoteBranchNameFailed)?;

git::ext_push(
true,
remote_name.as_str().unwrap(),
branch_ref_name,
branch_ref_name,
)
.map_err(BranchError::CherryPickFailed)?;

// push branch up to remote branch
if create_remote_branch {
// get remote name of current branch (e.g. origin)
let cur_branch_name =
git::get_current_branch(&repo).ok_or(BranchError::CurrentBranchNameMissing)?;
let branch_upstream_name = git::branch_upstream_name(&repo, cur_branch_name.as_str())
.map_err(|_| BranchError::GetUpstreamBranchNameFailed)?;
let remote_name = repo
.branch_remote_name(&branch_upstream_name)
.map_err(|_| BranchError::GetRemoteBranchNameFailed)?;

git::ext_push(
true,
remote_name.as_str().unwrap(),
branch_ref_name,
branch_ref_name,
)
.map_err(BranchError::PushFailed)?;
}
} else {
// find the patch in the patch stack
let patches_vec =
ps::get_patch_list(&repo, &patch_stack).map_err(BranchError::GetPatchListFailed)?;
let patch_oid = patches_vec
.get(start_patch_index)
.ok_or(BranchError::PatchIndexNotFound)?
.oid;

// generate the default branch name and use provided branch name or fallback
let patch_commit = repo
.find_commit(patch_oid)
.map_err(BranchError::PatchCommitNotFound)?;
let patch_summary = patch_commit
.summary()
.ok_or(BranchError::PatchSummaryMissing)?;
let default_branch_name = ps::generate_branch_branch_name(patch_summary);
let branch_name = given_branch_name_option.unwrap_or(default_branch_name);

// create a branch on the base of the current patch stack
let branch = repo
.branch(branch_name.as_str(), &patch_stack_base_commit, true)
.map_err(BranchError::CreateBranchFailed)?;
let branch_ref_name = branch.get().name().ok_or(BranchError::BranchNameNotUtf8)?;

// cherry-pick the single patch into the new branch
git::cherry_pick_no_working_copy(&repo, &config, patch_oid, branch_ref_name, 0)
.map_err(BranchError::CherryPickFailed)?;

// push branch up to remote branch
if create_remote_branch {
// get remote name of current branch (e.g. origin)
let cur_branch_name =
git::get_current_branch(&repo).ok_or(BranchError::CurrentBranchNameMissing)?;
let branch_upstream_name = git::branch_upstream_name(&repo, cur_branch_name.as_str())
.map_err(|_| BranchError::GetUpstreamBranchNameFailed)?;
let remote_name = repo
.branch_remote_name(&branch_upstream_name)
.map_err(|_| BranchError::GetRemoteBranchNameFailed)?;

git::ext_push(
true,
remote_name.as_str().unwrap(),
branch_ref_name,
branch_ref_name,
)
.map_err(BranchError::PushFailed)?;
}
.map_err(BranchError::PushFailed)?;
}

Ok(())
Expand Down

0 comments on commit 66524d0

Please sign in to comment.