Skip to content

Commit

Permalink
Fix broken test
Browse files Browse the repository at this point in the history
  • Loading branch information
mtsgrd committed Jul 17, 2024
1 parent 2c4a2aa commit 1c3246b
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ impl BranchManager<'_> {
let (applied_statuses, _) = get_applied_status(
self.project_repository,
&integration_commit.id(),
&target_commit.id(),
virtual_branches,
None,
)
Expand Down
117 changes: 116 additions & 1 deletion crates/gitbutler-branch-actions/src/virtual.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use git2::ErrorCode;
use gitbutler_branch::diff::{self, diff_files_into_hunks, trees, FileDiff, GitHunk};
use gitbutler_branch::{dedup, BranchUpdateRequest, VirtualBranchesHandle};
use gitbutler_branch::{dedup_fmt, Branch, BranchCreateRequest, BranchId};
Expand All @@ -12,6 +13,7 @@ use gitbutler_repo::credentials::Helper;
use gitbutler_repo::{LogUntil, RepoActionsExt, RepositoryExt};
use itertools::Itertools;
use std::borrow::Borrow;
use std::default;
#[cfg(target_family = "unix")]
use std::os::unix::prelude::PermissionsExt;
use std::time::SystemTime;
Expand All @@ -20,6 +22,7 @@ use std::{
path::{Path, PathBuf},
time, vec,
};
use tokio::time::Instant;

use anyhow::{anyhow, bail, Context, Result};
use bstr::{BString, ByteSlice, ByteVec};
Expand Down Expand Up @@ -218,6 +221,7 @@ pub fn unapply_ownership(
project_repository.assure_resolved()?;

let vb_state = project_repository.project().virtual_branches();
let default_target = &vb_state.get_default_target()?;

let virtual_branches = vb_state
.list_branches_in_workspace()
Expand All @@ -228,6 +232,7 @@ pub fn unapply_ownership(
let (applied_statuses, _) = get_applied_status(
project_repository,
&integration_commit_id,
&default_target.sha,
virtual_branches,
None,
)
Expand Down Expand Up @@ -1068,13 +1073,110 @@ pub fn get_status_by_branch(
project_repository,
// TODO: Keep this optional or update lots of tests?
integration_commit.unwrap_or(&default_target.sha),
&default_target.sha,
virtual_branches,
perm,
)?;

Ok((applied_status, skipped_files))
}

fn compute_merge_base(
project_repository: &ProjectRepository,
target_sha: &git2::Oid,
virtual_branches: &Vec<Branch>,
) -> Result<git2::Oid> {
let repo = project_repository.repo();
let mut merge_base = *target_sha;
for branch in virtual_branches {
if let Some(last) = project_repository
.l(branch.head, LogUntil::Commit(*target_sha))?
.last()
.map(|id| repo.find_commit(id.to_owned()))
{
if let Ok(parent) = last?.parent(0) {
merge_base = repo.merge_base(parent.id(), merge_base)?;
}
}
}
Ok(merge_base)
}

fn compute_locks(
project_repository: &ProjectRepository,
integration_commit: &git2::Oid,
target_sha: &git2::Oid,
base_diffs: &BranchStatus,
virtual_branches: &Vec<Branch>,
) -> Result<HashMap<HunkHash, Vec<diff::HunkLock>>> {
let merge_base = compute_merge_base(project_repository, target_sha, virtual_branches)?;
let mut locked_hunk_map = HashMap::<HunkHash, Vec<diff::HunkLock>>::new();

let mut commit_to_branch = HashMap::new();
for branch in virtual_branches {
for commit in project_repository.log(branch.head, LogUntil::Commit(*target_sha))? {
commit_to_branch.insert(commit.id(), branch.id);
}
}

for (path, hunks) in base_diffs.clone().into_iter() {
for hunk in hunks {
println!(
"{:?} {:?} {:?} {:?} {:?}",
&path, hunk.old_start, hunk.old_lines, merge_base, integration_commit
);
let blame = match project_repository.repo().blame(
&path,
hunk.old_start,
(hunk.old_start + hunk.old_lines).saturating_sub(0),
merge_base,
*integration_commit,
) {
Ok(blame) => blame,
Err(error) => {
if error.code() == ErrorCode::NotFound {
continue;
} else {
return Err(error.into());
}
}
};

for blame_hunk in blame.iter() {
let commit_id = blame_hunk.orig_commit_id();
dbg!(commit_id);
println!(
"start: {} lines: {}",
blame_hunk.final_start_line(),
blame_hunk.lines_in_hunk()
);
if commit_id == *integration_commit || commit_id == *target_sha {
continue;
}
let hash = Hunk::hash_diff(&hunk.diff_lines);
dbg!(hash);
let Some(branch_id) = commit_to_branch.get(&commit_id) else {
continue;
};
dbg!(branch_id);

let hunk_lock = diff::HunkLock {
branch_id: *branch_id,
commit_id,
};
dbg!(&hunk_lock);
locked_hunk_map
.entry(hash)
.and_modify(|locks| {
locks.push(hunk_lock);
})
.or_insert(vec![hunk_lock]);
}
}
}
Ok(locked_hunk_map)
}

fn new_compute_locks(
repository: &git2::Repository,
unstaged_hunks_by_path: &HashMap<PathBuf, Vec<diff::GitHunk>>,
Expand Down Expand Up @@ -1166,6 +1268,7 @@ fn new_compute_locks(
pub(crate) fn get_applied_status(
project_repository: &ProjectRepository,
integration_commit: &git2::Oid,
target_sha: &git2::Oid,
mut virtual_branches: Vec<Branch>,
perm: Option<&mut WorktreeWritePermission>,
) -> Result<(AppliedStatuses, Vec<diff::FileDiff>)> {
Expand Down Expand Up @@ -1200,7 +1303,14 @@ pub(crate) fn get_applied_status(
.map(|branch| (branch.id, HashMap::new()))
.collect();

let locks = new_compute_locks(project_repository.repo(), &base_diffs, &virtual_branches)?;
let locks = compute_locks(
project_repository,
integration_commit,
target_sha,
&base_diffs,
&virtual_branches,
)?;
// let locks = new_compute_locks(project_repository.repo(), &base_diffs, &virtual_branches)?;

for branch in &mut virtual_branches {
let old_claims = branch.ownership.claims.clone();
Expand Down Expand Up @@ -2179,6 +2289,7 @@ pub(crate) fn amend(
let (mut applied_statuses, _) = get_applied_status(
project_repository,
&integration_commit_id,
&default_target.sha,
virtual_branches,
None,
)?;
Expand Down Expand Up @@ -2661,11 +2772,13 @@ pub(crate) fn move_commit(
bail!("branch {target_branch_id} is not among applied branches")
}

let default_target = &vb_state.get_default_target()?;
let integration_commit_id = get_workspace_head(&vb_state, project_repository)?;

let (mut applied_statuses, _) = get_applied_status(
project_repository,
&integration_commit_id,
&default_target.sha,
applied_branches,
None,
)?;
Expand Down Expand Up @@ -2873,6 +2986,8 @@ fn update_conflict_markers(

#[cfg(test)]
mod tests {
use git2::ErrorCode;

use super::*;
#[test]
fn joined_test() {
Expand Down
3 changes: 1 addition & 2 deletions crates/gitbutler-repo/src/repository_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,8 +224,7 @@ impl RepositoryExt for Repository {
opts.min_line(min_line as usize)
.max_line(max_line as usize)
.newest_commit(newest_commit)
.oldest_commit(oldest_commit)
.first_parent(true);
.oldest_commit(oldest_commit);
self.blame_file(path, Some(&mut opts))
}

Expand Down

0 comments on commit 1c3246b

Please # to comment.