chore: DRYer approach

This commit is contained in:
Meesayen 2024-02-16 14:19:47 +01:00 committed by Federico Giovagnoli
parent fd7c18d121
commit bd7bf3b8a9
5 changed files with 12 additions and 181 deletions

View File

@ -205,7 +205,6 @@ fn main() {
virtual_branches::commands::apply_branch,
virtual_branches::commands::unapply_branch,
virtual_branches::commands::unapply_ownership,
virtual_branches::commands::unapply_file_changes,
virtual_branches::commands::push_virtual_branch,
virtual_branches::commands::create_virtual_branch_from_branch,
virtual_branches::commands::can_apply_virtual_branch,

View File

@ -326,25 +326,6 @@ pub async fn unapply_ownership(
Ok(())
}
#[tauri::command(async)]
#[instrument(skip(handle))]
pub async fn unapply_file_changes(
handle: AppHandle,
project_id: &str,
file_path: &str,
) -> Result<(), Error> {
let project_id = project_id.parse().map_err(|_| Error::UserError {
code: Code::Validation,
message: "Malformed project id".to_string(),
})?;
handle
.state::<Controller>()
.unapply_file_changes(&project_id, &file_path)
.await?;
emit_vbranches(&handle, &project_id).await;
Ok(())
}
#[tauri::command(async)]
#[instrument(skip(handle))]
pub async fn push_virtual_branch(

View File

@ -247,17 +247,6 @@ impl Controller {
.await
}
pub async fn unapply_file_changes(
&self,
project_id: &ProjectId,
file_path: &str,
) -> Result<(), ControllerError<errors::UnapplyOwnershipError>> {
self.inner(project_id)
.await
.unapply_file_changes(project_id, file_path)
.await
}
pub async fn amend(
&self,
project_id: &ProjectId,
@ -720,18 +709,6 @@ impl ControllerInner {
})
}
pub async fn unapply_file_changes(
&self,
project_id: &ProjectId,
file_path: &str,
) -> Result<(), ControllerError<errors::UnapplyOwnershipError>> {
let _permit = self.semaphore.acquire().await;
self.with_verify_branch(project_id, |gb_repository, project_repository, _| {
super::unapply_file_changes(gb_repository, project_repository, file_path)
.map_err(Into::into)
})
}
pub async fn amend(
&self,
project_id: &ProjectId,

View File

@ -1,8 +1,4 @@
use std::{
collections::HashMap,
path::{self, PathBuf},
time, vec,
};
use std::{collections::HashMap, path, time, vec};
#[cfg(target_family = "unix")]
use std::os::unix::prelude::*;
@ -498,136 +494,14 @@ pub fn unapply_ownership(
let mut hunks_to_unapply = Vec::new();
for (path, hunks) in branch_files {
if let Some(ownership) = ownership.files.iter().find(|o| o.file_path == path) {
for hunk in hunks {
if ownership.hunks.contains(&Hunk::from(&hunk)) {
hunks_to_unapply.push((path.clone(), hunk));
}
}
}
}
hunks_to_unapply.sort_by(|a, b| a.1.old_start.cmp(&b.1.old_start));
Ok(hunks_to_unapply)
},
)
.collect::<Result<Vec<_>>>()?
.into_iter()
.flatten()
.collect::<Vec<_>>();
let mut diff = HashMap::new();
for h in hunks_to_unapply {
if let Some(reversed_hunk) = diff::reverse_hunk(&h.1) {
diff.entry(h.0).or_insert_with(Vec::new).push(reversed_hunk);
} else {
return Err(errors::UnapplyOwnershipError::Other(anyhow::anyhow!(
"failed to reverse hunk"
)));
}
}
let repo = &project_repository.git_repository;
let target_commit = repo
.find_commit(default_target.sha)
.context("failed to find target commit")?;
let base_tree = target_commit.tree().context("failed to get target tree")?;
let final_tree = applied_statuses.into_iter().fold(
target_commit.tree().context("failed to get target tree"),
|final_tree, status| {
let final_tree = final_tree?;
let tree_oid = write_tree(project_repository, &default_target, &status.1)?;
let branch_tree = repo.find_tree(tree_oid)?;
let mut result = repo.merge_trees(&base_tree, &final_tree, &branch_tree)?;
let final_tree_oid = result.write_tree_to(repo)?;
repo.find_tree(final_tree_oid)
.context("failed to find tree")
},
)?;
let final_tree_oid = write_tree_onto_tree(project_repository, &final_tree, &diff)?;
let final_tree = repo
.find_tree(final_tree_oid)
.context("failed to find tree")?;
repo.checkout_tree(&final_tree)
.force()
.remove_untracked()
.checkout()
.context("failed to checkout tree")?;
super::integration::update_gitbutler_integration(gb_repository, project_repository)?;
Ok(())
}
pub fn unapply_file_changes(
gb_repository: &gb_repository::Repository,
project_repository: &project_repository::Repository,
file_path: &str,
) -> Result<(), errors::UnapplyOwnershipError> {
if conflicts::is_resolving(project_repository) {
return Err(errors::UnapplyOwnershipError::Conflict(
errors::ProjectConflictError {
project_id: project_repository.project().id,
},
));
}
let latest_session = gb_repository
.get_latest_session()
.context("failed to get or create current session")?
.ok_or_else(|| {
errors::UnapplyOwnershipError::DefaultTargetNotSet(errors::DefaultTargetNotSetError {
project_id: project_repository.project().id,
})
})?;
let latest_session_reader = sessions::Reader::open(gb_repository, &latest_session)
.context("failed to open current session")?;
let default_target = get_default_target(&latest_session_reader)
.context("failed to get default target")?
.ok_or_else(|| {
errors::UnapplyOwnershipError::DefaultTargetNotSet(errors::DefaultTargetNotSetError {
project_id: project_repository.project().id,
})
})?;
let applied_branches = Iterator::new(&latest_session_reader)
.context("failed to create branch iterator")?
.collect::<Result<Vec<branch::Branch>, reader::Error>>()
.context("failed to read virtual branches")?
.into_iter()
.filter(|b| b.applied)
.collect::<Vec<_>>();
let applied_statuses = get_applied_status(
gb_repository,
project_repository,
&default_target,
applied_branches,
)
.context("failed to get status by branch")?;
let hunks_to_unapply = applied_statuses
.iter()
.map(
|(branch, branch_files)| -> Result<Vec<(std::path::PathBuf, diff::Hunk)>> {
let branch_files = calculate_non_commited_diffs(
project_repository,
branch,
&default_target,
branch_files,
)?;
let mut hunks_to_unapply = Vec::new();
for (path, hunks) in branch_files {
if path.eq(&PathBuf::from(file_path)) {
for hunk in hunks {
let ownership_hunks: Vec<&Hunk> = ownership
.files
.iter()
.filter(|o| o.file_path == path)
.flat_map(|f| &f.hunks)
.collect();
for hunk in hunks {
if ownership_hunks.contains(&&Hunk::from(&hunk)) {
hunks_to_unapply.push((path.clone(), hunk));
}
}

View File

@ -152,12 +152,12 @@ export class BranchController {
async unapplyFile(file: LocalFile) {
try {
await invoke<void>('unapply_file_changes', {
await invoke<void>('unapply_ownership', {
projectId: this.projectId,
filePath: file.path
ownership: file.hunks.map((h) => `${file.path}:${h.id}`).join('\n')
});
} catch (err) {
toasts.error('Failed to unapply hunk');
toasts.error('Failed to unapply file changes');
}
}