Skip to content

Commit

Permalink
Merge branch 'gix-submodule'
Browse files Browse the repository at this point in the history
  • Loading branch information
Byron committed Aug 22, 2023
2 parents c35ddab + fc0529e commit 8f3f358
Show file tree
Hide file tree
Showing 87 changed files with 609 additions and 384 deletions.
94 changes: 72 additions & 22 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,10 @@ members = [

"gix-diff/tests",
"gix-pack/tests",
"gix-odb/tests",
"gix-worktree-state/tests",
"gix-status/tests",
"gix-worktree/tests",
"gix-index/tests",
"gix-ref/tests",
"gix-config/tests",
Expand Down
19 changes: 14 additions & 5 deletions gitoxide-core/src/repository/index/entries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,11 @@ pub(crate) mod function {
recurse_submodules,
}: Options,
) -> anyhow::Result<()> {
use crate::OutputFormat::*;
let mut out = BufWriter::with_capacity(64 * 1024, out);
let mut all_attrs = statistics.then(BTreeSet::new);

#[cfg(feature = "serde")]
if let Json = format {
if let OutputFormat::Json = format {
out.write_all(b"[\n")?;
}

Expand All @@ -70,13 +69,14 @@ pub(crate) mod function {
)?;

#[cfg(feature = "serde")]
if format == Json {
if format == OutputFormat::Json {
out.write_all(b"]\n")?;
out.flush()?;
if statistics {
serde_json::to_writer_pretty(&mut err, &stats)?;
}
} else if format == Human && statistics {
}
if format == OutputFormat::Human && statistics {
out.flush()?;
writeln!(err, "{stats:#?}")?;
if let Some(attrs) = all_attrs.filter(|a| !a.is_empty()) {
Expand All @@ -101,7 +101,9 @@ pub(crate) mod function {
recurse_submodules: bool,
out: &mut impl std::io::Write,
) -> anyhow::Result<Statistics> {
let _span = gix::trace::coarse!("print_entries()", git_dir = ?repo.git_dir());
let (mut pathspec, index, mut cache) = init_cache(repo, attributes, pathspecs.clone())?;
let mut repo_attrs = all_attrs.is_some().then(BTreeSet::default);
let submodules_by_path = recurse_submodules
.then(|| {
repo.submodules()
Expand Down Expand Up @@ -142,7 +144,7 @@ pub(crate) mod function {
};
stats.with_attributes += usize::from(!attributes.is_empty());
stats.max_attributes_per_path = stats.max_attributes_per_path.max(attributes.len());
if let Some(attrs) = all_attrs.as_deref_mut() {
if let Some(attrs) = repo_attrs.as_mut() {
attributes.iter().for_each(|attr| {
attrs.insert(attr.clone());
});
Expand Down Expand Up @@ -232,6 +234,12 @@ pub(crate) mod function {
}

stats.cache = cache.map(|c| *c.1.statistics());
if let Some((attrs, all_attrs)) = repo_attrs.zip(all_attrs) {
stats
.attributes
.extend(attrs.iter().map(|attr| attr.as_ref().to_string()));
all_attrs.extend(attrs);
}
Ok(stats)
}

Expand Down Expand Up @@ -301,6 +309,7 @@ pub(crate) mod function {
pub with_attributes: usize,
pub max_attributes_per_path: usize,
pub cache: Option<gix::worktree::stack::Statistics>,
pub attributes: Vec<String>,
pub submodule: Vec<(BString, Statistics)>,
}

Expand Down
1 change: 1 addition & 0 deletions gitoxide-core/src/repository/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,6 @@ pub mod mailmap;
pub mod odb;
pub mod remote;
pub mod revision;
pub mod submodule;
pub mod tree;
pub mod verify;
67 changes: 67 additions & 0 deletions gitoxide-core/src/repository/submodule.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
use crate::OutputFormat;
use anyhow::bail;
use gix::commit::describe::SelectRef;
use gix::prelude::ObjectIdExt;
use gix::{Repository, Submodule};

pub fn list(repo: Repository, mut out: impl std::io::Write, format: OutputFormat) -> anyhow::Result<()> {
if format != OutputFormat::Human {
bail!("Only human output is supported for now")
}

let Some(submodules) = repo.submodules()? else { return Ok(()) };
for sm in submodules {
print_sm(sm, &mut out)?;
}
Ok(())
}

fn print_sm(sm: Submodule<'_>, out: &mut impl std::io::Write) -> anyhow::Result<()> {
let _span = gix::trace::coarse!("print_sm", path = ?sm.path());
let state = sm.state()?;
let mut sm_repo = sm.open()?;
if let Some(repo) = sm_repo.as_mut() {
repo.object_cache_size_if_unset(4 * 1024 * 1024);
};
writeln!(
out,
" {is_active} {path} {config} head:{head_id} index:{index_id} ({worktree}) [{url}]",
is_active = if !sm.is_active()? || !state.repository_exists {
"ⅹ"
} else {
"✓"
},
path = sm.path()?,
config = if state.superproject_configuration {
"config:yes"
} else {
"config:no"
},
head_id = submodule_short_hash(sm.head_id()?, sm_repo.as_ref()),
index_id = submodule_short_hash(sm.index_id()?, sm_repo.as_ref()),
worktree = match sm_repo {
Some(repo) => {
// TODO(name-revision): this is the simple version, `git` gives it
// multiple tries https://github.com/git/git/blob/fac96dfbb1c24369ba7d37a5affd8adfe6c650fd/builtin/submodule--helper.c#L161
// and even uses `git name-rev`/`git describe --contains` which we can't do yet.
repo.head_commit()?
.describe()
.names(SelectRef::AllRefs)
.format()?
.to_string()
}
None => {
"no worktree".to_string()
}
},
url = sm.url()?.to_bstring()
)?;
Ok(())
}

fn submodule_short_hash(id: Option<gix::ObjectId>, repo: Option<&Repository>) -> String {
id.map_or_else(
|| "none".to_string(),
|id| repo.map_or_else(|| id.to_string(), |repo| id.attach(repo).shorten_or_id().to_string()),
)
}
Loading

0 comments on commit 8f3f358

Please sign in to comment.