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

improvements #1834

Merged
merged 1 commit into from
Feb 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
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
12 changes: 12 additions & 0 deletions gix/src/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::borrow::Cow;
pub use gix_filter as plumbing;
use gix_object::Find;

use crate::prelude::ObjectIdExt;
use crate::{
bstr::BStr,
config::{
Expand Down Expand Up @@ -207,6 +208,9 @@ impl Pipeline<'_> {
}

/// Add the worktree file at `rela_path` to the object database and return its `(id, entry, symlink_metadata)` for use in a tree or in the index, for instance.
/// If `rela_path` is a directory *and* is a repository with its `HEAD` pointing to a commit, it will also be provided with the appropriate kind.
/// Note that this can easily lead to embedded repositories as no submodule-crosscheck is performed. Otherwise, unreadable repositories or directories
/// are ignored with `None` as return value.
///
/// `index` is used in particularly rare cases where the CRLF filter in auto-mode tries to determine whether to apply itself,
/// and it should match the state used when [instantiating this instance](Self::new()).
Expand Down Expand Up @@ -257,6 +261,14 @@ impl Pipeline<'_> {
gix_object::tree::EntryKind::Blob
};
(id, kind)
} else if md.is_dir() {
let Some(submodule_repo) = crate::open_opts(&path, repo.open_options().clone()).ok() else {
return Ok(None);
};
let Some(id) = submodule_repo.head_id().ok() else {
return Ok(None);
};
(id.detach().attach(repo), gix_object::tree::EntryKind::Commit)
} else {
// This is probably a type-change to something we can't track.
return Ok(None);
Expand Down
10 changes: 10 additions & 0 deletions gix/tests/fixtures/repo_with_untracked_files.sh
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
#!/usr/bin/env bash
set -eu -o pipefail

git init embedded-repository
(cd embedded-repository
echo content >file && git add file && git commit -m "init"
)

git init -q
echo content >file
ln -s file link

echo binary >exe && chmod +x exe
mkfifo fifo

git submodule add ./embedded-repository submodule

mkdir empty-dir
git init uninitialized-embedded-repository
26 changes: 22 additions & 4 deletions gix/tests/gix/repository/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,32 @@ fn pipeline_in_repo_without_special_options() -> crate::Result {
#[cfg(unix)]
fn pipeline_worktree_file_to_object() -> crate::Result {
let repo = named_repo("repo_with_untracked_files.sh")?;
let work_dir = repo.work_dir().expect("non-bare");
let (mut pipe, index) = repo.filter_pipeline(None)?;
fn take_two<A, B, C>(t: Option<(A, B, C)>) -> Option<(A, B)> {
t.map(|t| (t.0, t.1))
}

let submodule_id = hex_to_id("a047f8183ba2bb7eb00ef89e60050c5fde740483");
assert_eq!(
take_two(pipe.worktree_file_to_object("embedded-repository".into(), &index)?),
Some((submodule_id, gix::object::tree::EntryKind::Commit))
);
assert_eq!(
take_two(pipe.worktree_file_to_object("submodule".into(), &index)?),
Some((submodule_id, gix::object::tree::EntryKind::Commit))
);
assert_eq!(
take_two(pipe.worktree_file_to_object("uninitialized-embedded-repository".into(), &index)?),
None,
"repositories that don't have HEAD pointing to an ID yet are ignored"
);
assert!(work_dir.join("empty-dir").is_dir());
assert_eq!(
take_two(pipe.worktree_file_to_object("empty-dir".into(), &index)?),
None,
"directories that aren't even repos are also ignored"
);
assert_eq!(
take_two(pipe.worktree_file_to_object("file".into(), &index)?),
Some((
Expand All @@ -66,10 +87,7 @@ fn pipeline_worktree_file_to_object() -> crate::Result {
None,
"Missing files are specifically typed and no error"
);
assert!(
repo.work_dir().expect("non-bare").join("fifo").exists(),
"there is a fifo"
);
assert!(work_dir.join("fifo").exists(), "there is a fifo");
assert_eq!(
take_two(pipe.worktree_file_to_object("fifo".into(), &index)?),
None,
Expand Down
Loading