Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tree -> index diff for status #1410

Merged
merged 17 commits into from
Jan 3, 2025
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions gix/src/submodule/mod.rs
Original file line number Diff line number Diff line change
@@ -323,6 +323,11 @@ pub mod status {
/// Return the status of the submodule, just like [`status`](Self::status), but allows to adjust options
/// for more control over how the status is performed.
///
/// If `check_dirty` is `true`, the computation will stop once the first in a ladder operations
/// ordered from cheap to expensive shows that the submodule is dirty. When checking for detailed
/// status information (i.e. untracked file, modifications, HEAD-index changes) only the first change
/// will be kept to stop as early as possible.
///
/// Use `&mut std::convert::identity` for `adjust_options` if no specific options are desired.
/// A reason to change them might be to enable sorting to enjoy deterministic order of changes.
///
@@ -389,6 +394,9 @@ pub mod status {
let mut changes = Vec::new();
for change in statuses {
changes.push(change?);
if check_dirty {
break;
}
}
status.changes = Some(changes);
Ok(status)
Binary file modified gix/tests/fixtures/generated-archives/make_submodules.tar
Binary file not shown.
11 changes: 11 additions & 0 deletions gix/tests/fixtures/make_submodules.sh
Original file line number Diff line number Diff line change
@@ -21,6 +21,17 @@ git init submodule-head-changed
cd m1 && git checkout @~1
)

git init submodule-index-changed
(cd submodule-index-changed
git submodule add ../module1 m1
git commit -m "add submodule"

(cd m1
git mv subdir subdir-renamed
git mv this that
)
)

git init submodule-head-changed-no-worktree
(cd submodule-head-changed-no-worktree
git submodule add ../module1 m1
39 changes: 36 additions & 3 deletions gix/tests/gix/submodule.rs
Original file line number Diff line number Diff line change
@@ -186,6 +186,37 @@ mod open {
Ok(())
}

#[test]
fn modified_in_index_only() -> crate::Result {
let repo = repo("submodule-index-changed")?;
let sm = repo.submodules()?.into_iter().flatten().next().expect("one submodule");

for mode in [
gix::submodule::config::Ignore::Untracked,
gix::submodule::config::Ignore::None,
] {
for check_dirty in [false, true] {
let status = sm.status_opts(mode, check_dirty, &mut |platform| platform)?;
assert_eq!(
status.is_dirty(),
Some(true),
"two files were renamed using `git mv` for an HEAD^{{tree}}-index change"
);
assert_eq!(
status.changes.expect("present").len(),
if check_dirty { 1 } else { 3 },
"in is-dirty mode, we don't collect all changes"
);
}
}

assert!(
repo.is_dirty()?,
"superproject should see submodule changes in the index as well"
);
Ok(())
}

#[test]
fn modified_and_untracked() -> crate::Result {
let repo = repo("modified-and-untracked")?;
@@ -194,7 +225,7 @@ mod open {
let status = sm.status(gix::submodule::config::Ignore::Dirty, false)?;
assert_eq!(status.is_dirty(), Some(false), "Dirty skips worktree changes entirely");

let status = sm.status_opts(
let mut status = sm.status_opts(
gix::submodule::config::Ignore::None,
false,
&mut |status: gix::status::Platform<'_, gix::progress::Discard>| {
@@ -217,16 +248,18 @@ mod open {

let status_with_dirty_check = sm.status_opts(
gix::submodule::config::Ignore::None,
true,
true, /* check-dirty */
&mut |status: gix::status::Platform<'_, gix::progress::Discard>| {
status.index_worktree_options_mut(|opts| {
opts.sorting = Some(gix_status::index_as_worktree_with_renames::Sorting::ByPathCaseSensitive);
})
},
)?;
status.changes.as_mut().expect("two changes").pop();
assert_eq!(
status_with_dirty_check, status,
"it cannot abort early as the only change it sees is the modification check"
"it cannot abort early as the only change it sees is the modification check.\
However, with check-dirty, it would only gather the changes"
);

let status = sm.status(gix::submodule::config::Ignore::Untracked, false)?;