Skip to content

Commit

Permalink
feat: gix remote ref-map --show-unmapped-remote-refs. (#450)
Browse files Browse the repository at this point in the history
That way it's more obvious to see what was filtered out by ref-specs.

It's also great to validate that server-side filtering via ref-prefix
will not send refs that are referred to by symbolic refs that are
not filtered out. That should be fine as it's all about objects,
it's just something to deal with as we may have to deal with symbolic
refs that aren't in the set of refs the server sent to us.
  • Loading branch information
Byron committed Oct 31, 2022
1 parent 376829a commit e973dfe
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 10 deletions.
10 changes: 9 additions & 1 deletion gitoxide-core/src/repository/fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,15 @@ pub(crate) mod function {
let ref_specs = remote.refspecs(git::remote::Direction::Fetch);
match res.status {
Status::NoChange => {
crate::repository::remote::refs::print_refmap(&repo, ref_specs, res.ref_map, &mut out, err)
let show_unmapped = false;
crate::repository::remote::refs::print_refmap(
&repo,
ref_specs,
res.ref_map,
show_unmapped,
&mut out,
err,
)
}
Status::DryRun { update_refs } => print_updates(&repo, update_refs, ref_specs, res.ref_map, &mut out, err),
Status::Change {
Expand Down
41 changes: 35 additions & 6 deletions gitoxide-core/src/repository/remote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
mod refs_impl {
use anyhow::bail;
use git_repository as git;
use git_repository::remote::fetch::Source;
use git_repository::{
protocol::fetch,
refspec::{match_group::validate::Fix, RefSpec},
Expand All @@ -19,7 +20,10 @@ mod refs_impl {

pub enum Kind {
Remote,
Tracking { ref_specs: Vec<BString> },
Tracking {
ref_specs: Vec<BString>,
show_unmapped_remote_refs: bool,
},
}

pub struct Options {
Expand All @@ -46,14 +50,21 @@ mod refs_impl {
) -> anyhow::Result<()> {
use anyhow::Context;
let mut remote = by_name_or_url(&repo, name_or_url.as_deref())?;
if let refs::Kind::Tracking { ref_specs, .. } = &kind {
let show_unmapped = if let refs::Kind::Tracking {
ref_specs,
show_unmapped_remote_refs,
} = &kind
{
if format != OutputFormat::Human {
bail!("JSON output isn't yet supported for listing ref-mappings.");
}
if !ref_specs.is_empty() {
remote.replace_refspecs(ref_specs.iter(), git::remote::Direction::Fetch)?;
}
}
*show_unmapped_remote_refs
} else {
false
};
progress.info(format!(
"Connecting to {:?}",
remote
Expand All @@ -75,9 +86,14 @@ mod refs_impl {
writeln!(out, "\t{:?}", map.handshake)?;
}
match kind {
refs::Kind::Tracking { .. } => {
print_refmap(&repo, remote.refspecs(git::remote::Direction::Fetch), map, out, err)
}
refs::Kind::Tracking { .. } => print_refmap(
&repo,
remote.refspecs(git::remote::Direction::Fetch),
map,
show_unmapped,
out,
err,
),
refs::Kind::Remote => {
match format {
OutputFormat::Human => drop(print(out, &map.remote_refs)),
Expand All @@ -96,6 +112,7 @@ mod refs_impl {
repo: &git::Repository,
refspecs: &[RefSpec],
mut map: git::remote::fetch::RefMap,
show_unmapped_remotes: bool,
mut out: impl std::io::Write,
mut err: impl std::io::Write,
) -> anyhow::Result<()> {
Expand Down Expand Up @@ -169,6 +186,18 @@ mod refs_impl {
map.remote_refs.len() - map.mappings.len(),
refspecs.len()
)?;
if show_unmapped_remotes {
writeln!(&mut out, "\nFiltered: ")?;
for remote_ref in map.remote_refs.iter().filter(|r| {
!map.mappings.iter().any(|m| match &m.remote {
Source::Ref(other) => other == *r,
Source::ObjectId(_) => false,
})
}) {
print_ref(&mut out, remote_ref)?;
writeln!(&mut out)?;
}
}
}
if refspecs.is_empty() {
bail!("Without ref-specs there is nothing to show here. Add ref-specs as arguments or configure them in git-config.")
Expand Down
10 changes: 7 additions & 3 deletions src/plumbing/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,9 +178,13 @@ pub fn main() -> Result<()> {
remote::Subcommands::Refs | remote::Subcommands::RefMap { .. } => {
let kind = match cmd {
remote::Subcommands::Refs => core::repository::remote::refs::Kind::Remote,
remote::Subcommands::RefMap { ref_spec } => {
core::repository::remote::refs::Kind::Tracking { ref_specs: ref_spec }
}
remote::Subcommands::RefMap {
ref_spec,
show_unmapped_remote_refs,
} => core::repository::remote::refs::Kind::Tracking {
ref_specs: ref_spec,
show_unmapped_remote_refs,
},
};
let context = core::repository::remote::refs::Options {
name_or_url: name,
Expand Down
3 changes: 3 additions & 0 deletions src/plumbing/options/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,9 @@ pub mod remote {
Refs,
/// Print all references available on the remote as filtered through ref-specs.
RefMap {
/// Also display remote references that were sent by the server, but filtered by the refspec locally.
#[clap(long, short = 'u')]
show_unmapped_remote_refs: bool,
/// Override the built-in and configured ref-specs with one or more of the given ones.
#[clap(parse(try_from_os_str = git::env::os_str_to_bstring))]
ref_spec: Vec<git_repository::bstr::BString>,
Expand Down

0 comments on commit e973dfe

Please sign in to comment.