Remove ideas about being unapplied

This commit is contained in:
Caleb Owens 2024-06-16 18:43:25 +02:00
parent 56b516e3e0
commit 95f7f500ee
No known key found for this signature in database
9 changed files with 73 additions and 193 deletions

View File

@ -80,9 +80,7 @@ impl Project {
let mut head_tree_ids = Vec::new();
for branch in vb_state.list_branches()? {
if branch.applied {
head_tree_ids.push(branch.tree);
}
head_tree_ids.push(branch.tree);
// commits in virtual branches (tree and commit data)
// calculate all the commits between branch.head and the target and codify them
@ -685,10 +683,7 @@ fn lines_since_snapshot(project: &Project, repo: &git2::Repository) -> Result<us
let vbranches = project.virtual_branches().list_branches()?;
let mut lines_changed = 0;
let dirty_branches = vbranches
.iter()
.filter(|b| b.applied)
.filter(|b| !b.ownership.claims.is_empty());
let dirty_branches = vbranches.iter().filter(|b| !b.ownership.claims.is_empty());
for branch in dirty_branches {
lines_changed += branch_lines_since_snapshot(branch, repo, oplog_commit_id)?;
}
@ -782,12 +777,8 @@ fn tree_from_applied_vbranches(
let vbs_from_toml: crate::virtual_branches::VirtualBranchesState =
toml::from_str(from_utf8(vb_toml_blob.content())?)?;
let applied_branch_trees: Vec<git2::Oid> = vbs_from_toml
.branches
.values()
.filter(|b| b.applied)
.map(|b| b.tree)
.collect();
let applied_branch_trees: Vec<git2::Oid> =
vbs_from_toml.branches.values().map(|b| b.tree).collect();
let mut workdir_tree_id = target_tree.id();
let base_tree = target_tree;

View File

@ -11,9 +11,7 @@ use super::{
},
target, BranchId, RemoteCommit, VirtualBranchHunk, VirtualBranchesHandle,
};
use crate::{
git::BranchExt, git::RepositoryExt, types::ReferenceName, virtual_branches::errors::Marker,
};
use crate::{git::RepositoryExt, virtual_branches::errors::Marker};
use crate::{
git::{self, diff},
project_repository::{self, LogUntil},
@ -69,11 +67,6 @@ fn go_back_to_integration(
.list_branches()
.context("failed to read virtual branches")?;
let applied_virtual_branches = all_virtual_branches
.iter()
.filter(|branch| branch.applied)
.collect::<Vec<_>>();
let target_commit = project_repository
.repo()
.find_commit(default_target.sha)
@ -85,7 +78,7 @@ fn go_back_to_integration(
let mut final_tree = target_commit
.tree()
.context("failed to get base tree from commit")?;
for branch in &applied_virtual_branches {
for branch in &all_virtual_branches {
// merge this branches tree with our tree
let branch_head = project_repository
.repo()
@ -243,7 +236,7 @@ pub fn set_base_branch(
id: BranchId::generate(),
name: head_name.to_string().replace("refs/heads/", ""),
notes: String::new(),
applied: true,
old_applied: true,
upstream,
upstream_head,
created_timestamp_ms: now_ms,
@ -547,7 +540,6 @@ pub fn update_base_branch<'repo>(
let final_tree = updated_vbranches
.iter()
.filter(|branch| branch.applied)
.fold(new_target_commit.tree(), |final_tree, branch| {
let repo: &git2::Repository = repo;
let final_tree = final_tree?;

View File

@ -21,7 +21,9 @@ pub struct Branch {
pub id: BranchId,
pub name: String,
pub notes: String,
pub applied: bool,
/// Previously used to determine if the branch should be shown on the board. If a branch is not shown on the board, it is converted to a real git branch.
#[serde(rename = "applied")]
pub old_applied: bool,
pub upstream: Option<git::RemoteRefname>,
// upstream_head is the last commit on we've pushed to the upstream branch
#[serde(with = "crate::serde::oid_opt", default)]

View File

@ -134,7 +134,6 @@ pub fn reconcile_claims(
) -> Result<Vec<ClaimOutcome>> {
let mut other_branches = all_branches
.into_iter()
.filter(|branch| branch.applied)
.filter(|branch| branch.id != claiming_branch.id)
.collect::<Vec<_>>();

View File

@ -44,10 +44,7 @@ pub fn get_workspace_head(
let vb_state = project_repo.project().virtual_branches();
let all_virtual_branches = vb_state.list_branches()?;
let applied_branches = all_virtual_branches
.iter()
.filter(|branch| branch.applied)
.collect::<Vec<_>>();
let branches = all_virtual_branches.iter().collect::<Vec<_>>();
let target_commit = repo.find_commit(target.sha)?;
let mut workspace_tree = target_commit.tree()?;
@ -55,12 +52,12 @@ pub fn get_workspace_head(
if conflicts::is_conflicting(project_repo, None)? {
let merge_parent =
conflicts::merge_parent(project_repo)?.ok_or(anyhow!("No merge parent"))?;
let first_branch = applied_branches.first().ok_or(anyhow!("No branches"))?;
let first_branch = branches.first().ok_or(anyhow!("No branches"))?;
let merge_base = repo.merge_base(first_branch.head, merge_parent)?;
workspace_tree = repo.find_commit(merge_base)?.tree()?;
} else {
for branch in &applied_branches {
for branch in &branches {
let branch_tree = repo.find_commit(branch.head)?.tree()?;
let merge_tree = repo.find_commit(target.sha)?.tree()?;
let mut index = repo.merge_trees(&merge_tree, &workspace_tree, &branch_tree, None)?;
@ -73,7 +70,7 @@ pub fn get_workspace_head(
}
}
let branch_heads = applied_branches
let branch_heads = branches
.iter()
.map(|b| repo.find_commit(b.head))
.collect::<Result<Vec<_>, _>>()?;
@ -87,7 +84,7 @@ pub fn get_workspace_head(
// TODO(mg): Can we make this a constant?
let committer = get_integration_commiter()?;
let mut heads: Vec<git2::Commit<'_>> = applied_branches
let mut heads: Vec<git2::Commit<'_>> = branches
.iter()
.filter(|b| b.head != target.sha)
.map(|b| repo.find_commit(b.head))
@ -177,11 +174,6 @@ pub fn update_gitbutler_integration(
.list_branches()
.context("failed to list virtual branches")?;
let applied_virtual_branches = all_virtual_branches
.iter()
.filter(|branch| branch.applied)
.collect::<Vec<_>>();
let integration_commit =
repo.find_commit(get_workspace_head(&vb_state, project_repository)?)?;
let integration_tree = integration_commit.tree()?;
@ -200,7 +192,7 @@ pub fn update_gitbutler_integration(
message.push_str("If you switch to another branch, GitButler will need to be reinitialized.\n");
message.push_str("If you commit on this branch, GitButler will throw it away.\n\n");
message.push_str("Here are the branches that are currently applied:\n");
for branch in &applied_virtual_branches {
for branch in &all_virtual_branches {
message.push_str(" - ");
message.push_str(branch.name.as_str());
message.push_str(format!(" ({})", &branch.refname()).as_str());

View File

@ -247,10 +247,6 @@ pub fn apply_branch(
let mut branch = vb_state.get_branch(branch_id)?;
if branch.applied {
return Ok(branch.name);
}
let target_commit = repo
.find_commit(default_target.sha)
.context("failed to find target commit")?;
@ -287,15 +283,10 @@ pub fn apply_branch(
.0
.into_iter()
.map(|(branch, _)| branch)
.filter(|branch| branch.applied)
{
convert_to_real_branch(project_repository, branch.id, Default::default())?;
}
// apply the branch
branch.applied = true;
vb_state.set_branch(branch.clone())?;
// checkout the conflicts
repo.checkout_index_builder(&mut merge_index)
.allow_conflicts()
@ -435,10 +426,6 @@ pub fn apply_branch(
.context(Marker::ProjectConflict);
}
// apply the branch
branch.applied = true;
vb_state.set_branch(branch.clone())?;
ensure_selected_for_changes(&vb_state).context("failed to ensure selected for changes")?;
// checkout the merge index
repo.checkout_index_builder(&mut merge_index)
@ -484,11 +471,10 @@ pub fn unapply_ownership(
let vb_state = project_repository.project().virtual_branches();
let default_target = vb_state.get_default_target()?;
let applied_branches = vb_state
let branches = vb_state
.list_branches()
.context("failed to read virtual branches")?
.into_iter()
.filter(|b| b.applied)
.collect::<Vec<_>>();
let integration_commit_id = get_workspace_head(&vb_state, project_repository)?;
@ -497,7 +483,7 @@ pub fn unapply_ownership(
project_repository,
&integration_commit_id,
&default_target.sha,
applied_branches,
branches,
)
.context("failed to get status by branch")?;
@ -707,55 +693,51 @@ pub fn convert_to_real_branch(
let vb_state = project_repository.project().virtual_branches();
let target_branch = vb_state.get_branch(branch_id)?;
if target_branch.applied {
let repo = project_repository.repo();
let repo = project_repository.repo();
let integration_commit = repo.integration_commit()?;
let target_commit = repo.target_commit()?;
let base_tree = target_commit.tree().context("failed to get target tree")?;
let integration_commit = repo.integration_commit()?;
let target_commit = repo.target_commit()?;
let base_tree = target_commit.tree().context("failed to get target tree")?;
let applied_branches = vb_state
.list_branches()
.context("failed to read virtual branches")?
.into_iter()
.filter(|b| b.applied)
.collect::<Vec<_>>();
let branches = vb_state
.list_branches()
.context("failed to read virtual branches")?
.into_iter()
.collect::<Vec<_>>();
let (applied_statuses, _) = get_applied_status(
project_repository,
&integration_commit.id(),
&target_commit.id(),
applied_branches,
)
.context("failed to get status by branch")?;
let (applied_statuses, _) = get_applied_status(
project_repository,
&integration_commit.id(),
&target_commit.id(),
branches,
)
.context("failed to get status by branch")?;
// go through the other applied branches and merge them into the final tree
// then check that out into the working directory
let final_tree = applied_statuses
.into_iter()
.filter(|(branch, _)| branch.id != branch_id)
.fold(
target_commit.tree().context("failed to get target tree"),
|final_tree, status| {
let final_tree = final_tree?;
let branch = status.0;
let tree_oid = write_tree(project_repository, &branch.head, status.1)?;
let branch_tree = repo.find_tree(tree_oid)?;
let mut result =
repo.merge_trees(&base_tree, &final_tree, &branch_tree, None)?;
let final_tree_oid = result.write_tree_to(repo)?;
repo.find_tree(final_tree_oid)
.context("failed to find tree")
},
)?;
// go through the other applied branches and merge them into the final tree
// then check that out into the working directory
let final_tree = applied_statuses
.into_iter()
.filter(|(branch, _)| branch.id != branch_id)
.fold(
target_commit.tree().context("failed to get target tree"),
|final_tree, status| {
let final_tree = final_tree?;
let branch = status.0;
let tree_oid = write_tree(project_repository, &branch.head, status.1)?;
let branch_tree = repo.find_tree(tree_oid)?;
let mut result = repo.merge_trees(&base_tree, &final_tree, &branch_tree, None)?;
let final_tree_oid = result.write_tree_to(repo)?;
repo.find_tree(final_tree_oid)
.context("failed to find tree")
},
)?;
// checkout final_tree into the working directory
repo.checkout_tree_builder(&final_tree)
.force()
.remove_untracked()
.checkout()
.context("failed to checkout tree")?;
}
// checkout final_tree into the working directory
repo.checkout_tree_builder(&final_tree)
.force()
.remove_untracked()
.checkout()
.context("failed to checkout tree")?;
// Convert the vbranch to a real branch
let real_branch =
@ -817,7 +799,7 @@ pub fn list_virtual_branches(
.unwrap_or(-1);
for (branch, files) in statuses {
if !branch.applied {
if !branch.old_applied {
convert_to_real_branch(project_repository, branch.id, Default::default())?;
}
@ -887,10 +869,8 @@ pub fn list_virtual_branches(
let merge_base = repo
.merge_base(default_target.sha, branch.head)
.context("failed to find merge base")?;
let mut base_current = true;
if !branch.applied {
base_current = merge_base == default_target.sha;
}
let base_current = merge_base == default_target.sha;
let upstream = upstream_branch
.map(|upstream_branch| branch_to_remote_branch(&upstream_branch))
@ -925,7 +905,7 @@ pub fn list_virtual_branches(
id: branch.id,
name: branch.name,
notes: branch.notes,
active: branch.applied,
active: branch.old_applied,
files,
order: branch.order,
commits: vbranch_commits,
@ -1138,7 +1118,7 @@ pub fn create_virtual_branch(
id: BranchId::generate(),
name: name.clone(),
notes: String::new(),
applied: true,
old_applied: true,
upstream: None,
upstream_head: None,
tree: tree.id(),
@ -1488,7 +1468,6 @@ fn ensure_selected_for_changes(vb_state: &VirtualBranchesHandle) -> Result<()> {
.list_branches()
.context("failed to list branches")?
.into_iter()
.filter(|b| b.applied)
.collect::<Vec<_>>();
if applied_branches.is_empty() {
@ -1615,68 +1594,15 @@ pub fn get_status_by_branch(
.list_branches()
.context("failed to read virtual branches")?;
let applied_virtual_branches = virtual_branches
.iter()
.filter(|branch| branch.applied)
.cloned()
.collect::<Vec<_>>();
let (applied_status, skipped_files) = get_applied_status(
project_repository,
// TODO: Keep this optional or update lots of tests?
integration_commit.unwrap_or(&default_target.sha),
&default_target.sha,
applied_virtual_branches,
virtual_branches,
)?;
let non_applied_virtual_branches = virtual_branches
.into_iter()
.filter(|branch| !branch.applied)
.collect::<Vec<_>>();
let non_applied_status =
get_non_applied_status(project_repository, non_applied_virtual_branches)?;
Ok((
applied_status
.into_iter()
.chain(non_applied_status)
.collect(),
skipped_files,
))
}
// given a list of non applied virtual branches, return the status of each file, comparing the default target with
// virtual branch latest tree
//
// ownerships are not taken into account here, as they are not relevant for non applied branches
fn get_non_applied_status(
project_repository: &project_repository::Repository,
virtual_branches: Vec<branch::Branch>,
) -> Result<Vec<(branch::Branch, BranchStatus)>> {
virtual_branches
.into_iter()
.map(|branch| -> Result<(branch::Branch, BranchStatus)> {
if branch.applied {
bail!("branch {} is applied", branch.name);
}
let branch_tree = project_repository
.repo()
.find_tree(branch.tree)
.context(format!("failed to find tree {}", branch.tree))?;
let head_tree = project_repository
.repo()
.find_commit(branch.head)
.context("failed to find target commit")?
.tree()
.context("failed to find target tree")?;
let diff = diff::trees(project_repository.repo(), &head_tree, &branch_tree)?;
Ok((branch, diff::diff_files_into_hunks(diff).collect()))
})
.collect::<Result<Vec<_>>>()
Ok((applied_status, skipped_files))
}
fn new_compute_locks(
@ -1695,7 +1621,6 @@ fn new_compute_locks(
let branch_path_diffs = virtual_branches
.iter()
.filter(|branch| branch.applied)
.filter_map(|branch| {
let commit = repository.find_commit(branch.head).ok()?;
let tree = commit.tree().ok()?;
@ -1886,10 +1811,6 @@ fn get_applied_status(
};
for branch in &mut virtual_branches {
if !branch.applied {
bail!("branch {} is not applied", branch.name);
}
let old_claims = branch.ownership.claims.clone();
let new_claims = old_claims
.iter()
@ -2916,15 +2837,6 @@ pub fn amend(
bail!("could not find any branch with id {branch_id} to amend to");
}
let applied_branches = all_branches
.into_iter()
.filter(|b| b.applied)
.collect::<Vec<_>>();
if !applied_branches.iter().any(|b| b.id == branch_id) {
bail!("could not find applied branch with id {branch_id} to amend to");
}
let default_target = vb_state.get_default_target()?;
let integration_commit_id =
@ -2934,7 +2846,7 @@ pub fn amend(
project_repository,
&integration_commit_id,
&default_target.sha,
applied_branches,
all_branches,
)?;
let (ref mut target_branch, target_status) = applied_statuses
@ -3356,11 +3268,6 @@ pub fn cherry_pick(
.get_branch(branch_id)
.context("failed to read branch")?;
if !branch.applied {
// todo?
bail!("can not cherry pick a branch that is not applied")
}
let target_commit = project_repository
.repo()
.find_commit(target_commit_id)
@ -3383,7 +3290,6 @@ pub fn cherry_pick(
.list_branches()
.context("failed to read virtual branches")?
.into_iter()
.filter(|b| b.applied)
.collect::<Vec<_>>();
let integration_commit_id = get_workspace_head(&vb_state, project_repository)?;
@ -3715,14 +3621,13 @@ pub fn move_commit(
project_repository.assure_resolved()?;
let vb_state = project_repository.project().virtual_branches();
let applied_branches = vb_state
let branches = vb_state
.list_branches()
.context("failed to read virtual branches")?
.into_iter()
.filter(|b| b.applied)
.collect::<Vec<_>>();
if !applied_branches.iter().any(|b| b.id == target_branch_id) {
if !branches.iter().any(|b| b.id == target_branch_id) {
bail!("branch {target_branch_id} is not among applied branches")
}
@ -3735,7 +3640,7 @@ pub fn move_commit(
project_repository,
&integration_commit_id,
&default_target.sha,
applied_branches,
branches,
)?;
let (ref mut source_branch, source_status) = applied_statuses
@ -3947,7 +3852,7 @@ pub fn create_virtual_branch_from_branch(
id: BranchId::generate(),
name: branch_name.clone(),
notes: String::new(),
applied: false,
old_applied: true,
upstream_head: upstream_branch.is_some().then_some(head_commit.id()),
upstream: upstream_branch,
tree: head_commit_tree.id(),

View File

@ -30,7 +30,7 @@ fn reconcile_ownership_simple() {
],
}],
},
applied: true,
old_applied: true,
tree: git2::Oid::zero(),
head: git2::Oid::zero(),
id: BranchId::default(),
@ -56,7 +56,7 @@ fn reconcile_ownership_simple() {
}],
}],
},
applied: true,
old_applied: true,
tree: git2::Oid::zero(),
head: git2::Oid::zero(),
id: BranchId::default(),

View File

@ -15,7 +15,7 @@ fn new_test_branch() -> virtual_branches::branch::Branch {
id: virtual_branches::BranchId::generate(),
name: format!("branch_name_{}", TEST_INDEX.load(Ordering::Relaxed)),
notes: String::new(),
applied: true,
old_applied: true,
upstream: Some(
format!(
"refs/remotes/origin/upstream_{}",

View File

@ -310,7 +310,6 @@ fn create_branch_no_arguments() -> Result<()> {
let branches = vb_state.list_branches().expect("failed to read branches");
assert_eq!(branches.len(), 1);
assert_eq!(branches[0].name, "Virtual branch");
assert!(branches[0].applied);
assert_eq!(branches[0].ownership, BranchOwnershipClaims::default());
assert_eq!(branches[0].order, 0);