Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
814 changes: 0 additions & 814 deletions crates/but-api/src/commit.rs

This file was deleted.

94 changes: 94 additions & 0 deletions crates/but-api/src/commit/amend.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
use std::collections::BTreeMap;

use but_api_macros::but_api;
use but_core::{DiffSpec, sync::RepoExclusive};
use but_oplog::legacy::{OperationKind, SnapshotDetails};
use but_rebase::graph_rebase::{GraphExt, LookupStep as _};
use tracing::instrument;

use super::types::CommitCreateResult;

/// Amends an existing commit with selected changes.
#[but_api(crate::commit::json::UICommitCreateResult)]
#[instrument(err(Debug))]
pub fn commit_amend_only(
ctx: &mut but_ctx::Context,
commit_id: gix::ObjectId,
changes: Vec<DiffSpec>,
) -> anyhow::Result<CommitCreateResult> {
let context_lines = ctx.settings.context_lines;
let mut guard = ctx.exclusive_worktree_access();
commit_amend_only_impl(
ctx,
commit_id,
changes,
context_lines,
guard.write_permission(),
)
}

/// Amends an existing commit with selected changes.
pub(crate) fn commit_amend_only_impl(
ctx: &mut but_ctx::Context,
commit_id: gix::ObjectId,
changes: Vec<DiffSpec>,
context_lines: u32,
perm: &mut RepoExclusive,
) -> anyhow::Result<CommitCreateResult> {
let meta = ctx.meta()?;
let (repo, mut ws, _) = ctx.workspace_mut_and_db_with_perm(perm)?;
let editor = ws.graph.to_editor(&repo)?;

let but_workspace::commit::CommitAmendOutcome {
rebase,
commit_selector,
rejected_specs,
} = but_workspace::commit::commit_amend(editor, commit_id, changes, context_lines)?;

let (new_commit, replaced_commits) = match commit_selector {
Some(commit_selector) => {
let materialized = rebase.materialize()?;
let new_commit = materialized.lookup_pick(commit_selector)?;
let replaced_commits = materialized.history.commit_mappings();
(Some(new_commit), replaced_commits)
}
None => (None, BTreeMap::new()),
};

ws.refresh_from_head(&repo, &meta)?;

Ok(CommitCreateResult {
new_commit,
rejected_specs,
replaced_commits,
})
}

/// Amends an existing commit with selected changes, with oplog support.
#[but_api(napi, crate::commit::json::UICommitCreateResult)]
#[instrument(err(Debug))]
pub fn commit_amend(
ctx: &mut but_ctx::Context,
commit_id: gix::ObjectId,
changes: Vec<DiffSpec>,
) -> anyhow::Result<CommitCreateResult> {
let context_lines = ctx.settings.context_lines;
let maybe_oplog_entry = but_oplog::UnmaterializedOplogSnapshot::from_details(
ctx,
SnapshotDetails::new(OperationKind::AmendCommit),
)
.ok();

let mut guard = ctx.exclusive_worktree_access();
let res = commit_amend_only_impl(
ctx,
commit_id,
changes,
context_lines,
guard.write_permission(),
);
if let Some(snapshot) = maybe_oplog_entry.filter(|_| res.is_ok()) {
snapshot.commit(ctx, guard.write_permission()).ok();
};
res
}
115 changes: 115 additions & 0 deletions crates/but-api/src/commit/create.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
use std::collections::BTreeMap;

use but_api_macros::but_api;
use but_core::{DiffSpec, sync::RepoExclusive};
use but_oplog::legacy::{OperationKind, SnapshotDetails};
use but_rebase::graph_rebase::{
GraphExt, LookupStep as _,
mutate::{InsertSide, RelativeTo},
};
use tracing::instrument;

use super::types::CommitCreateResult;

/// Creates and inserts a commit relative to either a commit or a reference.
#[but_api(crate::commit::json::UICommitCreateResult)]
#[instrument(err(Debug))]
pub fn commit_create_only(
ctx: &mut but_ctx::Context,
relative_to: crate::commit::json::RelativeTo,
side: InsertSide,
changes: Vec<DiffSpec>,
message: String,
) -> anyhow::Result<CommitCreateResult> {
let context_lines = ctx.settings.context_lines;
let mut guard = ctx.exclusive_worktree_access();
commit_create_only_impl(
ctx,
relative_to,
side,
changes,
message,
context_lines,
guard.write_permission(),
)
}

/// Creates and inserts a commit relative to either a commit or a reference.
pub(crate) fn commit_create_only_impl(
ctx: &mut but_ctx::Context,
relative_to: crate::commit::json::RelativeTo,
side: InsertSide,
changes: Vec<DiffSpec>,
message: String,
context_lines: u32,
perm: &mut RepoExclusive,
) -> anyhow::Result<CommitCreateResult> {
let meta = ctx.meta()?;
let (repo, mut ws, _) = ctx.workspace_mut_and_db_with_perm(perm)?;
let editor = ws.graph.to_editor(&repo)?;
let relative_to: RelativeTo = (&relative_to).into();

let but_workspace::commit::CommitCreateOutcome {
rebase,
commit_selector,
rejected_specs,
} = but_workspace::commit::commit_create(
editor,
changes,
relative_to,
side,
&message,
context_lines,
)?;

let (new_commit, replaced_commits) = match commit_selector {
Some(commit_selector) => {
let materialized = rebase.materialize()?;
let new_commit = materialized.lookup_pick(commit_selector)?;
let replaced_commits = materialized.history.commit_mappings();
(Some(new_commit), replaced_commits)
}
None => (None, BTreeMap::new()),
};

ws.refresh_from_head(&repo, &meta)?;

Ok(CommitCreateResult {
new_commit,
rejected_specs,
replaced_commits,
})
}

/// Creates and inserts a commit relative to either a commit or a reference, with oplog support.
#[but_api(napi, crate::commit::json::UICommitCreateResult)]
#[instrument(err(Debug))]
pub fn commit_create(
ctx: &mut but_ctx::Context,
relative_to: crate::commit::json::RelativeTo,
side: InsertSide,
changes: Vec<DiffSpec>,
message: String,
) -> anyhow::Result<CommitCreateResult> {
let context_lines = ctx.settings.context_lines;
let maybe_oplog_entry = but_oplog::UnmaterializedOplogSnapshot::from_details(
ctx,
SnapshotDetails::new(OperationKind::CreateCommit),
)
.ok();

let mut guard = ctx.exclusive_worktree_access();
let res = commit_create_only_impl(
ctx,
relative_to,
side,
changes,
message,
context_lines,
guard.write_permission(),
);
if let Some(snapshot) = maybe_oplog_entry.filter(|_| res.is_ok()) {
snapshot.commit(ctx, guard.write_permission()).ok();
};
res
}
77 changes: 77 additions & 0 deletions crates/but-api/src/commit/insert_blank.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
use but_api_macros::but_api;
use but_core::sync::RepoExclusive;
use but_oplog::legacy::{OperationKind, SnapshotDetails};
use but_rebase::graph_rebase::{
GraphExt, LookupStep as _,
mutate::{InsertSide, RelativeTo},
};
use tracing::instrument;

use super::types::CommitInsertBlankResult;

/// Inserts a blank commit relative to either a commit or a reference
///
/// Returns the result including the new commit ID and any replaced commits.
#[but_api(crate::commit::json::UICommitInsertBlankResult)]
#[instrument(err(Debug))]
pub fn commit_insert_blank_only(
ctx: &mut but_ctx::Context,
relative_to: crate::commit::json::RelativeTo,
side: InsertSide,
) -> anyhow::Result<CommitInsertBlankResult> {
let mut guard = ctx.exclusive_worktree_access();
commit_insert_blank_only_impl(ctx, relative_to, side, guard.write_permission())
}

/// Implementation of inserting a blank commit relative to either a commit or a reference
///
/// Returns the result including the new commit ID and any replaced commits.
pub(crate) fn commit_insert_blank_only_impl(
ctx: &mut but_ctx::Context,
relative_to: crate::commit::json::RelativeTo,
side: InsertSide,
perm: &mut RepoExclusive,
) -> anyhow::Result<CommitInsertBlankResult> {
let meta = ctx.meta()?;
let (repo, mut ws, _) = ctx.workspace_mut_and_db_with_perm(perm)?;
let editor = ws.graph.to_editor(&repo)?;
let relative_to: RelativeTo = (&relative_to).into();

let (outcome, blank_commit_selector) =
but_workspace::commit::insert_blank_commit(editor, side, relative_to)?;

let outcome = outcome.materialize()?;
let id = outcome.lookup_pick(blank_commit_selector)?;
let replaced_commits = outcome.history.commit_mappings();

ws.refresh_from_head(&repo, &meta)?;

Ok(CommitInsertBlankResult {
new_commit: id,
replaced_commits,
})
}

/// Inserts a blank commit relative to either a commit or a reference, with oplog support
///
/// Returns the result including the new commit ID and any replaced commits.
#[but_api(napi, crate::commit::json::UICommitInsertBlankResult)]
#[instrument(err(Debug))]
pub fn commit_insert_blank(
ctx: &mut but_ctx::Context,
relative_to: crate::commit::json::RelativeTo,
side: InsertSide,
) -> anyhow::Result<CommitInsertBlankResult> {
let maybe_oplog_entry = but_oplog::UnmaterializedOplogSnapshot::from_details(
ctx,
SnapshotDetails::new(OperationKind::InsertBlankCommit),
)
.ok();

let mut guard = ctx.exclusive_worktree_access();
let res = commit_insert_blank_only_impl(ctx, relative_to, side, guard.write_permission());
if let Some(snapshot) = maybe_oplog_entry.filter(|_| res.is_ok()) {
snapshot.commit(ctx, guard.write_permission()).ok();
};
res
}
Loading
Loading