Skip to content

Commit 8ae9e57

Browse files
committed
feat: Repository::is_dirty() now also checks for tree/index changes.
This copmpletes the `is_dirty()` implementation.
1 parent 83f3d93 commit 8ae9e57

File tree

5 files changed

+48
-10
lines changed

5 files changed

+48
-10
lines changed

gix/src/config/cache/access.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ impl Cache {
181181
.user_agent
182182
.get_or_init(|| {
183183
self.resolved
184-
.string(Gitoxide::USER_AGENT.logical_name().as_str())
184+
.string(&Gitoxide::USER_AGENT)
185185
.map_or_else(|| crate::env::agent().into(), |s| s.to_string())
186186
})
187187
.to_owned();

gix/src/status/mod.rs

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ impl Repository {
130130
///
131131
pub mod is_dirty {
132132
use crate::Repository;
133+
use std::convert::Infallible;
133134

134135
/// The error returned by [Repository::is_dirty()].
135136
#[derive(Debug, thiserror::Error)]
@@ -139,6 +140,12 @@ pub mod is_dirty {
139140
StatusPlatform(#[from] crate::status::Error),
140141
#[error(transparent)]
141142
CreateStatusIterator(#[from] crate::status::index_worktree::iter::Error),
143+
#[error(transparent)]
144+
TreeIndexStatus(#[from] crate::status::tree_index::Error),
145+
#[error(transparent)]
146+
HeadTreeId(#[from] crate::reference::head_tree_id::Error),
147+
#[error(transparent)]
148+
OpenWorktreeIndex(#[from] crate::worktree::open_index::Error),
142149
}
143150

144151
impl Repository {
@@ -150,12 +157,26 @@ pub mod is_dirty {
150157
/// * submodules are taken in consideration, along with their `ignore` and `isActive` configuration
151158
///
152159
/// Note that *untracked files* do *not* affect this flag.
153-
///
154-
/// ### Incomplete Implementation Warning
155-
///
156-
/// Currently, this does not compute changes between the head and the index.
157-
// TODO: use iterator which also tests for head->index changes.
158160
pub fn is_dirty(&self) -> Result<bool, Error> {
161+
{
162+
let head_tree_id = self.head_tree_id()?;
163+
let mut index_is_dirty = false;
164+
165+
// Run this first as there is a high likelihood to find something, and it's very fast.
166+
self.tree_index_status(
167+
&head_tree_id,
168+
&*self.index_or_empty()?,
169+
None,
170+
crate::status::tree_index::TrackRenames::Disabled,
171+
|_, _, _| {
172+
index_is_dirty = true;
173+
Ok::<_, Infallible>(gix_diff::index::Action::Cancel)
174+
},
175+
)?;
176+
if index_is_dirty {
177+
return Ok(true);
178+
}
179+
}
159180
let is_dirty = self
160181
.status(gix_features::progress::Discard)?
161182
.index_worktree_rewrites(None)
Binary file not shown.

gix/tests/fixtures/make_status_repos.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,11 @@ git init -q untracked-only
1313
mkdir new
1414
touch new/untracked subdir/untracked
1515
)
16+
17+
git init git-mv
18+
(cd git-mv
19+
echo hi > file
20+
git add file && git commit -m "init"
21+
22+
git mv file renamed
23+
)

gix/tests/gix/status.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ mod index_worktree {
134134
}
135135

136136
mod is_dirty {
137-
use crate::status::submodule_repo;
137+
use crate::status::{repo, submodule_repo};
138138

139139
#[test]
140140
fn various_changes_positive() -> crate::Result {
@@ -155,7 +155,7 @@ mod is_dirty {
155155
let repo = submodule_repo("module1")?;
156156
assert_eq!(
157157
repo.status(gix::progress::Discard)?
158-
.into_index_worktree_iter(Vec::new())?
158+
.into_index_worktree_iter(None)?
159159
.count(),
160160
1,
161161
"there is one untracked file"
@@ -168,9 +168,18 @@ mod is_dirty {
168168
}
169169

170170
#[test]
171-
fn no_changes() -> crate::Result {
171+
fn index_changed() -> crate::Result {
172+
let repo = repo("git-mv")?;
173+
assert!(
174+
repo.is_dirty()?,
175+
"the only detectable change is in the index, in comparison to the HEAD^{{tree}}"
176+
);
177+
172178
let repo = submodule_repo("with-submodules")?;
173-
assert!(!repo.is_dirty()?, "there are no changes");
179+
assert!(
180+
repo.is_dirty()?,
181+
"the index changed here as well, this time there is also a new file"
182+
);
174183
Ok(())
175184
}
176185
}

0 commit comments

Comments
 (0)