Skip to content

Commit

Permalink
Create ref on StackBranch construction
Browse files Browse the repository at this point in the history
  • Loading branch information
krlvi committed Feb 21, 2025
1 parent 15b1593 commit 6987743
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 82 deletions.
34 changes: 27 additions & 7 deletions crates/but-workspace/tests/workspace/commit_engine/refs_update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ fn new_commits_to_tip_from_unborn_head() -> anyhow::Result<()> {
("s1-b/first", repo.rev_parse_single("@~1")?.detach()),
("s1-b/init", repo.rev_parse_single("@~2")?.detach()),
],
&repo,
);
vb.branches.insert(stack.id, stack);

Expand All @@ -155,6 +156,7 @@ fn new_commits_to_tip_from_unborn_head() -> anyhow::Result<()> {
("s2-b/first", repo.rev_parse_single("@~1")?.detach()),
("s2-b/init", repo.rev_parse_single("@~2")?.detach()),
],
&repo,
);
vb.branches.insert(stack.id, stack);

Expand Down Expand Up @@ -274,7 +276,12 @@ fn insert_commit_into_single_stack_with_signatures() -> anyhow::Result<()> {
* ecd6722 (tag: first-commit, first-commit) init
");

let stack = stack_with_branches("s1", head_commit_id, [("s1-b/init", initial_commit_id)]);
let stack = stack_with_branches(
"s1",
head_commit_id,
[("s1-b/init", initial_commit_id)],
&repo,
);
vb.branches.insert(stack.id, stack);
// Add 10 lines to the end.
write_sequence(&repo, "file", [(30, None)])?;
Expand Down Expand Up @@ -430,7 +437,12 @@ fn branch_tip_below_non_merge_workspace_commit() -> anyhow::Result<()> {
* 4342edf (tag: first-commit) init
");

let stack = stack_with_branches("s1", head_commit_id, [("s1-b/init", initial_commit_id)]);
let stack = stack_with_branches(
"s1",
head_commit_id,
[("s1-b/init", initial_commit_id)],
&repo,
);
vb.branches.insert(stack.id, stack);

write_sequence(&repo, "file", [(110, None)])?;
Expand Down Expand Up @@ -529,7 +541,7 @@ fn insert_commits_into_workspace() -> anyhow::Result<()> {

let mut vb = VirtualBranchesState::default();
let stack1_head = repo.rev_parse_single("merge^1")?.detach();
let stack = stack_with_branches("s1", head_commit_id, [("s1-b/init", stack1_head)]);
let stack = stack_with_branches("s1", head_commit_id, [("s1-b/init", stack1_head)], &repo);
vb.branches.insert(stack.id, stack);

// another 10 to the end (HEAD range is 1-30).
Expand Down Expand Up @@ -657,7 +669,7 @@ fn merge_commit_remains_unsigned_in_remerge() -> anyhow::Result<()> {

let branch_a = repo.rev_parse_single("A")?.detach();
let mut vb = VirtualBranchesState::default();
let stack = stack_with_branches("s1", branch_a, [("s1-b/top", branch_a)]);
let stack = stack_with_branches("s1", branch_a, [("s1-b/top", branch_a)], &repo);
vb.branches.insert(stack.id, stack);

// initial is 1-30, remove first 5
Expand Down Expand Up @@ -745,6 +757,7 @@ fn commit_on_top_of_branch_in_workspace() -> anyhow::Result<()> {
// The order indicates which one actually is on top, even though they both point to the
// same commit.
[("s1-b/below-top", branch_a), ("s1-b/top", branch_a)],
&repo,
);
vb.branches.insert(stack.id, stack);

Expand Down Expand Up @@ -826,7 +839,7 @@ fn amend_on_top_of_branch_in_workspace() -> anyhow::Result<()> {

let branch_a = repo.rev_parse_single("A")?.detach();
let mut vb = VirtualBranchesState::default();
let stack = stack_with_branches("s1", branch_a, [("s1-b/top", branch_a)]);
let stack = stack_with_branches("s1", branch_a, [("s1-b/top", branch_a)], &repo);
vb.branches.insert(stack.id, stack);

// initial is 1-30, make a change that transfers correctly to A where it is 5-20.
Expand Down Expand Up @@ -910,6 +923,7 @@ mod utils {
name: &str,
tip: gix::ObjectId,
branches: impl IntoIterator<Item = (&'static str, gix::ObjectId)>,
repo: &gix::Repository,
) -> gitbutler_stack::Stack {
gitbutler_stack::Stack {
id: Default::default(),
Expand All @@ -918,7 +932,8 @@ mod utils {
head: tip.to_git2(),
heads: branches
.into_iter()
.map(|(name, target_id)| new_stack_branch(name, target_id))
.map(|(name, target_id)| new_stack_branch(name, target_id, repo))
.filter_map(Result::ok)
.collect(),
notes: String::new(),
source_refname: None,
Expand All @@ -936,11 +951,16 @@ mod utils {
}
}

fn new_stack_branch(name: &str, head: gix::ObjectId) -> gitbutler_stack::StackBranch {
fn new_stack_branch(
name: &str,
head: gix::ObjectId,
repo: &gix::Repository,
) -> anyhow::Result<gitbutler_stack::StackBranch> {
gitbutler_stack::StackBranch::new(
CommitOrChangeId::CommitId(head.to_string()),
name.into(),
None,
repo,
)
}

Expand Down
3 changes: 2 additions & 1 deletion crates/gitbutler-branch-actions/src/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,12 @@ pub fn create_series(
assure_open_workspace_mode(ctx).context("Requires an open workspace mode")?;
let mut stack = ctx.project().virtual_branches().get_stack(stack_id)?;
let normalized_head_name = normalize_branch_name(&req.name)?;
let repo = ctx.gix_repository()?;
// If target_patch is None, create a new head that points to the top of the stack (most recent patch)
if let Some(target_patch) = req.target_patch {
stack.add_series(
ctx,
StackBranch::new(target_patch, normalized_head_name, req.description),
StackBranch::new(target_patch, normalized_head_name, req.description, &repo)?,
req.preceding_head,
)
} else {
Expand Down
40 changes: 1 addition & 39 deletions crates/gitbutler-stack/src/heads.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pub(crate) fn remove_head(
/// Returns new, updated list of heads with the new head added in the correct position.
/// If there are multiple heads pointing to the same patch, it uses `preceding_head` to disambiguate the order.
// TODO: when there is a patch reference for a commit ID and a patch reference for a change ID, recognize if they are equivalent (i.e. point to the same commit)
pub(crate) fn add_head(
pub fn add_head(
existing_heads: Vec<StackBranch>,
new_head: StackBranch,
preceding_head: Option<StackBranch>,
Expand Down Expand Up @@ -138,41 +138,3 @@ pub(crate) fn add_head(
}
Ok(updated_heads)
}

#[cfg(test)]
mod test {
use super::*;
#[test]
fn add_head_with_archived_bottom_head() -> Result<()> {
let mut head_1_archived = StackBranch::new(
CommitOrChangeId::CommitId("328447a2-08aa-4c4d-a1bc-08d5cd82bcd4".to_string()),
"kv-branch-3".to_string(),
None,
);
head_1_archived.archived = true;
let head_2 = StackBranch::new(
CommitOrChangeId::CommitId("11609175-039d-44ee-9d4a-6baa9ad2a750".to_string()),
"more-on-top".to_string(),
None,
);
let existing_heads = vec![head_1_archived.clone(), head_2.clone()];
let new_head = StackBranch::new(
CommitOrChangeId::CommitId("11609175-039d-44ee-9d4a-6baa9ad2a750".to_string()),
"abcd".to_string(),
None,
);
let patches = vec![
CommitOrChangeId::CommitId("92a89ae608d77ff75c1ce52ea9dccc0bccd577e9".to_string()),
CommitOrChangeId::CommitId("11609175-039d-44ee-9d4a-6baa9ad2a750".to_string()),
];

let updated_heads = add_head(
existing_heads,
new_head.clone(),
Some(head_2.clone()),
patches,
)?;
assert_eq!(updated_heads, vec![head_1_archived, head_2, new_head]);
Ok(())
}
}
1 change: 1 addition & 0 deletions crates/gitbutler-stack/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub use state::{VirtualBranches as VirtualBranchesState, VirtualBranchesHandle};
pub use target::Target;

mod heads;
pub use heads::add_head;
pub use stack::{commit_by_oid_or_change_id, CommitsForId, PatchReferenceUpdate, TargetUpdate};

// This is here because CommitOrChangeId::ChangeId is deprecated, for some reason allow cant be done on the CommitOrChangeId struct
Expand Down
16 changes: 9 additions & 7 deletions crates/gitbutler-stack/src/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,9 +306,10 @@ impl Stack {
) -> Result<StackBranch> {
let commit = ctx.repo().find_commit(self.head())?;
let state = branch_state(ctx);
let repo = ctx.gix_repository()?;

let name = Stack::next_available_name(
ctx,
&repo,
&state,
if let Some(refname) = self.upstream.as_ref() {
refname.branch().to_string()
Expand All @@ -319,14 +320,14 @@ impl Stack {
allow_duplicate_refs,
)?;

let reference = StackBranch::new(commit.into(), name, None);
let reference = StackBranch::new(commit.into(), name, None, &repo)?;
validate_name(&reference, &state)?;

Ok(reference)
}

fn next_available_name(
ctx: &CommandContext,
repo: &gix::Repository,
state: &VirtualBranchesHandle,
mut name: String,
allow_duplicate_refs: bool,
Expand All @@ -335,10 +336,9 @@ impl Stack {
Ok(if allow_duplicate_refs {
patch_reference_exists(state, name)?
} else {
let repository = ctx.gix_repository()?;
patch_reference_exists(state, name)?
|| local_reference_exists(&repository, name)?
|| remote_reference_exists(&repository, state, name)?
|| local_reference_exists(repo, name)?
|| remote_reference_exists(repo, state, name)?
})
};
while is_duplicate(&name)? {
Expand Down Expand Up @@ -402,7 +402,9 @@ impl Stack {
let current_top_head = self.heads.last().ok_or(anyhow!(
"Stack is in an invalid state - heads list is empty"
))?;
let new_head = StackBranch::new(current_top_head.head().to_owned(), name, description);
let repo = ctx.gix_repository()?;
let new_head =
StackBranch::new(current_top_head.head().to_owned(), name, description, &repo)?;
self.add_series(ctx, new_head, Some(current_top_head.name().clone()))
}

Expand Down
13 changes: 10 additions & 3 deletions crates/gitbutler-stack/src/stack_branch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,22 @@ impl RepositoryExt for git2::Repository {
}

impl StackBranch {
pub fn new(head: CommitOrChangeId, name: String, description: Option<String>) -> Self {
StackBranch {
pub fn new(
head: CommitOrChangeId,
name: String,
description: Option<String>,
repo: &gix::Repository,
) -> Result<Self> {
let branch = StackBranch {
head,
name,
description,
pr_number: None,
archived: false,
review_id: None,
}
};
let _ = branch.set_real_reference(repo, &branch.head);
Ok(branch)
}

pub fn head(&self) -> &CommitOrChangeId {
Expand Down
Loading

0 comments on commit 6987743

Please sign in to comment.