Skip to content

Commit 8c92102

Browse files
authored
Merge pull request #9766 from gitbutlerapp/kv-branch-50
Remove the move_commit_file API
2 parents 3fedd0a + 7a64e04 commit 8c92102

File tree

10 files changed

+6
-486
lines changed

10 files changed

+6
-486
lines changed

apps/desktop/src/lib/stacks/stackService.svelte.ts

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -714,10 +714,6 @@ export class StackService {
714714
return this.api.endpoints.amendCommit.mutate;
715715
}
716716

717-
get moveCommitFileMutation() {
718-
return this.api.endpoints.moveCommitFile.mutate;
719-
}
720-
721717
/** Squash all the commits in a branch together */
722718
async squashAllCommits({
723719
projectId,
@@ -1448,27 +1444,6 @@ function injectEndpoints(api: ClientState['backendApi'], uiState: UiState) {
14481444
invalidatesItem(ReduxTag.StackDetails, args.stackId)
14491445
]
14501446
}),
1451-
moveCommitFile: build.mutation<
1452-
void,
1453-
{
1454-
projectId: string;
1455-
stackId: string;
1456-
fromCommitOid: string;
1457-
toCommitOid: string;
1458-
ownership: string;
1459-
}
1460-
>({
1461-
extraOptions: {
1462-
command: 'move_commit_file',
1463-
actionName: 'Move Commit File'
1464-
},
1465-
query: (args) => args,
1466-
invalidatesTags: (_result, _error, args) => [
1467-
invalidatesList(ReduxTag.WorktreeChanges), // Could cause conflicts
1468-
invalidatesItem(ReduxTag.StackDetails, args.stackId),
1469-
invalidatesList(ReduxTag.BranchListing)
1470-
]
1471-
}),
14721447
newBranchName: build.query<
14731448
string,
14741449
{

crates/but-api/src/commands/virtual_branches.rs

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -317,22 +317,6 @@ pub struct MoveCommitFileParams {
317317
pub ownership: BranchOwnershipClaims,
318318
}
319319

320-
pub fn move_commit_file(app: &App, params: MoveCommitFileParams) -> Result<String, Error> {
321-
let project = gitbutler_project::get(params.project_id)?;
322-
let ctx = CommandContext::open(&project, app.app_settings.get()?.clone())?;
323-
let from_commit_id = git2::Oid::from_str(&params.from_commit_id).map_err(|e| anyhow!(e))?;
324-
let to_commit_id = git2::Oid::from_str(&params.to_commit_id).map_err(|e| anyhow!(e))?;
325-
let claim = params.ownership.into();
326-
let oid = gitbutler_branch_actions::move_commit_file(
327-
&ctx,
328-
params.stack_id,
329-
from_commit_id,
330-
to_commit_id,
331-
&claim,
332-
)?;
333-
Ok(oid.to_string())
334-
}
335-
336320
#[derive(Deserialize)]
337321
#[serde(rename_all = "camelCase")]
338322
pub struct UndoCommitParams {

crates/but-server/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,6 @@ async fn handle_command(
272272
"amend_virtual_branch" => {
273273
run_cmd(&app, request.params, virtual_branches::amend_virtual_branch)
274274
}
275-
"move_commit_file" => run_cmd(&app, request.params, virtual_branches::move_commit_file),
276275
"undo_commit" => run_cmd(&app, request.params, virtual_branches::undo_commit),
277276
"insert_blank_commit" => {
278277
run_cmd(&app, request.params, virtual_branches::insert_blank_commit)

crates/gitbutler-branch-actions/src/actions.rs

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -284,23 +284,6 @@ fn amend_with_commit_engine(
284284
Ok(new_commit.to_git2())
285285
}
286286

287-
pub fn move_commit_file(
288-
ctx: &CommandContext,
289-
stack_id: StackId,
290-
from_commit_oid: git2::Oid,
291-
to_commit_oid: git2::Oid,
292-
ownership: &BranchOwnershipClaims,
293-
) -> Result<git2::Oid> {
294-
let mut guard = ctx.project().exclusive_worktree_access();
295-
ctx.verify(guard.write_permission())?;
296-
ensure_open_workspace_mode(ctx).context("Amending a commit requires open workspace mode")?;
297-
let _ = ctx.create_snapshot(
298-
SnapshotDetails::new(OperationKind::MoveCommitFile),
299-
guard.write_permission(),
300-
);
301-
vbranch::move_commit_file(ctx, stack_id, from_commit_oid, to_commit_oid, ownership)
302-
}
303-
304287
pub fn undo_commit(ctx: &CommandContext, stack_id: StackId, commit_oid: git2::Oid) -> Result<()> {
305288
let mut guard = ctx.project().exclusive_worktree_access();
306289
ctx.verify(guard.write_permission())?;

crates/gitbutler-branch-actions/src/lib.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ pub use actions::{
66
amend, can_apply_remote_branch, create_commit, create_virtual_branch,
77
create_virtual_branch_from_branch, delete_local_branch, fetch_from_remotes, find_commit,
88
find_git_branches, get_uncommited_files, insert_blank_commit, integrate_upstream,
9-
integrate_upstream_commits, list_commit_files, move_commit, move_commit_file, push_base_branch,
10-
reorder_stack, resolve_upstream_integration, set_base_branch, set_target_push_remote,
11-
squash_commits, unapply_stack, undo_commit, update_commit_message, update_stack_order,
12-
update_virtual_branch, upstream_integration_statuses,
9+
integrate_upstream_commits, list_commit_files, move_commit, push_base_branch, reorder_stack,
10+
resolve_upstream_integration, set_base_branch, set_target_push_remote, squash_commits,
11+
unapply_stack, undo_commit, update_commit_message, update_stack_order, update_virtual_branch,
12+
upstream_integration_statuses,
1313
};
1414
mod squash;
1515

crates/gitbutler-branch-actions/src/virtual.rs

Lines changed: 2 additions & 200 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
use crate::{hunk::VirtualBranchHunk, status::get_applied_status_cached, VirtualBranchesExt};
22
use anyhow::{anyhow, bail, Context, Result};
3-
use bstr::{BString, ByteSlice};
3+
use bstr::BString;
44
use but_rebase::RebaseStep;
55
use but_workspace::stack_ext::StackExt;
66
use gitbutler_branch::dedup;
77
use gitbutler_branch::BranchUpdateRequest;
88
use gitbutler_cherry_pick::RepositoryExt as _;
99
use gitbutler_command_context::CommandContext;
10-
use gitbutler_commit::{commit_ext::CommitExt, commit_headers::HasCommitHeaders};
10+
use gitbutler_commit::commit_ext::CommitExt;
1111
use gitbutler_diff::GitHunk;
1212
use gitbutler_oxidize::{
1313
git2_signature_to_gix_signature, git2_to_gix_object_id, gix_to_git2_oid, GixRepositoryExt,
@@ -486,204 +486,6 @@ pub fn is_remote_branch_mergeable(
486486
Ok(mergeable)
487487
}
488488

489-
// this function takes a list of file ownership from a "from" commit and "moves"
490-
// those changes to a "to" commit in a branch. This allows users to drag changes
491-
// from one commit to another.
492-
// if the "to" commit is below the "from" commit, the changes are simply added to the "to" commit
493-
// and the rebase should be simple. if the "to" commit is above the "from" commit,
494-
// the changes need to be removed from the "from" commit, everything rebased,
495-
// then added to the "to" commit and everything above that rebased again.
496-
//
497-
// NB: It appears that this function is semi-broken when the "to" commit is above the "from" commit.
498-
// Ths changes are indeed removed from the "from" commit, but they end up in the workspace and not the "to" commit.
499-
// This was broken before the migration to the rebase engine.
500-
// The way the trees of "diffs to keep" and "diffs to amend" are computed with gitbutler_diff::write::hunks_onto_commit is incredibly sketchy
501-
pub(crate) fn move_commit_file(
502-
ctx: &CommandContext,
503-
stack_id: StackId,
504-
from_commit_id: git2::Oid,
505-
to_commit_id: git2::Oid,
506-
target_ownership: &BranchOwnershipClaims,
507-
) -> Result<git2::Oid> {
508-
let vb_state = ctx.project().virtual_branches();
509-
510-
let default_target = vb_state.get_default_target()?;
511-
512-
let mut stack = vb_state.get_stack_in_workspace(stack_id)?;
513-
let gix_repo = ctx.gix_repo()?;
514-
let merge_base = stack.merge_base(ctx)?;
515-
516-
// first, let's get the from commit data and it's parent data
517-
let from_commit = ctx
518-
.repo()
519-
.find_commit(from_commit_id)
520-
.context("failed to find commit")?;
521-
let from_tree = from_commit.tree().context("failed to find tree")?;
522-
let from_parent = from_commit.parent(0).context("failed to find parent")?;
523-
let from_parent_tree = from_parent.tree().context("failed to find parent tree")?;
524-
525-
// ok, what is the entire patch introduced in the "from" commit?
526-
// we need to remove the parts of this patch that are in target_ownership (the parts we're moving)
527-
// and then apply the rest to the parent tree of the "from" commit to
528-
// create the new "from" commit without the changes we're moving
529-
let from_commit_diffs = gitbutler_diff::trees(ctx.repo(), &from_parent_tree, &from_tree, true)
530-
.context("failed to diff trees")?;
531-
532-
// filter from_commit_diffs to HashMap<filepath, Vec<GitHunk>> only for hunks NOT in target_ownership
533-
// this is the patch parts we're keeping
534-
let diffs_to_keep = from_commit_diffs
535-
.iter()
536-
.filter_map(|(filepath, file_diff)| {
537-
let hunks = file_diff
538-
.hunks
539-
.iter()
540-
.filter(|hunk| {
541-
!target_ownership.claims.iter().any(|file_ownership| {
542-
file_ownership.file_path.eq(filepath)
543-
&& file_ownership.hunks.iter().any(|owned_hunk| {
544-
owned_hunk.start == hunk.new_start
545-
&& owned_hunk.end == hunk.new_start + hunk.new_lines
546-
})
547-
})
548-
})
549-
.cloned()
550-
.collect::<Vec<_>>();
551-
if hunks.is_empty() {
552-
None
553-
} else {
554-
Some((filepath.clone(), hunks))
555-
}
556-
})
557-
.collect::<HashMap<_, _>>();
558-
559-
// write our new tree and commit for the new "from" commit without the moved changes
560-
let new_from_tree_id =
561-
gitbutler_diff::write::hunks_onto_commit(ctx, from_parent.id(), &diffs_to_keep)?;
562-
let new_from_tree = &ctx
563-
.repo()
564-
.find_tree(new_from_tree_id)
565-
.with_context(|| "tree {new_from_tree_oid} not found")?;
566-
let new_from_commit_oid = ctx
567-
.repo()
568-
.commit_with_signature(
569-
None,
570-
&from_commit.author(),
571-
&from_commit.committer(),
572-
&from_commit.message_bstr().to_str_lossy(),
573-
new_from_tree,
574-
&[&from_parent],
575-
from_commit.gitbutler_headers(),
576-
)
577-
.context("commit failed")?;
578-
579-
// rebase swapping the from_commit_oid with the new_from_commit_oid
580-
let mut steps = stack.as_rebase_steps(ctx, &gix_repo)?;
581-
// replace the "from" commit in the rebase steps with the new "from" commit which has the moved changes removed
582-
for step in steps.iter_mut() {
583-
if let RebaseStep::Pick { commit_id, .. } = step {
584-
if *commit_id == from_commit_id.to_gix() {
585-
*commit_id = new_from_commit_oid.to_gix();
586-
}
587-
}
588-
}
589-
let mut rebase = but_rebase::Rebase::new(&gix_repo, merge_base, None)?;
590-
rebase.steps(steps)?;
591-
rebase.rebase_noops(false);
592-
let outcome = rebase.rebase()?;
593-
// ensure that the stack here has been updated.
594-
stack.set_heads_from_rebase_output(ctx, outcome.references)?;
595-
596-
// Discover the new id of the commit to amend `to_commit_id` from the output of the first rebas
597-
let to_commit_id = outcome
598-
.commit_mapping
599-
.iter()
600-
.find(|(_base, old, _new)| old == &to_commit_id.to_gix())
601-
.map(|(_base, _old, new)| new.to_git2())
602-
.ok_or_else(|| anyhow!("failed to find the to_ammend_commit after the initial rebase"))?;
603-
604-
let to_commit = ctx
605-
.repo()
606-
.find_commit(to_commit_id)
607-
.context("failed to find commit")?;
608-
let to_commit_parents: Vec<_> = to_commit.parents().collect();
609-
610-
// get a list of all the diffs across all the virtual branches
611-
let base_file_diffs = gitbutler_diff::workdir(ctx.repo(), default_target.sha)
612-
.context("failed to diff workdir")?;
613-
614-
// filter base_file_diffs to HashMap<filepath, Vec<GitHunk>> only for hunks in target_ownership
615-
// this is essentially the group of patches that we're "moving"
616-
let diffs_to_amend = target_ownership
617-
.claims
618-
.iter()
619-
.filter_map(|file_ownership| {
620-
let hunks = base_file_diffs
621-
.get(&file_ownership.file_path)
622-
.map(|hunks| {
623-
hunks
624-
.hunks
625-
.iter()
626-
.filter(|hunk| {
627-
file_ownership.hunks.iter().any(|owned_hunk| {
628-
owned_hunk.start == hunk.new_start
629-
&& owned_hunk.end == hunk.new_start + hunk.new_lines
630-
})
631-
})
632-
.cloned()
633-
.collect::<Vec<_>>()
634-
})
635-
.unwrap_or_default();
636-
if hunks.is_empty() {
637-
None
638-
} else {
639-
Some((file_ownership.file_path.clone(), hunks))
640-
}
641-
})
642-
.collect::<HashMap<_, _>>();
643-
// apply diffs_to_amend to the commit tree
644-
// and write a new commit with the changes we're moving
645-
// let new_tree_oid =
646-
// gitbutler_diff::write::hunks_onto_commit(ctx, to_commit_id, &diffs_to_amend)?;
647-
let new_tree_oid =
648-
gitbutler_diff::write::hunks_onto_tree(ctx, &to_commit.tree()?, &diffs_to_amend, true)?;
649-
650-
let new_tree = ctx
651-
.repo()
652-
.find_tree(new_tree_oid)
653-
.context("failed to find new tree")?;
654-
let new_to_commit_oid = ctx
655-
.repo()
656-
.commit_with_signature(
657-
None,
658-
&to_commit.author(),
659-
&to_commit.committer(),
660-
&to_commit.message_bstr().to_str_lossy(),
661-
&new_tree,
662-
&to_commit_parents.iter().collect::<Vec<_>>(),
663-
to_commit.gitbutler_headers(),
664-
)
665-
.context("failed to create commit")?;
666-
667-
// another rebase
668-
let mut steps = stack.as_rebase_steps(ctx, &gix_repo)?;
669-
// replace the "to" commit in the rebase steps with the new "to" commit which has the moved changes added
670-
for step in steps.iter_mut() {
671-
if let RebaseStep::Pick { commit_id, .. } = step {
672-
if *commit_id == to_commit_id.to_gix() {
673-
*commit_id = new_to_commit_oid.to_gix();
674-
}
675-
}
676-
}
677-
let mut rebase = but_rebase::Rebase::new(&gix_repo, merge_base, None)?;
678-
rebase.steps(steps)?;
679-
rebase.rebase_noops(false);
680-
let outcome = rebase.rebase()?;
681-
stack.set_heads_from_rebase_output(ctx, outcome.references)?;
682-
stack.set_stack_head(&vb_state, &gix_repo, outcome.top_commit.to_git2(), None)?;
683-
// todo: maybe update the workspace commit here?
684-
Ok(new_to_commit_oid)
685-
}
686-
687489
// create and insert a blank commit (no tree change) either above or below a commit
688490
// if offset is positive, insert below, if negative, insert above
689491
// return map of the updated commit ids

crates/gitbutler-branch-actions/tests/virtual_branches/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ mod init;
6262
mod insert_blank_commit;
6363
mod list;
6464
mod list_details;
65-
mod move_commit_file;
6665
mod move_commit_to_vbranch;
6766
mod oplog;
6867
mod save_and_unapply_virtual_branch;

0 commit comments

Comments
 (0)