Skip to content

Commit

Permalink
support for --url for arbitrary urls when fetching (#450)
Browse files Browse the repository at this point in the history
Also known as 'anonymous remotes'.
  • Loading branch information
Byron committed Oct 2, 2022
1 parent 5b72d27 commit 8c7351c
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 11 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ Please see _'Development Status'_ for a listing of all crates and their capabili
* **remote**
* [x] **refs** - list all references available on the remote based on the current remote configuration.
* [x] **ref-map** - show how remote references relate to their local tracking branches as mapped by refspecs.
* **fetch** - fetch the current remote or the given one, optionally just as dry-run.
* **credential**
* [x] **fill/approve/reject** - The same as `git credential`, but implemented in Rust, calling helpers only when from trusted configuration.
* **free** - no git repository necessary
Expand Down
3 changes: 3 additions & 0 deletions gitoxide-core/src/repository/fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub struct Options {
pub format: OutputFormat,
pub dry_run: bool,
pub remote: Option<String>,
pub url: Option<git::Url>,
/// If non-empty, override all ref-specs otherwise configured in the remote
pub ref_specs: Vec<BString>,
}
Expand All @@ -26,9 +27,11 @@ pub(crate) mod function {
format,
dry_run,
remote,
url,
ref_specs,
}: Options,
) -> anyhow::Result<()> {
let _remote = crate::repository::remote::by_name_or_url(&repo, remote.as_deref(), url)?;
todo!()
}
}
33 changes: 22 additions & 11 deletions gitoxide-core/src/repository/remote.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
#[cfg(any(feature = "blocking-client", feature = "async-client"))]
mod refs_impl {
use super::by_name_or_url;
use crate::OutputFormat;
use anyhow::bail;
use git_repository as git;
use git_repository::{
protocol::fetch,
refspec::{match_group::validate::Fix, RefSpec},
};

use crate::OutputFormat;

pub mod refs {
use git_repository::bstr::BString;

Expand Down Expand Up @@ -46,15 +46,7 @@ mod refs_impl {
}: refs::Context,
) -> anyhow::Result<()> {
use anyhow::Context;
let mut remote = match (name, url) {
(Some(name), None) => repo.find_remote(&name)?,
(None, None) => repo
.head()?
.into_remote(git::remote::Direction::Fetch)
.context("Cannot find a remote for unborn branch")??,
(None, Some(url)) => repo.remote_at(url)?,
(Some(_), Some(_)) => bail!("Must not set both the remote name and the url - they are mutually exclusive"),
};
let mut remote = by_name_or_url(&repo, name.as_deref(), url)?;
if let refs::Kind::Tracking { ref_specs, .. } = &kind {
if format != OutputFormat::Human {
bail!("JSON output isn't yet supported for listing ref-mappings.");
Expand Down Expand Up @@ -258,3 +250,22 @@ mod refs_impl {
}
#[cfg(any(feature = "blocking-client", feature = "async-client"))]
pub use refs_impl::{refs, refs_fn as refs, JsonRef};

use git_repository as git;

pub(crate) fn by_name_or_url<'repo>(
repo: &'repo git::Repository,
name: Option<&str>,
url: Option<git::Url>,
) -> anyhow::Result<git::Remote<'repo>> {
use anyhow::{bail, Context};
Ok(match (name, url) {
(Some(name), None) => repo.find_remote(&name)?,
(None, None) => repo
.head()?
.into_remote(git::remote::Direction::Fetch)
.context("Cannot find a remote for unborn branch")??,
(None, Some(url)) => repo.remote_at(url)?,
(Some(_), Some(_)) => bail!("Must not set both the remote name and the url - they are mutually exclusive"),
})
}
2 changes: 2 additions & 0 deletions src/plumbing/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,14 @@ pub fn main() -> Result<()> {
dry_run,
remote,
ref_spec,
url,
}) => {
let opts = core::repository::fetch::Options {
format,
dry_run,
remote,
ref_specs: ref_spec,
url,
};
prepare_and_run(
"fetch",
Expand Down
4 changes: 4 additions & 0 deletions src/plumbing/options/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,10 @@ pub mod fetch {
#[clap(long, short = 'r')]
pub remote: Option<String>,

/// Connect directly to the given URL, forgoing any configuration from the repository.
#[clap(long, short = 'u', conflicts_with("remote"), parse(try_from_os_str = std::convert::TryFrom::try_from))]
pub url: Option<git::Url>,

/// 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))]
pub ref_spec: Vec<git_repository::bstr::BString>,
Expand Down

0 comments on commit 8c7351c

Please sign in to comment.