Skip to main content

vcs_core/
dto.rs

1//! Backend-agnostic data types the facade returns, generalising the per-tool
2//! shapes of `vcs-git` and `vcs-jj` into one set a consumer can use without
3//! knowing which backend is in play.
4
5use std::path::PathBuf;
6
7/// Which version-control tool backs a [`Repo`](crate::Repo).
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9#[non_exhaustive]
10pub enum BackendKind {
11    /// A plain Git repository.
12    Git,
13    /// A Jujutsu repository (possibly colocated with Git).
14    Jj,
15}
16
17impl BackendKind {
18    /// The tool's short name (`"git"` / `"jj"`).
19    pub fn as_str(self) -> &'static str {
20        match self {
21            BackendKind::Git => "git",
22            BackendKind::Jj => "jj",
23        }
24    }
25}
26
27/// How a file changed in the working copy.
28#[derive(Debug, Clone, Copy, PartialEq, Eq)]
29#[non_exhaustive]
30pub enum ChangeKind {
31    /// Added or untracked.
32    Added,
33    /// Contents modified.
34    Modified,
35    /// Removed.
36    Deleted,
37    /// Renamed (see [`FileChange::old_path`]).
38    Renamed,
39}
40
41/// One changed path in the working copy, unified across `git status` /
42/// `jj diff --summary`.
43#[derive(Debug, Clone, PartialEq, Eq)]
44#[non_exhaustive]
45pub struct FileChange {
46    /// The path (the *new* path for a rename).
47    pub path: String,
48    /// The original path for a rename; `None` otherwise (jj never supplies it).
49    pub old_path: Option<String>,
50    /// How the file changed.
51    pub kind: ChangeKind,
52}
53
54/// Aggregate insertion/deletion counts for the working copy.
55#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
56#[non_exhaustive]
57pub struct DiffStat {
58    /// Number of files changed.
59    pub files_changed: usize,
60    /// Lines inserted.
61    pub insertions: usize,
62    /// Lines deleted.
63    pub deletions: usize,
64}
65
66/// One attached worktree (git) / workspace (jj).
67#[derive(Debug, Clone, PartialEq, Eq)]
68#[non_exhaustive]
69pub struct WorktreeInfo {
70    /// Filesystem path of the worktree's working copy.
71    pub path: PathBuf,
72    /// The branch (git) or first bookmark (jj) on it; `None` when detached/none.
73    pub branch: Option<String>,
74    /// The checked-out commit; `None` when unavailable (e.g. a bare git entry).
75    pub commit: Option<String>,
76    /// A bare git worktree entry (always `false` for jj).
77    pub is_bare: bool,
78}
79
80/// Whether the working copy is mid-operation, unified across the backends'
81/// different models: git exposes an in-progress merge or rebase as on-disk state
82/// (`MERGE_HEAD` / a `rebase-*` dir), while jj has no multi-step operations — it
83/// records a conflict directly on the working-copy change.
84#[derive(Debug, Clone, Copy, PartialEq, Eq)]
85#[non_exhaustive]
86pub enum OperationState {
87    /// No operation in progress and no conflict.
88    Clear,
89    /// A git merge is in progress (`MERGE_HEAD` present).
90    Merge,
91    /// A git rebase is in progress (a `rebase-merge`/`rebase-apply` dir present).
92    Rebase,
93    /// The working copy has an unresolved conflict (chiefly jj, which records
94    /// conflicts on the change rather than pausing an operation).
95    Conflict,
96}
97
98/// How a worktree was materialised. The facade always reports
99/// [`Plain`](CreateOutcome::Plain); the [`CowCloned`](CreateOutcome::CowCloned)
100/// variant exists so a consumer that layers a copy-on-write strategy on top can
101/// reuse this type.
102#[derive(Debug, Clone, Copy, PartialEq, Eq)]
103#[non_exhaustive]
104pub enum CreateOutcome {
105    /// The tool materialised the working copy itself.
106    Plain,
107    /// A copy-on-write clone populated the working copy (consumer-supplied).
108    CowCloned,
109}