Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
remote-helper: Simplify handling of `GIT_DIR`
Lorenz Leutgeb committed 7 months ago
commit 60b920e7b65ae985b6383af26eb389e05e1fdeb9
parent 3ade4a776da19e075418ce868d434ac63eade6dd
3 files changed +17 -42
modified crates/radicle-remote-helper/src/fetch.rs
@@ -1,5 +1,4 @@
use std::io;
-
use std::path::Path;
use std::str::FromStr;

use thiserror::Error;
@@ -28,7 +27,6 @@ pub enum Error {
/// Run a git fetch command.
pub fn run<R: ReadRepository>(
    mut refs: Vec<(git::Oid, git::RefString)>,
-
    working: &Path,
    stored: R,
    stdin: &io::Stdin,
    verbosity: Verbosity,
modified crates/radicle-remote-helper/src/main.rs
@@ -84,12 +84,6 @@ pub enum Error {
    /// I/O error.
    #[error("i/o error: {0}")]
    Io(#[from] io::Error),
-
    /// The `GIT_DIR` env var is not set.
-
    #[error("the `GIT_DIR` environment variable is not set")]
-
    NoGitDir,
-
    /// No parent of `GIT_DIR` was found.
-
    #[error("expected parent of .git but found {path:?}")]
-
    NoWorkingCopy { path: PathBuf },
    /// Git error.
    #[error("git: {0}")]
    Git(#[from] git::raw::Error),
@@ -180,13 +174,14 @@ pub fn run(profile: radicle::Profile) -> Result<(), Error> {
        }
    };

+
    // Assume the default remote if there was no remote.
+
    let remote = remote.unwrap_or_else(|| (*radicle::rad::REMOTE_NAME).clone());
+

    let stored = profile.storage.repository_mut(url.repo)?;
    if stored.is_empty()? {
        return Err(Error::RepositoryNotFound(stored.path().to_path_buf()));
    }

-
    // `GIT_DIR` is set by Git tooling, if we're in a working copy.
-
    let working = env::var("GIT_DIR").map(PathBuf::from);
    // Whether we should output debug logs.
    let debug = radicle::profile::env::debug();

@@ -237,33 +232,23 @@ pub fn run(profile: radicle::Profile) -> Result<(), Error> {
            ["fetch", oid, refstr] => {
                let oid = git::Oid::from_str(oid)?;
                let refstr = git::RefString::try_from(*refstr)?;
-

-
                // N.b. `working` is the `.git` folder and `fetch::run`
-
                // requires the working directory.
-
                let working = dunce::canonicalize(working.map_err(|_| Error::NoGitDir)?)?;
-
                let working = working.parent().ok_or_else(|| Error::NoWorkingCopy {
-
                    path: working.clone(),
-
                })?;
-

-
                return fetch::run(vec![(oid, refstr)], working, stored, &stdin, opts.verbosity)
-
                    .map_err(Error::from);
+
                return Ok(fetch::run(
+
                    vec![(oid, refstr)],
+
                    stored,
+
                    &stdin,
+
                    opts.verbosity,
+
                )?);
            }
            ["push", refspec] => {
-
                // We have to be in a working copy to push.
-
                let working = working.map_err(|_| Error::NoGitDir)?;
-

-
                return push::run(
+
                return Ok(push::run(
                    vec![refspec.to_string()],
-
                    &working,
-
                    // N.b. assume the default remote if there was no remote
-
                    remote.unwrap_or((*radicle::rad::REMOTE_NAME).clone()),
+
                    remote,
                    url,
                    &stored,
                    &profile,
                    &stdin,
                    opts,
-
                )
-
                .map_err(Error::from);
+
                )?);
            }
            ["list"] => {
                list::for_fetch(&url, &profile, &stored)?;
@@ -370,4 +355,4 @@ pub(crate) fn patches_mut<'a>(
        }
        Err(err) => Err(err.into()),
    }
-
}

\ No newline at end of file
+
}
modified crates/radicle-remote-helper/src/push.rs
@@ -5,7 +5,6 @@ mod error;

use std::collections::HashMap;
use std::io::IsTerminal;
-
use std::path::{Path, PathBuf};
use std::process::ExitStatus;
use std::str::FromStr;
use std::{assert_eq, io};
@@ -36,10 +35,6 @@ use crate::{hint, read_line, Options, Verbosity};

#[derive(Debug, Error)]
pub enum Error {
-
    #[error(
-
        "the Git repository found at {path:?} is a bare repository, expected a working directory"
-
    )]
-
    BareRepository { path: PathBuf },
    /// Public key doesn't match the remote namespace we're pushing to.
    #[error("cannot push to remote namespace owned by {0}")]
    KeyMismatch(Did),
@@ -251,7 +246,6 @@ impl PushAction {
/// Run a git push command.
pub fn run(
    mut specs: Vec<String>,
-
    working: &Path,
    remote: git::RefString,
    url: Url,
    stored: &storage::git::Repository,
@@ -296,7 +290,7 @@ pub fn run(
    let canonical_ref = git::refs::branch(project.default_branch());
    let mut set_canonical_refs: Vec<(git::Qualified, git::canonical::Object)> =
        Vec::with_capacity(specs.len());
-
    let working = git::raw::Repository::open(working)?;
+
    let working = git::raw::Repository::open_from_env()?;

    // For each refspec, push a ref or delete a ref.
    for spec in specs {
@@ -506,7 +500,7 @@ where
    //
    // In case the reference is not properly deleted, the next attempt to open a patch should
    // not fail, since the reference will already exist with the correct OID.
-
    push_ref(src, &dst, false, working, stored.raw(), opts.verbosity)?;
+
    push_ref(src, &dst, false, stored.raw(), opts.verbosity)?;

    let (_, target) = stored.canonical_head()?;
    let base = if let Some(base) = opts.base {
@@ -620,7 +614,7 @@ where
    let commit = *src;
    let dst = dst.with_namespace(nid.into());

-
    push_ref(src, &dst, force, working, stored.raw(), opts.verbosity)?;
+
    push_ref(src, &dst, force, stored.raw(), opts.verbosity)?;

    let Ok(Some(patch)) = patches.get(&patch_id) else {
        return Err(Error::NotFound(patch_id));
@@ -700,7 +694,7 @@ where
    // It's ok for the destination reference to be unknown, eg. when pushing a new branch.
    let old = stored.backend.find_reference(dst.as_str()).ok();

-
    push_ref(src, &dst, force, working, stored.raw(), verbosity)?;
+
    push_ref(src, &dst, force, stored.raw(), verbosity)?;

    if let Some(old) = old {
        let proj = stored.project()?;
@@ -881,7 +875,6 @@ fn push_ref(
    src: &git::Oid,
    dst: &git::Namespaced,
    force: bool,
-
    working: &git::raw::Repository,
    stored: &git::raw::Repository,
    verbosity: Verbosity,
) -> Result<(), Error> {
@@ -889,7 +882,6 @@ fn push_ref(
    // Nb. The *force* indicator (`+`) is processed by Git tooling before we even reach this code.
    // This happens during the `list for-push` phase.
    let refspec = git::Refspec { src, dst, force };
-
    let repo = working.workdir().unwrap_or_else(|| working.path());

    let mut args = vec![
        "push".to_string(),