Radish alpha
r
rad:z6cFWeWpnZNHh9rUW8phgA3b5yGt
Git libraries for Radicle
Radicle
Git
Fix surf not showing files in some dirs
Merged did:key:z6Mkm8ky...cKu8 opened 2 months ago

Fixes requesting a directory containing another directory with [brackets] in its name

6 files changed +72 -10 f70012fd b4797686
modified Cargo.lock
@@ -758,6 +758,7 @@ dependencies = [
 "radicle-git-ext-test",
 "radicle-surf",
 "serde_json",
+
 "tempfile",
 "test-helpers",
 "url",
]
modified radicle-surf/src/fs.rs
@@ -114,7 +114,7 @@ impl File {
    ///
    /// The path is relative to the git repository root.
    pub fn path(&self) -> PathBuf {
-
        self.prefix.join(escaped_name(&self.name))
+
        self.prefix.join(&self.name)
    }

    /// Return the [`Path`] where this `File` is located, relative to the
@@ -345,7 +345,7 @@ impl Directory {
    ///
    /// The path is relative to the git repository root.
    pub fn path(&self) -> PathBuf {
-
        self.prefix.join(escaped_name(&self.name))
+
        self.prefix.join(&self.name)
    }

    /// Return the [`Path`] where this `Directory` is located, relative to the
@@ -587,7 +587,7 @@ impl Submodule {
    ///
    /// The path is relative to the git repository root.
    pub fn path(&self) -> PathBuf {
-
        self.prefix.join(escaped_name(&self.name))
+
        self.prefix.join(&self.name)
    }

    /// The object identifier of this `Submodule`.
@@ -603,9 +603,3 @@ impl Submodule {
        &self.url
    }
}
-

-
/// When we need to escape "\" (represented as `\\`) for `PathBuf`
-
/// so that it can be processed correctly.
-
fn escaped_name(name: &str) -> String {
-
    name.replace('\\', r"\\")
-
}
modified radicle-surf/src/repo.rs
@@ -510,6 +510,7 @@ impl Repository {
        let mut opts = git2::DiffOptions::new();
        if let Some(path) = path {
            opts.pathspec(path.to_string_lossy().to_string());
+
            opts.disable_pathspec_match(true);
            opts.skip_binary_check(false);
        }

modified radicle-surf/t/Cargo.toml
@@ -17,6 +17,7 @@ nonempty = "0.5"
pretty_assertions = "1.3.0"
proptest = "1"
serde_json = "1"
+
tempfile = "3"
url = "2.5"

[dev-dependencies.git2]
modified radicle-surf/t/src/file_system.rs
@@ -137,4 +137,69 @@ mod directory {
            "a0dd9122d33dff2a35f564d564db127152c88e02"
        );
    }
+

+
    /// Test that directories and files with glob metacharacters in their names
+
    /// can be browsed and have their history retrieved correctly.
+
    ///
+
    /// This is a regression test for a bug where paths containing `[` were
+
    /// interpreted as glob patterns by git's pathspec, causing errors.
+
    #[test]
+
    fn directory_with_bracket_in_name() {
+
        let tmp = tempfile::tempdir().unwrap();
+
        let repo_path = tmp.path();
+

+
        // Initialize the repo and create test structure:
+
        // src/
+
        //   [special-dir]/
+
        //     file.txt
+
        //   normal-file.txt
+
        let git_repo = git2::Repository::init(repo_path).unwrap();
+

+
        let src_dir = repo_path.join("src");
+
        std::fs::create_dir(&src_dir).unwrap();
+

+
        let special_dir_path = src_dir.join("[special-dir]");
+
        std::fs::create_dir(&special_dir_path).unwrap();
+
        std::fs::write(special_dir_path.join("file.txt"), "hello world").unwrap();
+

+
        std::fs::write(src_dir.join("normal-file.txt"), "normal content").unwrap();
+

+
        let mut index = git_repo.index().unwrap();
+
        index
+
            .add_all(["*"].iter(), git2::IndexAddOption::DEFAULT, None)
+
            .unwrap();
+
        index.write().unwrap();
+
        let tree_id = index.write_tree().unwrap();
+
        let tree = git_repo.find_tree(tree_id).unwrap();
+
        let sig = git2::Signature::now("Test", "test@test.com").unwrap();
+
        git_repo
+
            .commit(Some("HEAD"), &sig, &sig, "Initial commit", &tree, &[])
+
            .unwrap();
+

+
        let repo = Repository::open(repo_path).unwrap();
+
        let branch = Branch::local(refname!("master"));
+
        let root = repo.root_dir(&branch).unwrap();
+

+
        let src = root.find_directory(&"src", &repo).unwrap();
+
        let src_entries: Vec<Entry> = src.entries(&repo).unwrap().collect();
+
        assert_eq!(src_entries.len(), 2);
+

+
        let special_dir = src.find_directory(&"[special-dir]", &repo).unwrap();
+
        assert_eq!(special_dir.name(), "[special-dir]");
+

+
        let dir_path = special_dir.path();
+
        println!("Testing last_commit for dir path: {:?}", dir_path);
+
        let dir_last_commit = repo.last_commit(&dir_path, &branch).unwrap();
+
        assert!(dir_last_commit.is_some(), "Should get last commit for directory with bracket");
+

+
        let file = special_dir.find_file(&"file.txt", &repo).unwrap();
+
        let file_path = file.path();
+
        println!("Testing last_commit for file path: {:?}", file_path);
+
        let file_last_commit = repo.last_commit(&file_path, &branch).unwrap();
+
        assert!(file_last_commit.is_some(), "Should get last commit for file inside bracket dir");
+

+
        let history = repo.history(&branch).unwrap();
+
        let file_history: Vec<_> = history.by_path(&file_path).collect();
+
        assert_eq!(file_history.len(), 1, "Should have 1 commit in history");
+
    }
}
modified radicle-surf/t/src/last_commit.rs
@@ -78,7 +78,7 @@ fn can_get_last_commit_for_special_filenames() {
    let expected_commit_id = Oid::from_str("a0dd9122d33dff2a35f564d564db127152c88e02").unwrap();

    let backslash_commit_id = repo
-
        .last_commit(&r"special/faux\\path", oid)
+
        .last_commit(&"special/faux\\path", oid)
        .expect("Failed to get last commit")
        .map(|commit| commit.id);
    assert_eq!(backslash_commit_id, Some(expected_commit_id));