OXYGENHUB

Clones and remote add store a local path absolute 827281eed2ed

oxy clone ../repo copy recorded the relative path, so fetch, pull and
push from inside the clone looked for it in the wrong place. Local
paths are now stored absolute (file:// kept); http(s) URLs as given.
Test.

closes #57
Author
Andy McCall @andymccall <[email protected]>
When
· 2026-10-02 12:00 UTC
Signature
✔ signed by Andy McCall
Hash
827281eed2edba36efa3786793efd72b79ec415f6643103c6e036e5b13fd50ff
Depends on
5b9c6ad45f6e 750251b21a96 982864068a59 b35df36b7dc5 b3c5a59a875a fce44ae9ad29
Depended on by
9aa399044d9d 8d80356371c5 9f9e72b93e4e a46f3e4f50b1
In bookmarks
agents-in-readme bare-hashes carried-not-removed carry-identical doctor-trust identical-sides keyless-tags main merge-remote-bookmark only-help-103 paths-for-resolutions-and-amend push-notes show-stat subrepo-pin-state switch-says
In tags
v0.10.0 v0.11.0 v0.3.0 v0.3.1 v0.4.0 v0.4.1 v0.4.2 v0.4.3 v0.4.4 v0.4.5 v0.4.6 v0.5.0 v0.5.1 v0.6.0 v0.7.0 v0.8.0 v0.9.0
Edits
6 atoms, 0 tree operations, 4 files

Browse the tree at this change

modified crates/oxy-core/src/protocol.rs +17 −0
…
492 unchanged lines
493 493
    }
494 494
}
495 495
496 +
/// A remote's URL as it is stored: an `http(s)://` URL as given, a local
497 +
/// path made absolute (with its `file://` kept), so it still names the same
498 +
/// repository from inside the clone (oxygen#57).
499 +
pub fn stored_url(url: &str) -> String {
500 +
    if url.starts_with("http://") || url.starts_with("https://") {
501 +
        return url.to_string();
502 +
    }
503 +
    let (prefix, path) = match url.strip_prefix("file://") {
504 +
        Some(p) => ("file://", p),
505 +
        None => ("", url),
506 +
    };
507 +
    match std::path::absolute(path) {
508 +
        Ok(abs) => format!("{prefix}{}", abs.display()),
509 +
        Err(_) => url.to_string(),
510 +
    }
511 +
}
512 +
496 513
/// Open a remote by URL: a local path (optionally `file://`), or `http(s)://`.
497 514
pub fn open_remote(url: &str, options: &RemoteOptions) -> Result<Box<dyn Remote>> {
498 515
    if url.starts_with("http://") || url.starts_with("https://") {
…
689 unchanged lines
modified crates/oxy-core/src/repo/sync.rs +2 −1
…
1824 unchanged lines
1825 1825
            ));
1826 1826
        }
1827 1827
        let mut repo = Repo::init_with_id(dest, id)?;
1828 -
        repo.config.set("remote.origin.url", url)?;
1828 +
        repo.config
1829 +
            .set("remote.origin.url", &crate::protocol::stored_url(url))?;
1829 1830
        if let Some(m) = max_blob {
1830 1831
            repo.config.set("filter.max-blob", &m.to_string())?;
1831 1832
        } else if !sparse.is_empty() {
…
59 unchanged lines
modified crates/oxy-core/src/repo/tests.rs +21 −0
…
6917 unchanged lines
6918 6918
    c.config.set("remote.origin.url", &url).unwrap();
6919 6919
    assert_eq!(c.default_remote(), "origin");
6920 6920
}
6921 +
6922 +
/// oxygen#57: a clone from a relative local path records the remote as an
6923 +
/// absolute path, so fetch still finds it from inside the clone.
6924 +
#[test]
6925 +
fn a_clone_from_a_relative_path_records_it_absolute() {
6926 +
    hermetic();
6927 +
    let dir = tempfile::tempdir().unwrap();
6928 +
    let root = dir.path();
6929 +
    Repo::init(&root.join("origin")).unwrap();
6930 +
    let rel = crate::protocol::stored_url("relative/repo");
6931 +
    assert!(std::path::Path::new(&rel).is_absolute(), "{rel}");
6932 +
    assert_eq!(
6933 +
        crate::protocol::stored_url("https://hub.example/o/n"),
6934 +
        "https://hub.example/o/n"
6935 +
    );
6936 +
    assert!(crate::protocol::stored_url("file://x").starts_with("file:///"));
6937 +
    let url = root.join("origin").to_string_lossy().to_string();
6938 +
    let b = Repo::clone(&url, &root.join("b")).unwrap();
6939 +
    assert_eq!(b.config.remotes["origin"], url);
6940 +
    b.fetch("origin").unwrap();
6941 +
}
modified src/cli/sync.rs +4 −1
…
96 unchanged lines
97 97
98 98
pub fn remote_add(name: &str, url: &str) -> Result<i32> {
99 99
    let mut repo = open()?;
100 -
    repo.config.set(&format!("remote.{name}.url"), url)?;
100 +
    repo.config.set(
101 +
        &format!("remote.{name}.url"),
102 +
        &oxy_core::protocol::stored_url(url),
103 +
    )?;
101 104
    repo.save_config()?;
102 105
    println!(
103 106
        "{} remote {} {} {url}",
…
764 unchanged lines