Skip to content

Commit 83f25f3

Browse files
committed
The TreeChange now keeps track of the underlying gix status item.
That way it's possible to reconstruct the exact status, and know if it's coming from a change in the index, or a change in the worktree. This is relevant later when storing index changes.
1 parent 83ab16a commit 83f25f3

File tree

5 files changed

+49
-5
lines changed

5 files changed

+49
-5
lines changed

crates/but-core/src/diff/mod.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,15 @@ impl TreeChange {
5959
}
6060
}
6161

62+
impl std::fmt::Debug for TreeChange {
63+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64+
f.debug_struct("TreeChange")
65+
.field("path", &self.path)
66+
.field("status", &self.status)
67+
.finish()
68+
}
69+
}
70+
6271
impl ModeFlags {
6372
fn calculate(old: &ChangeState, new: &ChangeState) -> Option<Self> {
6473
Self::calculate_inner(old.kind, new.kind)

crates/but-core/src/diff/tree_changes.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ impl From<gix::object::tree::diff::ChangeDetached> for TreeChange {
8181
},
8282
is_untracked: false,
8383
},
84+
status_item: None,
8485
},
8586
Change::Deletion {
8687
location,
@@ -95,6 +96,7 @@ impl From<gix::object::tree::diff::ChangeDetached> for TreeChange {
9596
kind: entry_mode.kind(),
9697
},
9798
},
99+
status_item: None,
98100
},
99101
Change::Modification {
100102
location,
@@ -118,6 +120,7 @@ impl From<gix::object::tree::diff::ChangeDetached> for TreeChange {
118120
state,
119121
flags: ModeFlags::calculate(&previous_state, &state),
120122
},
123+
status_item: None,
121124
}
122125
}
123126
Change::Rewrite {
@@ -147,6 +150,7 @@ impl From<gix::object::tree::diff::ChangeDetached> for TreeChange {
147150
state,
148151
flags: ModeFlags::calculate(&previous_state, &state),
149152
},
153+
status_item: None,
150154
}
151155
}
152156
}

crates/but-core/src/diff/worktree.rs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ pub fn worktree_changes(repo: &gix::Repository) -> anyhow::Result<WorktreeChange
7575
let mut ignored_changes = Vec::new();
7676
for change in status_changes {
7777
let change = change?;
78-
let change = match change {
78+
let change = match change.clone() {
7979
status::Item::TreeIndex(gix::diff::index::Change::Deletion {
8080
location,
8181
id,
@@ -91,6 +91,7 @@ pub fn worktree_changes(repo: &gix::Repository) -> anyhow::Result<WorktreeChange
9191
},
9292
},
9393
path: location.into_owned(),
94+
status_item: Some(change),
9495
},
9596
),
9697
status::Item::TreeIndex(gix::diff::index::Change::Addition {
@@ -109,6 +110,7 @@ pub fn worktree_changes(repo: &gix::Repository) -> anyhow::Result<WorktreeChange
109110
kind: into_tree_entry_kind(entry_mode)?,
110111
},
111112
},
113+
status_item: Some(change),
112114
},
113115
),
114116
status::Item::TreeIndex(gix::diff::index::Change::Modification {
@@ -136,6 +138,7 @@ pub fn worktree_changes(repo: &gix::Repository) -> anyhow::Result<WorktreeChange
136138
state,
137139
flags: ModeFlags::calculate(&previous_state, &state),
138140
},
141+
status_item: Some(change),
139142
},
140143
)
141144
}
@@ -154,6 +157,7 @@ pub fn worktree_changes(repo: &gix::Repository) -> anyhow::Result<WorktreeChange
154157
kind: into_tree_entry_kind(entry.mode)?,
155158
},
156159
},
160+
status_item: Some(change),
157161
},
158162
),
159163
status::Item::IndexWorktree(index_worktree::Item::Modification {
@@ -180,6 +184,7 @@ pub fn worktree_changes(repo: &gix::Repository) -> anyhow::Result<WorktreeChange
180184
state,
181185
flags: ModeFlags::calculate(&previous_state, &state),
182186
},
187+
status_item: Some(change),
183188
},
184189
)
185190
}
@@ -216,6 +221,7 @@ pub fn worktree_changes(repo: &gix::Repository) -> anyhow::Result<WorktreeChange
216221
state,
217222
flags: ModeFlags::calculate(&previous_state, &state),
218223
},
224+
status_item: Some(change),
219225
},
220226
)
221227
}
@@ -237,6 +243,7 @@ pub fn worktree_changes(repo: &gix::Repository) -> anyhow::Result<WorktreeChange
237243
},
238244
is_untracked: false,
239245
},
246+
status_item: Some(change),
240247
},
241248
),
242249
status::Item::IndexWorktree(index_worktree::Item::DirectoryContents {
@@ -269,17 +276,20 @@ pub fn worktree_changes(repo: &gix::Repository) -> anyhow::Result<WorktreeChange
269276
},
270277
is_untracked: true,
271278
},
279+
status_item: Some(change),
272280
},
273281
)
274282
}
275283
status::Item::IndexWorktree(index_worktree::Item::Modification {
276284
rela_path,
277285
entry,
278286
status:
279-
EntryStatus::Change(index_as_worktree::Change::SubmoduleModification(change)),
287+
EntryStatus::Change(index_as_worktree::Change::SubmoduleModification(
288+
submodule_change,
289+
)),
280290
..
281291
}) => {
282-
let Some(checked_out_head_id) = change.checked_out_head_id else {
292+
let Some(checked_out_head_id) = submodule_change.checked_out_head_id else {
283293
continue;
284294
};
285295
// We can arrive here if the user configures to `ignore = none`, and there are
@@ -306,6 +316,7 @@ pub fn worktree_changes(repo: &gix::Repository) -> anyhow::Result<WorktreeChange
306316
state,
307317
flags: ModeFlags::calculate(&previous_state, &state),
308318
},
319+
status_item: Some(change),
309320
},
310321
)
311322
}
@@ -361,6 +372,7 @@ pub fn worktree_changes(repo: &gix::Repository) -> anyhow::Result<WorktreeChange
361372
state,
362373
flags: ModeFlags::calculate(&previous_state, &state),
363374
},
375+
status_item: Some(change),
364376
},
365377
)
366378
}
@@ -391,6 +403,7 @@ pub fn worktree_changes(repo: &gix::Repository) -> anyhow::Result<WorktreeChange
391403
state,
392404
flags: ModeFlags::calculate(&previous_state, &state),
393405
},
406+
status_item: Some(change),
394407
},
395408
)
396409
}
@@ -655,6 +668,8 @@ fn merge_changes(
655668
status: TreeStatus::Deletion {
656669
previous_state: *previous_state,
657670
},
671+
// NOTE: not relevant, as renames are disabled for snapshots where this is used.
672+
status_item: None,
658673
}));
659674
}
660675
(
@@ -674,6 +689,8 @@ fn merge_changes(
674689
// It's just in the index, which to us doesn't exist.
675690
is_untracked: true,
676691
},
692+
// NOTE: not relevant, as renames are disabled for snapshots where this is used.
693+
status_item: None,
677694
}),
678695
Some(TreeChange {
679696
path: index_wt.path,
@@ -685,6 +702,8 @@ fn merge_changes(
685702
// read the initial state of a file from.
686703
is_untracked: true,
687704
},
705+
// NOTE: not relevant, as renames are disabled for snapshots where this is used.
706+
status_item: None,
688707
}),
689708
]);
690709
}

crates/but-core/src/lib.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,12 +233,16 @@ pub fn open_repo(path: impl Into<PathBuf>) -> anyhow::Result<gix::Repository> {
233233
///
234234
/// For simplicity, copy-tracking is not representable right now, but `copy: bool` could be added
235235
/// if needed. Copy-tracking is deactivated as well.
236-
#[derive(Debug, Clone)]
236+
#[derive(Clone)]
237237
pub struct TreeChange {
238238
/// The *relative* path in the worktree where the entry can be found.
239239
pub path: BString,
240240
/// The specific information about this change.
241241
pub status: TreeStatus,
242+
/// The status item that this change is derived from, used in places that need detailed information.
243+
/// This is only set if this instance was created from a worktree-status, and is `None` when created
244+
/// from a tree-diff.
245+
pub status_item: Option<gix::status::Item>,
242246
}
243247

244248
/// Specifically defines a [`TreeChange`].

crates/but-core/src/ui.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,12 +269,20 @@ impl From<TreeChange> for crate::TreeChange {
269269
crate::TreeChange {
270270
path: path_bytes,
271271
status: status.into(),
272+
// Lossy conversion, but this is fine.
273+
status_item: None,
272274
}
273275
}
274276
}
275277

276278
impl From<crate::TreeChange> for TreeChange {
277-
fn from(crate::TreeChange { path, status }: crate::TreeChange) -> Self {
279+
fn from(
280+
crate::TreeChange {
281+
path,
282+
status,
283+
status_item: _,
284+
}: crate::TreeChange,
285+
) -> Self {
278286
TreeChange {
279287
path: path.clone().into(),
280288
path_bytes: path,

0 commit comments

Comments
 (0)