Skip to main content

GitRepo

Trait GitRepo 

Source
pub trait GitRepo {
Show 28 methods // Required methods fn head_oid(&self) -> Result<String>; fn find_reference_point(&self, commit_ish: &str) -> Result<String>; fn list_commits( &self, from_oid: &str, to_oid: &str, ) -> Result<Vec<CommitInfo>>; fn commit_diff(&self, oid: &str) -> Result<CommitDiff>; fn commit_diff_for_fragmap(&self, oid: &str) -> Result<CommitDiff>; fn staged_diff(&self) -> Option<CommitDiff>; fn unstaged_diff(&self) -> Option<CommitDiff>; fn split_commit_per_file( &self, commit_oid: &str, head_oid: &str, ) -> Result<()>; fn split_commit_per_hunk( &self, commit_oid: &str, head_oid: &str, ) -> Result<()>; fn split_commit_per_hunk_group( &self, commit_oid: &str, head_oid: &str, reference_oid: &str, ) -> Result<()>; fn count_split_per_file(&self, commit_oid: &str) -> Result<usize>; fn count_split_per_hunk(&self, commit_oid: &str) -> Result<usize>; fn count_split_per_hunk_group( &self, commit_oid: &str, head_oid: &str, reference_oid: &str, ) -> Result<usize>; fn reword_commit( &self, commit_oid: &str, new_message: &str, head_oid: &str, ) -> Result<()>; fn get_config_string(&self, key: &str) -> Option<String>; fn drop_commit( &self, commit_oid: &str, head_oid: &str, ) -> Result<RebaseOutcome>; fn move_commit( &self, commit_oid: &str, insert_after_oid: &str, head_oid: &str, ) -> Result<RebaseOutcome>; fn rebase_continue(&self, state: &ConflictState) -> Result<RebaseOutcome>; fn rebase_abort(&self, state: &ConflictState) -> Result<()>; fn workdir(&self) -> Option<PathBuf>; fn read_index_stage( &self, path: &str, stage: i32, ) -> Result<Option<Vec<u8>>>; fn read_conflicting_files(&self) -> Vec<String>; fn squash_commits( &self, source_oid: &str, target_oid: &str, message: &str, head_oid: &str, ) -> Result<RebaseOutcome>; fn squash_try_combine( &self, source_oid: &str, target_oid: &str, combined_message: &str, is_fixup: bool, head_oid: &str, ) -> Result<Option<ConflictState>>; fn squash_finalize( &self, ctx: &SquashContext, message: &str, original_branch_oid: &str, ) -> Result<RebaseOutcome>; fn stage_file(&self, path: &str) -> Result<()>; fn auto_stage_resolved_conflicts(&self, files: &[String]) -> Result<()>; fn default_branch(&self) -> Option<String>;
}
Expand description

Abstraction over git repository operations.

Isolates the git2 crate to the repo::git2_impl module. Callers work through this trait so that the real Git2Repo implementation can be swapped with a mock or fake in tests.

Required Methods§

Source

fn head_oid(&self) -> Result<String>

Returns the OID that HEAD currently points at.

Fails if HEAD is detached or does not resolve to a direct commit reference.

Source

fn find_reference_point(&self, commit_ish: &str) -> Result<String>

Find the merge-base (reference point) between HEAD and a given commit-ish.

The commit-ish can be:

  • A branch name (e.g., “main”, “feature”)
  • A tag name (e.g., “v1.0”)
  • A commit hash (short or long)

Returns the OID of the common ancestor as a string.

Source

fn list_commits(&self, from_oid: &str, to_oid: &str) -> Result<Vec<CommitInfo>>

List commits from one commit back to another (inclusive).

Walks the commit graph from from_oid back to to_oid, collecting commit metadata. Returns commits in oldest-to-newest order.

Both from_oid and to_oid can be any commit-ish (branch, tag, hash). The range includes both endpoints.

Source

fn commit_diff(&self, oid: &str) -> Result<CommitDiff>

Extract the full diff for a single commit compared to its first parent.

For the root commit (no parents), diffs against an empty tree so all files show as additions. Returns a CommitDiff containing the commit metadata and every file/hunk/line changed.

Source

fn commit_diff_for_fragmap(&self, oid: &str) -> Result<CommitDiff>

Extract commit diff with zero context lines, suitable for fragmap analysis.

The fragmap algorithm needs each logical change as its own hunk. With the default 3-line context, git merges adjacent hunks together which produces fewer but larger hunks — breaking the SPG’s fine-grained span tracking.

Source

fn staged_diff(&self) -> Option<CommitDiff>

Return a synthetic CommitDiff for changes staged in the index (index vs HEAD).

Returns None when the index is clean (no staged changes).

Source

fn unstaged_diff(&self) -> Option<CommitDiff>

Return a synthetic CommitDiff for unstaged working-tree changes (workdir vs index).

Returns None when the working tree is clean relative to the index.

Source

fn split_commit_per_file(&self, commit_oid: &str, head_oid: &str) -> Result<()>

Split a commit into one commit per changed file.

Creates N new commits (one per file touched by commit_oid), each applying only that file’s changes. Rebases all commits between commit_oid (exclusive) and head_oid (inclusive) onto the resulting commits, then fast-forwards the branch ref to the new tip.

Fails if:

  • the commit has fewer than 2 changed files (nothing to split)
  • staged or unstaged changes share file paths with the commit being split
  • a rebase conflict occurs while rebuilding descendants
Source

fn split_commit_per_hunk(&self, commit_oid: &str, head_oid: &str) -> Result<()>

Split a commit into one commit per hunk.

Creates N new commits (one per hunk across all files), in file-then-hunk-index order. Each intermediate tree is built by cumulatively applying the first k hunks of the full diff (with 0 context lines) onto the original parent tree.

Fails if:

  • the commit has fewer than 2 hunks (nothing to split)
  • staged or unstaged changes share file paths with the commit being split
  • a rebase conflict occurs while rebuilding descendants
Source

fn split_commit_per_hunk_group( &self, commit_oid: &str, head_oid: &str, reference_oid: &str, ) -> Result<()>

Split a commit into one commit per hunk group.

Hunks are grouped using the same SPG-based fragmap algorithm shown in the hunk group matrix: two hunks from the commit end up in the same group when they share the same set of interacting commits on the branch (i.e. their fragmap columns deduplicate to the same column). This yields fewer, more cohesive commits than per-hunk splitting, and the groups match exactly what the user sees in the TUI fragmap after deduplication.

Fails if:

  • the commit cannot be mapped to at least 2 fragmap groups (nothing to split)
  • staged or unstaged changes share file paths with the commit being split
  • a rebase conflict occurs while rebuilding descendants
Source

fn count_split_per_file(&self, commit_oid: &str) -> Result<usize>

Count how many commits split_commit_per_file would produce for this commit.

Source

fn count_split_per_hunk(&self, commit_oid: &str) -> Result<usize>

Count how many commits split_commit_per_hunk would produce for this commit.

Source

fn count_split_per_hunk_group( &self, commit_oid: &str, head_oid: &str, reference_oid: &str, ) -> Result<usize>

Count how many fragmap groups split_commit_per_hunk_group would produce for this commit, given the full branch context up to head_oid from reference_oid.

Source

fn reword_commit( &self, commit_oid: &str, new_message: &str, head_oid: &str, ) -> Result<()>

Reword the message of an existing commit.

Creates a new commit with the same tree and parents as commit_oid but with new_message as the commit message, then cherry-picks all commits strictly between commit_oid and head_oid (inclusive) onto the new commit, and fast-forwards the branch ref to the resulting tip.

Because only the message changes the diff at every step is identical, so no conflicts can arise from staged or unstaged working-tree changes.

Source

fn get_config_string(&self, key: &str) -> Option<String>

Read a string value from the repository’s git configuration.

Returns None when the key does not exist or is not valid UTF-8.

Source

fn drop_commit(&self, commit_oid: &str, head_oid: &str) -> Result<RebaseOutcome>

Drop a commit from the branch by cherry-picking its descendants onto its parent.

Returns RebaseOutcome::Complete when all descendants are successfully rebased, or RebaseOutcome::Conflict when a cherry-pick step produces merge conflicts. In the conflict case the working tree and index contain the partially merged state for the user to resolve.

Source

fn move_commit( &self, commit_oid: &str, insert_after_oid: &str, head_oid: &str, ) -> Result<RebaseOutcome>

Move a commit to a different position on the branch.

Removes commit_oid from its current position and inserts it immediately after insert_after_oid. All affected descendants are cherry-picked in the new order.

insert_after_oid may be the merge-base (reference point) to move the commit to the very beginning of the branch.

Returns RebaseOutcome::Complete on success or RebaseOutcome::Conflict when a cherry-pick step conflicts.

Source

fn rebase_continue(&self, state: &ConflictState) -> Result<RebaseOutcome>

Resume a conflicted rebase after the user has resolved conflicts.

Reads the current index (which the user resolved), creates a commit for the conflicting cherry-pick, then continues cherry-picking the remaining descendants. Returns a new RebaseOutcome — the next cherry-pick may also conflict.

Source

fn rebase_abort(&self, state: &ConflictState) -> Result<()>

Abort a conflicted rebase and restore the branch to its original state.

Resets the branch ref to state.original_branch_oid, cleans up the working tree and index.

Source

fn workdir(&self) -> Option<PathBuf>

Return the path of the repository’s working directory, if any.

Bare repositories have no working directory and return None.

Source

fn read_index_stage(&self, path: &str, stage: i32) -> Result<Option<Vec<u8>>>

Read the raw blob content of a specific index stage for a conflicted path.

Stage 1 = base (common ancestor), 2 = ours, 3 = theirs. Returns None when that stage entry does not exist for the path.

Source

fn read_conflicting_files(&self) -> Vec<String>

Return the list of paths that currently have conflict markers in the index (entries with stage > 0), sorted alphabetically and deduplicated.

Source

fn squash_commits( &self, source_oid: &str, target_oid: &str, message: &str, head_oid: &str, ) -> Result<RebaseOutcome>

Squash two commits into one.

Creates a single commit that combines target_oid (older) and source_oid (newer) by cherry-picking source’s diff onto target’s tree. The result replaces target’s position in the history and source is removed. All descendants between target and head_oid (excluding source) are rebased onto the squash commit.

Returns RebaseOutcome::Complete on success or RebaseOutcome::Conflict when a cherry-pick conflicts.

When the initial squash tree creation (source vs target) conflicts, the returned ConflictState carries a squash_context so the TUI can let the user resolve, then call squash_finalize.

Source

fn squash_try_combine( &self, source_oid: &str, target_oid: &str, combined_message: &str, is_fixup: bool, head_oid: &str, ) -> Result<Option<ConflictState>>

Test whether combining source onto target produces a conflict.

Returns Ok(None) when the trees merge cleanly (caller should proceed to open the editor and then call squash_commits).

Returns Ok(Some(ConflictState)) when the cherry-pick conflicts. The conflict is written to the working tree and index. The ConflictState carries a SquashContext so the TUI can let the user resolve, then (for squash) open the editor and call squash_finalize, or (for fixup) call squash_finalize directly without opening the editor.

Source

fn squash_finalize( &self, ctx: &SquashContext, message: &str, original_branch_oid: &str, ) -> Result<RebaseOutcome>

Finalize a squash after the user resolved a squash-time tree conflict.

Reads the resolved index, creates the squash commit with message, then cherry-picks the descendants listed in ctx. Returns RebaseOutcome::Complete or Conflict for a descendant conflict.

Source

fn stage_file(&self, path: &str) -> Result<()>

Stage a working-tree file, clearing any conflict entries for that path.

Equivalent to git add <path>. Reads the file from the working directory, adds it to the index at stage 0 (which removes stages 1/2/3), and writes the updated index to disk. Must be called after a merge tool resolves a conflict so that subsequent index.has_conflicts() checks return false.

Source

fn auto_stage_resolved_conflicts(&self, files: &[String]) -> Result<()>

Auto-stage conflicting files whose working-tree content no longer contains conflict markers.

When a user resolves conflicts in an external editor (instead of the built-in mergetool), the index still carries stage 1/2/3 entries. This method reads each file from disk and stages it if the standard <<<<<<< marker is absent, so that index.has_conflicts() reflects the actual resolution state.

Source

fn default_branch(&self) -> Option<String>

Return the name of the repository’s default upstream branch.

Looks up the symbolic target of refs/remotes/origin/HEAD (the pointer that git remote set-head origin --auto sets) and strips the refs/remotes/ prefix so the returned value can be passed directly to find_reference_point. For example when origin/HEAD points to refs/remotes/origin/main this returns Some("origin/main").

Returns None when the remote tracking ref is absent or has no symbolic target (e.g. the repo has no remote configured, or origin/HEAD was never set).

Implementors§