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}