mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2024-12-20 16:11:46 +03:00
chore: DRYer approach
This commit is contained in:
parent
fd7c18d121
commit
bd7bf3b8a9
@ -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,
|
||||
|
@ -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(
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
let ownership_hunks: Vec<&Hunk> = ownership
|
||||
.files
|
||||
.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)) {
|
||||
.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));
|
||||
}
|
||||
}
|
||||
|
@ -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');
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user