Skip to content

Commit 1a62ff0

Browse files
committed
Add a way to get a list of changed items in the worktree.
1 parent 2ac64b5 commit 1a62ff0

File tree

8 files changed

+203
-11
lines changed

8 files changed

+203
-11
lines changed

Cargo.lock

Lines changed: 40 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/but-core/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@ doctest = false
1212
serde = { workspace = true, features = ["std"] }
1313
bstr.workspace = true
1414
anyhow = "1.0.95"
15-
gix = { workspace = true, features = ["dirwalk", "credentials", "parallel"] }
15+
gix = { workspace = true, features = ["dirwalk", "credentials", "parallel", "serde"] }
1616
walkdir = "2.5.0"
1717
toml.workspace = true

crates/but-core/src/lib.rs

Lines changed: 71 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,88 @@
55
//!
66
//! ### House-~~Rules~~ Guidance
77
//!
8-
//! * Try hard to do write all the 'right' tests
8+
//! * **Try hard to do write all the 'right' tests**
99
//! - Tests should challenge the implementation, try hard to break it.
1010
//! - capture *all* business requirements
1111
//! - Try to avoid doing read-only filesystem fixtures with `tempdir`, instead use `gitbutler-testtools::readonly`.
12-
//! * minimal dependencies
13-
//! - both for the crate and for parameters of functions as well.
12+
//! * **minimal dependencies**
13+
//! - both for the *crate* and for *parameters* of functions as well.
1414
//! - i.e. try to avoid 'God' structures so the function only has access to what it needs to.
15-
//! * The filesystem is `Sync` but we don't have atomic operations
15+
//! * **The filesystem is `Sync` but we don't have atomic operations**
1616
//! - Let's be very careful about changes to the filesystem, must at least be on the level of Git which means `.lock` files instead of direct writes.
1717
//! - If only one part of the application is supposed to change the worktree, let's protect the Application from itself by using `gitbutler::access` just like we do now.
18-
//! * Make it work, make it work right, and if time and profiler permits, make it work fast.
19-
//! * All of the above can and should be scrutinized and is there is no hard rules.
18+
//! * **Implement `Serialize` on utility types to facilitate transfer to the frontend**
19+
//! - But don't make bigger types frontend-specific. If that is needed, create a new type in the frontend-crate that uses frontend types.
20+
//! - `BString` has a `BStringForFrontend` counterpart.
21+
//! - `gix::ObjectId` has a `with = gitbutler_serde::object_id` serialization module.
22+
//! * **Make it work, make it work right, and if time and profiler permits, make it work fast**.
23+
//! * **All of the above can and should be scrutinized and is there is no hard rules.**
24+
//!
25+
//! ### Terminology
26+
//!
27+
//! * **Worktree**
28+
//! - A git worktree, i.e. the checkout of a tree that makes the tree accessible on disk.
29+
//! * **Workspace**
30+
//! - A GitButler concept of the combination of one or more branches into one worktree. This allows
31+
//! multiple branches to be perceived in one worktree, by merging multiple branches together.
32+
//!
2033
2134
/// Functions related to a Git worktree, i.e. the files checked out from a repository.
2235
pub mod worktree {
36+
use bstr::BString;
37+
use serde::{Deserialize, Serialize};
2338
use std::path::Path;
2439

25-
/// Return a list of items that live underneath `worktree_root` that changed and thus can become part of a commit.
26-
pub fn committable_entries(_worktree_root: &Path) -> anyhow::Result<()> {
40+
/// Identify where a [`Committable`] is from.
41+
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
42+
pub enum DiffKind {
43+
/// The change was detected when doing a diff between a tree and an index.
44+
TreeIndex,
45+
/// The change was detected when doing a diff between an index and a worktree.
46+
IndexWorktree,
47+
}
48+
49+
/// Something that fully identifies the state of a [`Committable`].
50+
#[derive(Debug, Clone, Copy)]
51+
pub struct CommittableState {
52+
/// The content of the committable.
53+
///
54+
/// If [`null`](gix::ObjectId::is_null), the current state isn't known which can happen
55+
/// if this state is living in the worktree and has never been hashed.
56+
pub id: gix::ObjectId,
57+
/// The kind of the committable.
58+
pub kind: gix::object::tree::EntryKind,
59+
}
60+
61+
/// An entry in the worktree that changed and thus is eligible to being committed.
62+
///
63+
/// It either lives (or lived) in the in `.git/index`, or in the `worktree`.
64+
///
65+
/// ### Note
66+
///
67+
/// For simplicity, copy-tracking is not representable right now, but `copy: bool` could be added
68+
/// if needed.
69+
#[derive(Debug, Clone)]
70+
pub struct Committable {
71+
/// If this item was renamed, this is the previous path relative to the worktree where it
72+
/// was moved from.
73+
pub previous_path: Option<BString>,
74+
/// The *relative* path in the worktree where the entry can be found.
75+
pub path: BString,
76+
/// The state that was previously recorded.
77+
///
78+
/// If `None`, there is no known previous value, so this is a newly added item.
79+
pub previous_state: Option<CommittableState>,
80+
/// The content that the entry has currently.
81+
///
82+
/// If `None`, this means the entry was deleted, and no current state of it can be known.
83+
pub state: Option<CommittableState>,
84+
}
85+
86+
/// Return a list of `(DiffKind, Committable)` that live underneath `worktree_root` that changed and thus can become part of a commit.
87+
///
88+
/// The [`DiffKind`] determines which diff was performed to learn about the [`Committable`].
89+
pub fn committables(_worktree_root: &Path) -> anyhow::Result<Vec<(DiffKind, Committable)>> {
2790
todo!()
2891
}
2992
}

crates/gitbutler-serde/src/lib.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,29 @@ pub mod oid_opt {
4444
}
4545
}
4646

47+
///
48+
pub mod object_id {
49+
use serde::{Deserialize, Deserializer, Serialize};
50+
use std::str::FromStr;
51+
52+
/// serialize an object ID as hex-string.
53+
pub fn serialize<S>(v: &gix::ObjectId, s: S) -> Result<S::Ok, S::Error>
54+
where
55+
S: serde::Serializer,
56+
{
57+
v.to_string().serialize(s)
58+
}
59+
60+
/// deserialize an object ID from hex-string.
61+
pub fn deserialize<'de, D>(d: D) -> Result<gix::ObjectId, D::Error>
62+
where
63+
D: Deserializer<'de>,
64+
{
65+
let hex = String::deserialize(d)?;
66+
gix::ObjectId::from_str(hex.as_ref()).map_err(serde::de::Error::custom)
67+
}
68+
}
69+
4770
pub mod oid_vec {
4871
use serde::{Deserialize, Deserializer, Serialize};
4972

crates/gitbutler-tauri/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ gitbutler-edit-mode.workspace = true
8383
gitbutler-sync.workspace = true
8484
gitbutler-forge.workspace = true
8585
gitbutler-settings.workspace = true
86+
gitbutler-serde.workspace = true
87+
but-core.workspace = true
8688
open = "5"
8789
url = "2.5.4"
8890
itertools = "0.14"

0 commit comments

Comments
 (0)