mirror of
https://seed.radicle.dev/rad:z6cFWeWpnZNHh9rUW8phgA3b5yGt.git
synced 2026-10-24 22:00:38 +08:00
Remove RepositoryRef type and simply use &Repository.
Signed-off-by: Han Xu <keepsimple@gmail.com>
This commit is contained in:
+9
-55
@@ -1,13 +1,16 @@
|
||||
# radicle-surf
|
||||
|
||||
A code surfing library for VCS file systems 🏄♀️🏄♂️
|
||||
A code surfing library for Git repositories 🏄♀️🏄♂️
|
||||
|
||||
Welcome to `radicle-surf`!
|
||||
|
||||
`radicle-surf` is a system to describe a file-system in a VCS world.
|
||||
We have the concept of files and directories, but these objects can change over time while people iterate on them.
|
||||
Thus, it is a file-system within history and we, the user, are viewing the file-system at a particular snapshot.
|
||||
Alongside this, we will wish to take two snapshots and view their differences.
|
||||
`radicle-surf` is a library to describe a Git repository as a file system. It
|
||||
aims to provide an easy-to-use API to browse a repository via the concept of
|
||||
files and directories for any given revision. It also allows the user to diff
|
||||
any two different revisions.
|
||||
|
||||
One of the use cases would be to create a web GUI for interacting with a Git
|
||||
repository (thinking GitHub, GitLab or similar systems).
|
||||
|
||||
## Contributing
|
||||
|
||||
@@ -18,57 +21,8 @@ our [LICENSE](../LICENSE) file.
|
||||
|
||||
Join our community disccussions at [radicle.community](https://radicle.community)!
|
||||
|
||||
|
||||
# Example
|
||||
|
||||
To a taste for the capabilities of `radicle-surf` we provide an example below, but we also
|
||||
keep our documentation and doc-tests up to date.
|
||||
|
||||
```rust
|
||||
use radicle_surf::vcs::git;
|
||||
use radicle_surf::file_system::{Label, Path, SystemType};
|
||||
use radicle_surf::file_system::unsound;
|
||||
use pretty_assertions::assert_eq;
|
||||
use std::str::FromStr;
|
||||
|
||||
// We're going to point to this repo.
|
||||
let repo = git::Repository::new("./data/git-platinum")?;
|
||||
|
||||
// Here we initialise a new Broswer for a the git repo.
|
||||
let mut browser = git::Browser::new(&repo, "master")?;
|
||||
|
||||
// Set the history to a particular commit
|
||||
let commit = git::Oid::from_str("80ded66281a4de2889cc07293a8f10947c6d57fe")?;
|
||||
browser.commit(commit)?;
|
||||
|
||||
// Get the snapshot of the directory for our current HEAD of history.
|
||||
let directory = browser.get_directory()?;
|
||||
|
||||
// Let's get a Path to the memory.rs file
|
||||
let memory = unsound::path::new("src/memory.rs");
|
||||
|
||||
// And assert that we can find it!
|
||||
assert!(directory.find_file(memory).is_some());
|
||||
|
||||
let root_contents = directory.list_directory();
|
||||
|
||||
assert_eq!(root_contents, vec![
|
||||
SystemType::file(unsound::label::new(".i-am-well-hidden")),
|
||||
SystemType::file(unsound::label::new(".i-too-am-hidden")),
|
||||
SystemType::file(unsound::label::new("README.md")),
|
||||
SystemType::directory(unsound::label::new("bin")),
|
||||
SystemType::directory(unsound::label::new("src")),
|
||||
SystemType::directory(unsound::label::new("text")),
|
||||
SystemType::directory(unsound::label::new("this")),
|
||||
]);
|
||||
|
||||
let src = directory
|
||||
.find_directory(Path::new(unsound::label::new("src")))
|
||||
.expect("failed to find src");
|
||||
let src_contents = src.list_directory();
|
||||
|
||||
assert_eq!(src_contents, vec![
|
||||
SystemType::file(unsound::label::new("Eval.hs")),
|
||||
SystemType::file(unsound::label::new("Folder.svelte")),
|
||||
SystemType::file(unsound::label::new("memory.rs")),
|
||||
]);
|
||||
```
|
||||
|
||||
@@ -36,7 +36,7 @@ fn last_commit_comparison(c: &mut Criterion) {
|
||||
.iter()
|
||||
{
|
||||
group.bench_with_input(BenchmarkId::new("", path), path, |b, path| {
|
||||
b.iter(|| repo.as_ref().last_commit(path.clone(), &rev))
|
||||
b.iter(|| repo.last_commit(path.clone(), &rev))
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
use radicle_surf::{
|
||||
file_system::{Directory, DirectoryEntry},
|
||||
git::{Repository, RepositoryRef},
|
||||
git::Repository,
|
||||
};
|
||||
use std::{env, time::Instant};
|
||||
|
||||
@@ -39,7 +39,6 @@ fn main() {
|
||||
},
|
||||
};
|
||||
let repo = Repository::discover(&repo_path).unwrap();
|
||||
let repo = repo.as_ref();
|
||||
let now = Instant::now();
|
||||
let head = repo.head_oid().unwrap();
|
||||
let root = repo.root_dir(head).unwrap();
|
||||
@@ -49,7 +48,7 @@ fn main() {
|
||||
println!("browse with print: {} ms", elapsed_millis);
|
||||
}
|
||||
|
||||
fn print_directory(d: &Directory, repo: &RepositoryRef, indent_level: usize) {
|
||||
fn print_directory(d: &Directory, repo: &Repository, indent_level: usize) {
|
||||
let indent = " ".repeat(indent_level * 4);
|
||||
println!("{}{}/", &indent, d.name());
|
||||
for entry in d.contents(repo).unwrap().iter() {
|
||||
|
||||
@@ -26,13 +26,13 @@ fn main() {
|
||||
let options = get_options_or_exit();
|
||||
let repo = init_repository_or_exit(&options.path_to_repo);
|
||||
let head_oid = match options.head_revision {
|
||||
HeadRevision::Head => repo.as_ref().head_oid().unwrap(),
|
||||
HeadRevision::Head => repo.head_oid().unwrap(),
|
||||
HeadRevision::Commit(id) => Oid::from_str(&id).unwrap(),
|
||||
};
|
||||
let base_oid = Oid::from_str(&options.base_revision).unwrap();
|
||||
let now = Instant::now();
|
||||
let elapsed_nanos = now.elapsed().as_nanos();
|
||||
let diff = repo.as_ref().diff(base_oid, head_oid).unwrap();
|
||||
let diff = repo.diff(base_oid, head_oid).unwrap();
|
||||
print_diff_summary(&diff, elapsed_nanos);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ use serde::{
|
||||
use crate::{
|
||||
diff,
|
||||
file_system,
|
||||
git::{self, glob, Glob, RepositoryRef},
|
||||
git::{self, glob, Glob, Repository},
|
||||
person::Person,
|
||||
revision::Revision,
|
||||
};
|
||||
@@ -146,7 +146,7 @@ pub struct Commits {
|
||||
///
|
||||
/// Will return [`Error`] if the project doesn't exist or the surf interaction
|
||||
/// fails.
|
||||
pub fn commit<R: git::Revision>(repo: &RepositoryRef, rev: R) -> Result<Commit, Error> {
|
||||
pub fn commit<R: git::Revision>(repo: &Repository, rev: R) -> Result<Commit, Error> {
|
||||
let commit = repo.commit(rev)?;
|
||||
let sha1 = commit.id;
|
||||
let header = Header::from(&commit);
|
||||
@@ -216,7 +216,7 @@ pub fn commit<R: git::Revision>(repo: &RepositoryRef, rev: R) -> Result<Commit,
|
||||
///
|
||||
/// Will return [`Error`] if the project doesn't exist or the surf interaction
|
||||
/// fails.
|
||||
pub fn header(repo: &RepositoryRef, sha1: Oid) -> Result<Header, Error> {
|
||||
pub fn header(repo: &Repository, sha1: Oid) -> Result<Header, Error> {
|
||||
let commit = repo.commit(sha1)?;
|
||||
Ok(Header::from(&commit))
|
||||
}
|
||||
@@ -227,7 +227,7 @@ pub fn header(repo: &RepositoryRef, sha1: Oid) -> Result<Header, Error> {
|
||||
///
|
||||
/// Will return [`Error`] if the project doesn't exist or the surf interaction
|
||||
/// fails.
|
||||
pub fn commits(repo: &RepositoryRef, maybe_revision: Option<Revision>) -> Result<Commits, Error> {
|
||||
pub fn commits(repo: &Repository, maybe_revision: Option<Revision>) -> Result<Commits, Error> {
|
||||
let rev = match maybe_revision {
|
||||
Some(revision) => revision,
|
||||
None => Revision::Sha {
|
||||
|
||||
@@ -24,7 +24,7 @@ use serde::{ser, Serialize, Serializer};
|
||||
|
||||
use crate::{
|
||||
file_system::{Directory, Path},
|
||||
git::{Error, RepositoryRef},
|
||||
git::{Error, Repository},
|
||||
};
|
||||
|
||||
pub mod git;
|
||||
@@ -296,7 +296,7 @@ impl Diff {
|
||||
// TODO: Direction of comparison is not obvious with this signature.
|
||||
// For now using conventional approach with the right being "newer".
|
||||
#[allow(clippy::self_named_constructors)]
|
||||
pub fn diff(left: Directory, right: Directory, repo: RepositoryRef) -> Result<Self, Error> {
|
||||
pub fn diff(left: Directory, right: Directory, repo: Repository) -> Result<Self, Error> {
|
||||
// TODO: Some of the deleted files may actually be moved (renamed) to one of the
|
||||
// created files. Finding out which of the deleted files were deleted
|
||||
// and which were moved will probably require performing some variant of
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
use crate::{
|
||||
file_system::{error::LabelError, path::*, Error},
|
||||
git::{self, RepositoryRef, Revision},
|
||||
git::{self, Repository, Revision},
|
||||
};
|
||||
use git2::Blob;
|
||||
use radicle_git_ext::Oid;
|
||||
@@ -130,7 +130,7 @@ impl Directory {
|
||||
}
|
||||
|
||||
/// Returns a `DirectoryContent` for the current directory.
|
||||
pub fn contents(&self, repo: &RepositoryRef) -> Result<DirectoryContent, git::Error> {
|
||||
pub fn contents(&self, repo: &Repository) -> Result<DirectoryContent, git::Error> {
|
||||
let listing = repo.directory_get(self)?;
|
||||
Ok(DirectoryContent { listing })
|
||||
}
|
||||
@@ -139,10 +139,10 @@ impl Directory {
|
||||
pub fn get_path(
|
||||
&self,
|
||||
path: &path::Path,
|
||||
repo: &RepositoryRef,
|
||||
repo: &Repository,
|
||||
) -> Result<DirectoryEntry, git::Error> {
|
||||
// Search the path in git2 tree.
|
||||
let git2_tree = repo.repo_ref.find_tree(self.oid.into())?;
|
||||
let git2_tree = repo.git2_repo().find_tree(self.oid.into())?;
|
||||
let entry = git2_tree.get_path(path)?;
|
||||
|
||||
// Construct the DirectoryEntry.
|
||||
@@ -204,7 +204,7 @@ impl Directory {
|
||||
/// // We shouldn't be able to find a file that doesn't exist
|
||||
/// assert_eq!(directory.find_file(unsound::path::new("foo/bar/qux.rs")), None);
|
||||
/// ```
|
||||
pub fn find_file(&self, path: Path, repo: &RepositoryRef) -> Option<Oid> {
|
||||
pub fn find_file(&self, path: Path, repo: &Repository) -> Option<Oid> {
|
||||
let path_buf: std::path::PathBuf = (&path).into();
|
||||
let entry = match self.get_path(path_buf.as_path(), repo) {
|
||||
Ok(entry) => entry,
|
||||
@@ -252,7 +252,7 @@ impl Directory {
|
||||
/// // 'baz.rs' is a file and not a directory
|
||||
/// assert!(directory.find_directory(unsound::path::new("foo/bar/baz.rs")).is_none());
|
||||
/// ```
|
||||
pub fn find_directory(&self, path: Path, repo: &RepositoryRef) -> Option<Self> {
|
||||
pub fn find_directory(&self, path: Path, repo: &Repository) -> Option<Self> {
|
||||
let path_buf: std::path::PathBuf = (&path).into();
|
||||
let entry = match self.get_path(path_buf.as_path(), repo) {
|
||||
Ok(entry) => entry,
|
||||
@@ -274,7 +274,7 @@ impl Directory {
|
||||
|
||||
/// Get the total size, in bytes, of a `Directory`. The size is
|
||||
/// the sum of all files that can be reached from this `Directory`.
|
||||
pub fn size(&self, repo: &RepositoryRef) -> Result<usize, git::Error> {
|
||||
pub fn size(&self, repo: &Repository) -> Result<usize, git::Error> {
|
||||
let mut size = 0;
|
||||
let contents = self.contents(repo)?;
|
||||
for item in contents.iter() {
|
||||
@@ -295,7 +295,7 @@ impl Directory {
|
||||
impl Revision for Directory {
|
||||
type Error = Infallible;
|
||||
|
||||
fn object_id(&self, _repo: &RepositoryRef) -> Result<Oid, Self::Error> {
|
||||
fn object_id(&self, _repo: &Repository) -> Result<Oid, Self::Error> {
|
||||
Ok(self.oid)
|
||||
}
|
||||
}
|
||||
|
||||
+19
-19
@@ -71,7 +71,7 @@ use git_ref_format::{name::Components, Component, Qualified, RefString};
|
||||
pub use radicle_git_ext::Oid;
|
||||
|
||||
mod repo;
|
||||
pub use repo::{Error, Repository, RepositoryRef};
|
||||
pub use repo::{Error, Repository};
|
||||
|
||||
pub mod glob;
|
||||
pub use glob::Glob;
|
||||
@@ -116,45 +116,45 @@ pub trait Revision {
|
||||
type Error: std::error::Error + Send + Sync + 'static;
|
||||
|
||||
/// Returns the object id of this revision in `repo`.
|
||||
fn object_id(&self, repo: &RepositoryRef) -> Result<Oid, Self::Error>;
|
||||
fn object_id(&self, repo: &Repository) -> Result<Oid, Self::Error>;
|
||||
}
|
||||
|
||||
impl Revision for RefString {
|
||||
type Error = git2::Error;
|
||||
|
||||
fn object_id(&self, repo: &RepositoryRef) -> Result<Oid, Self::Error> {
|
||||
repo.repo_ref.refname_to_id(self.as_str()).map(Oid::from)
|
||||
fn object_id(&self, repo: &Repository) -> Result<Oid, Self::Error> {
|
||||
repo.git2_repo().refname_to_id(self.as_str()).map(Oid::from)
|
||||
}
|
||||
}
|
||||
|
||||
impl Revision for &RefString {
|
||||
type Error = git2::Error;
|
||||
|
||||
fn object_id(&self, repo: &RepositoryRef) -> Result<Oid, Self::Error> {
|
||||
repo.repo_ref.refname_to_id(self.as_str()).map(Oid::from)
|
||||
fn object_id(&self, repo: &Repository) -> Result<Oid, Self::Error> {
|
||||
repo.git2_repo().refname_to_id(self.as_str()).map(Oid::from)
|
||||
}
|
||||
}
|
||||
|
||||
impl Revision for Qualified<'_> {
|
||||
type Error = git2::Error;
|
||||
|
||||
fn object_id(&self, repo: &RepositoryRef) -> Result<Oid, Self::Error> {
|
||||
repo.repo_ref.refname_to_id(self.as_str()).map(Oid::from)
|
||||
fn object_id(&self, repo: &Repository) -> Result<Oid, Self::Error> {
|
||||
repo.git2_repo().refname_to_id(self.as_str()).map(Oid::from)
|
||||
}
|
||||
}
|
||||
|
||||
impl Revision for &Qualified<'_> {
|
||||
type Error = git2::Error;
|
||||
|
||||
fn object_id(&self, repo: &RepositoryRef) -> Result<Oid, Self::Error> {
|
||||
repo.repo_ref.refname_to_id(self.as_str()).map(Oid::from)
|
||||
fn object_id(&self, repo: &Repository) -> Result<Oid, Self::Error> {
|
||||
repo.git2_repo().refname_to_id(self.as_str()).map(Oid::from)
|
||||
}
|
||||
}
|
||||
|
||||
impl Revision for Oid {
|
||||
type Error = Infallible;
|
||||
|
||||
fn object_id(&self, _repo: &RepositoryRef) -> Result<Oid, Self::Error> {
|
||||
fn object_id(&self, _repo: &Repository) -> Result<Oid, Self::Error> {
|
||||
Ok(*self)
|
||||
}
|
||||
}
|
||||
@@ -162,7 +162,7 @@ impl Revision for Oid {
|
||||
impl Revision for &str {
|
||||
type Error = git2::Error;
|
||||
|
||||
fn object_id(&self, _repo: &RepositoryRef) -> Result<Oid, Self::Error> {
|
||||
fn object_id(&self, _repo: &Repository) -> Result<Oid, Self::Error> {
|
||||
Oid::from_str(self).map(Oid::from)
|
||||
}
|
||||
}
|
||||
@@ -170,16 +170,16 @@ impl Revision for &str {
|
||||
impl Revision for &Branch {
|
||||
type Error = Error;
|
||||
|
||||
fn object_id(&self, repo: &RepositoryRef) -> Result<Oid, Self::Error> {
|
||||
fn object_id(&self, repo: &Repository) -> Result<Oid, Self::Error> {
|
||||
let refname = repo.namespaced_refname(&self.refname())?;
|
||||
Ok(repo.repo_ref.refname_to_id(&refname).map(Oid::from)?)
|
||||
Ok(repo.git2_repo().refname_to_id(&refname).map(Oid::from)?)
|
||||
}
|
||||
}
|
||||
|
||||
impl Revision for &Tag {
|
||||
type Error = Infallible;
|
||||
|
||||
fn object_id(&self, _repo: &RepositoryRef) -> Result<Oid, Self::Error> {
|
||||
fn object_id(&self, _repo: &Repository) -> Result<Oid, Self::Error> {
|
||||
Ok(self.id())
|
||||
}
|
||||
}
|
||||
@@ -189,13 +189,13 @@ pub trait ToCommit {
|
||||
type Error: std::error::Error + Send + Sync + 'static;
|
||||
|
||||
/// Converts to a commit in `repo`.
|
||||
fn to_commit(self, repo: &RepositoryRef) -> Result<Commit, Self::Error>;
|
||||
fn to_commit(self, repo: &Repository) -> Result<Commit, Self::Error>;
|
||||
}
|
||||
|
||||
impl ToCommit for Commit {
|
||||
type Error = Infallible;
|
||||
|
||||
fn to_commit(self, _repo: &RepositoryRef) -> Result<Commit, Self::Error> {
|
||||
fn to_commit(self, _repo: &Repository) -> Result<Commit, Self::Error> {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
@@ -203,9 +203,9 @@ impl ToCommit for Commit {
|
||||
impl<R: Revision> ToCommit for R {
|
||||
type Error = Error;
|
||||
|
||||
fn to_commit(self, repo: &RepositoryRef) -> Result<Commit, Self::Error> {
|
||||
fn to_commit(self, repo: &Repository) -> Result<Commit, Self::Error> {
|
||||
let oid = repo.object_id(&self)?;
|
||||
let commit = repo.repo_ref.find_commit(oid.into())?;
|
||||
let commit = repo.git2_repo().find_commit(oid.into())?;
|
||||
Ok(Commit::try_from(commit)?)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,14 +17,14 @@
|
||||
|
||||
use crate::{
|
||||
file_system,
|
||||
git::{Commit, Error, RepositoryRef, ToCommit},
|
||||
git::{Commit, Error, Repository, ToCommit},
|
||||
};
|
||||
use std::convert::TryFrom;
|
||||
|
||||
/// An iterator that produces the history of commits for a given `head`,
|
||||
/// in the `repo`.
|
||||
pub struct History<'a> {
|
||||
repo: RepositoryRef<'a>,
|
||||
repo: &'a Repository,
|
||||
head: Commit,
|
||||
revwalk: git2::Revwalk<'a>,
|
||||
filter_by: Option<FilterBy>,
|
||||
@@ -37,11 +37,11 @@ enum FilterBy {
|
||||
|
||||
impl<'a> History<'a> {
|
||||
/// Creates a new history starting from `head`, in `repo`.
|
||||
pub fn new<C: ToCommit>(repo: RepositoryRef<'a>, head: C) -> Result<Self, Error> {
|
||||
pub fn new<C: ToCommit>(repo: &'a Repository, head: C) -> Result<Self, Error> {
|
||||
let head = head
|
||||
.to_commit(&repo)
|
||||
.to_commit(repo)
|
||||
.map_err(|err| Error::ToCommit(err.into()))?;
|
||||
let mut revwalk = repo.repo_ref.revwalk()?;
|
||||
let mut revwalk = repo.git2_repo().revwalk()?;
|
||||
revwalk.push(head.id.into())?;
|
||||
let history = Self {
|
||||
repo,
|
||||
@@ -76,7 +76,7 @@ impl<'a> Iterator for History<'a> {
|
||||
let found = oid
|
||||
.map_err(Error::Git)
|
||||
.and_then(|oid| {
|
||||
let git2_commit = self.repo.repo_ref.find_commit(oid)?;
|
||||
let git2_commit = self.repo.git2_repo().find_commit(oid)?;
|
||||
|
||||
// Handles the optional filter_by.
|
||||
if let Some(FilterBy::File { path }) = &self.filter_by {
|
||||
|
||||
@@ -99,36 +99,14 @@ pub enum Error {
|
||||
/// Wrapper around the `git2`'s `git2::Repository` type.
|
||||
/// This is to to limit the functionality that we can do
|
||||
/// on the underlying object.
|
||||
pub struct Repository(pub(super) git2::Repository);
|
||||
|
||||
/// A reference-only `Repository`. This means that we cannot mutate the
|
||||
/// underlying `Repository`. Not being able to mutate the `Repository` means
|
||||
/// that the functions defined for `RepositoryRef` should be thread-safe.
|
||||
///
|
||||
/// # Construction
|
||||
///
|
||||
/// Use the `From<&'a git2::Repository>` implementation to construct a
|
||||
/// `RepositoryRef`.
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct RepositoryRef<'a> {
|
||||
pub(crate) repo_ref: &'a git2::Repository,
|
||||
pub struct Repository {
|
||||
inner: git2::Repository,
|
||||
}
|
||||
|
||||
// RepositoryRef should be safe to transfer across thread boundaries since it
|
||||
// only holds a reference to git2::Repository. git2::Repository is also Send
|
||||
// (see: https://docs.rs/git2/0.13.5/src/git2/repo.rs.html#46)
|
||||
unsafe impl<'a> Send for RepositoryRef<'a> {}
|
||||
|
||||
impl<'a> From<&'a git2::Repository> for RepositoryRef<'a> {
|
||||
fn from(repo_ref: &'a git2::Repository) -> Self {
|
||||
RepositoryRef { repo_ref }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> RepositoryRef<'a> {
|
||||
impl Repository {
|
||||
/// What is the current namespace we're browsing in.
|
||||
pub fn which_namespace(&self) -> Result<Option<Namespace>, Error> {
|
||||
self.repo_ref
|
||||
self.inner
|
||||
.namespace_bytes()
|
||||
.map(|ns| Namespace::try_from(ns).map_err(Error::from))
|
||||
.transpose()
|
||||
@@ -139,7 +117,7 @@ impl<'a> RepositoryRef<'a> {
|
||||
let mut branches = Branches::default();
|
||||
for glob in pattern.globs() {
|
||||
let namespaced = self.namespaced_pattern(glob)?;
|
||||
let references = self.repo_ref.references_glob(&namespaced)?;
|
||||
let references = self.inner.references_glob(&namespaced)?;
|
||||
branches.push(references);
|
||||
}
|
||||
Ok(branches)
|
||||
@@ -150,7 +128,7 @@ impl<'a> RepositoryRef<'a> {
|
||||
let mut tags = Tags::default();
|
||||
for glob in pattern.globs() {
|
||||
let namespaced = self.namespaced_pattern(glob)?;
|
||||
let references = self.repo_ref.references_glob(&namespaced)?;
|
||||
let references = self.inner.references_glob(&namespaced)?;
|
||||
tags.push(references);
|
||||
}
|
||||
Ok(tags)
|
||||
@@ -161,7 +139,7 @@ impl<'a> RepositoryRef<'a> {
|
||||
let mut set = BTreeSet::new();
|
||||
for glob in pattern.globs() {
|
||||
let new_set = self
|
||||
.repo_ref
|
||||
.inner
|
||||
.references_glob(glob)?
|
||||
.map(|reference| {
|
||||
reference
|
||||
@@ -202,7 +180,7 @@ impl<'a> RepositoryRef<'a> {
|
||||
|
||||
/// Parse an [`Oid`] from the given string.
|
||||
pub fn oid(&self, oid: &str) -> Result<Oid, Error> {
|
||||
Ok(self.repo_ref.revparse_single(oid)?.id().into())
|
||||
Ok(self.inner.revparse_single(oid)?.id().into())
|
||||
}
|
||||
|
||||
/// Returns a top level `Directory` without nested sub-directories.
|
||||
@@ -213,7 +191,7 @@ impl<'a> RepositoryRef<'a> {
|
||||
let commit = commit
|
||||
.to_commit(self)
|
||||
.map_err(|err| Error::ToCommit(err.into()))?;
|
||||
let git2_commit = self.repo_ref.find_commit((commit.id).into())?;
|
||||
let git2_commit = self.inner.find_commit((commit.id).into())?;
|
||||
let tree = git2_commit.as_object().peel_to_tree()?;
|
||||
Ok(Directory {
|
||||
name: Label::root(),
|
||||
@@ -226,7 +204,7 @@ impl<'a> RepositoryRef<'a> {
|
||||
&self,
|
||||
d: &Directory,
|
||||
) -> Result<BTreeMap<Label, DirectoryEntry>, Error> {
|
||||
let git2_tree = self.repo_ref.find_tree(d.oid.into())?;
|
||||
let git2_tree = self.inner.find_tree(d.oid.into())?;
|
||||
let map = self.tree_first_level(git2_tree)?;
|
||||
Ok(map)
|
||||
}
|
||||
@@ -312,13 +290,13 @@ impl<'a> RepositoryRef<'a> {
|
||||
|
||||
/// Obtain the file content
|
||||
pub(crate) fn file_content(&self, object_id: Oid) -> Result<FileContent, Error> {
|
||||
let blob = self.repo_ref.find_blob(object_id.into())?;
|
||||
let blob = self.inner.find_blob(object_id.into())?;
|
||||
Ok(FileContent::new(blob))
|
||||
}
|
||||
|
||||
/// Return the size of a file
|
||||
pub(crate) fn file_size(&self, oid: Oid) -> Result<usize, Error> {
|
||||
let blob = self.repo_ref.find_blob(oid.into())?;
|
||||
let blob = self.inner.find_blob(oid.into())?;
|
||||
Ok(blob.size())
|
||||
}
|
||||
|
||||
@@ -332,7 +310,7 @@ impl<'a> RepositoryRef<'a> {
|
||||
let commit = self.get_git2_commit(id)?;
|
||||
let tree = commit.tree()?;
|
||||
let entry = tree.get_path(PathBuf::from(&path).as_ref())?;
|
||||
let object = entry.to_object(self.repo_ref)?;
|
||||
let object = entry.to_object(self.git2_repo())?;
|
||||
let blob = object.into_blob().map_err(|_| Error::PathNotFound(path))?;
|
||||
Ok(FileContent::new(blob))
|
||||
}
|
||||
@@ -349,18 +327,18 @@ impl<'a> RepositoryRef<'a> {
|
||||
|
||||
/// Returns the Oid of the current HEAD
|
||||
pub fn head_oid(&self) -> Result<Oid, Error> {
|
||||
let head = self.repo_ref.head()?;
|
||||
let head = self.inner.head()?;
|
||||
let head_commit = head.peel_to_commit()?;
|
||||
Ok(head_commit.id().into())
|
||||
}
|
||||
|
||||
/// Switch to a `namespace`
|
||||
pub fn switch_namespace(&self, namespace: &str) -> Result<(), Error> {
|
||||
Ok(self.repo_ref.set_namespace(namespace)?)
|
||||
Ok(self.inner.set_namespace(namespace)?)
|
||||
}
|
||||
|
||||
/// Returns a full reference name with namespace(s) included.
|
||||
pub(crate) fn namespaced_refname(
|
||||
pub(crate) fn namespaced_refname<'a>(
|
||||
&'a self,
|
||||
refname: &Qualified<'a>,
|
||||
) -> Result<Qualified<'a>, Error> {
|
||||
@@ -372,7 +350,7 @@ impl<'a> RepositoryRef<'a> {
|
||||
}
|
||||
|
||||
/// Returns a full reference name with namespace(s) included.
|
||||
pub(crate) fn namespaced_pattern(
|
||||
pub(crate) fn namespaced_pattern<'a>(
|
||||
&'a self,
|
||||
refname: &QualifiedPattern<'a>,
|
||||
) -> Result<QualifiedPattern<'a>, Error> {
|
||||
@@ -385,7 +363,7 @@ impl<'a> RepositoryRef<'a> {
|
||||
|
||||
/// Get a particular `git2::Commit` of `oid`.
|
||||
pub(crate) fn get_git2_commit(&self, oid: Oid) -> Result<git2::Commit, Error> {
|
||||
self.repo_ref.find_commit(oid.into()).map_err(Error::Git)
|
||||
self.inner.find_commit(oid.into()).map_err(Error::Git)
|
||||
}
|
||||
|
||||
/// Extract the signature from a commit
|
||||
@@ -404,7 +382,7 @@ impl<'a> RepositoryRef<'a> {
|
||||
// git_commit_extract_signature at
|
||||
// https://libgit2.org/libgit2/#HEAD/group/commit/git_commit_extract_signature
|
||||
// the return value for a commit without a signature will be GIT_ENOTFOUND
|
||||
match self.repo_ref.extract_signature(commit_oid, field) {
|
||||
match self.inner.extract_signature(commit_oid, field) {
|
||||
Err(error) => {
|
||||
if error.code() == git2::ErrorCode::NotFound {
|
||||
Ok(None)
|
||||
@@ -422,7 +400,7 @@ impl<'a> RepositoryRef<'a> {
|
||||
for branch in self.branches(&glob)? {
|
||||
let branch = branch?;
|
||||
let namespaced = self.namespaced_refname(&branch.refname())?;
|
||||
let reference = self.repo_ref.find_reference(namespaced.as_str())?;
|
||||
let reference = self.inner.find_reference(namespaced.as_str())?;
|
||||
if self.reachable_from(&reference, oid)? {
|
||||
contained_branches.push(branch);
|
||||
}
|
||||
@@ -434,7 +412,7 @@ impl<'a> RepositoryRef<'a> {
|
||||
fn reachable_from(&self, reference: &git2::Reference, oid: &Oid) -> Result<bool, Error> {
|
||||
let git2_oid = (*oid).into();
|
||||
let other = reference.peel_to_commit()?.id();
|
||||
let is_descendant = self.repo_ref.graph_descendant_of(other, git2_oid)?;
|
||||
let is_descendant = self.inner.graph_descendant_of(other, git2_oid)?;
|
||||
|
||||
Ok(other == git2_oid || is_descendant)
|
||||
}
|
||||
@@ -471,7 +449,7 @@ impl<'a> RepositoryRef<'a> {
|
||||
}
|
||||
|
||||
let mut diff =
|
||||
self.repo_ref
|
||||
self.inner
|
||||
.diff_tree_to_tree(old_tree.as_ref(), Some(&new_tree), Some(&mut opts))?;
|
||||
|
||||
// Detect renames by default.
|
||||
@@ -484,57 +462,39 @@ impl<'a> RepositoryRef<'a> {
|
||||
|
||||
/// Returns the history with the `head` commit.
|
||||
pub fn history<C: ToCommit>(&self, head: C) -> Result<History, Error> {
|
||||
History::new(*self, head)
|
||||
History::new(self, head)
|
||||
}
|
||||
|
||||
pub(super) fn object_id<R: Revision>(&self, r: &R) -> Result<Oid, Error> {
|
||||
r.object_id(self).map_err(|err| Error::Revision(err.into()))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> std::fmt::Debug for RepositoryRef<'a> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, ".git")
|
||||
}
|
||||
}
|
||||
|
||||
impl Repository {
|
||||
/// Open a git repository given its exact URI.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// * [`Error::Git`]
|
||||
pub fn open(repo_uri: impl AsRef<std::path::Path>) -> Result<Self, Error> {
|
||||
git2::Repository::open(repo_uri)
|
||||
.map(Repository)
|
||||
.map_err(Error::from)
|
||||
let repo = git2::Repository::open(repo_uri)?;
|
||||
Ok(Self { inner: repo })
|
||||
}
|
||||
|
||||
/// Attempt to open a git repository at or above `repo_uri` in the file
|
||||
/// system.
|
||||
pub fn discover(repo_uri: impl AsRef<std::path::Path>) -> Result<Self, Error> {
|
||||
git2::Repository::discover(repo_uri)
|
||||
.map(Repository)
|
||||
.map_err(Error::from)
|
||||
let repo = git2::Repository::discover(repo_uri)?;
|
||||
Ok(Self { inner: repo })
|
||||
}
|
||||
|
||||
/// Since our operations are read-only when it comes to surfing a repository
|
||||
/// we have a separate struct called [`RepositoryRef`]. This turns an owned
|
||||
/// [`Repository`] into a [`RepositoryRef`].
|
||||
pub fn as_ref(&'_ self) -> RepositoryRef<'_> {
|
||||
RepositoryRef { repo_ref: &self.0 }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a Repository> for RepositoryRef<'a> {
|
||||
fn from(repo: &'a Repository) -> Self {
|
||||
repo.as_ref()
|
||||
/// Get a reference to the underlying git2 repo.
|
||||
pub(crate) fn git2_repo(&self) -> &git2::Repository {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
|
||||
impl From<git2::Repository> for Repository {
|
||||
fn from(repo: git2::Repository) -> Self {
|
||||
Repository(repo)
|
||||
Repository { inner: repo }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+12
-18
@@ -1,5 +1,5 @@
|
||||
// This file is part of radicle-surf
|
||||
// <https://github.com/radicle-dev/radicle-surf>
|
||||
// This file is part of radicle-git
|
||||
// <https://github.com/radicle-dev/radicle-git>
|
||||
//
|
||||
// Copyright (C) 2019-2020 The Radicle Team <dev@radicle.xyz>
|
||||
//
|
||||
@@ -17,17 +17,18 @@
|
||||
|
||||
//! Welcome to `radicle-surf`!
|
||||
//!
|
||||
//! `radicle-surf` is a system to describe a file-system in a VCS world.
|
||||
//! We have the concept of files and directories, but these objects can change
|
||||
//! over time while people iterate on them. Thus, it is a file-system within
|
||||
//! history and we, the user, are viewing the file-system at a particular
|
||||
//! snapshot. Alongside this, we will wish to take two snapshots and view their
|
||||
//! differences.
|
||||
//! `radicle-surf` is a library to describe a Git repository as a file system.
|
||||
//! It aims to provide an easy-to-use API to browse a repository via the concept
|
||||
//! of files and directories for any given revision. It also allows the user to
|
||||
//! diff any two different revisions.
|
||||
//!
|
||||
//! One of the use cases would be to create a web GUI for interacting with a Git
|
||||
//! repository (thinking GitHub, GitLab or similar systems).
|
||||
//!
|
||||
//! Let's start surfing (and apologies for the `expect`s):
|
||||
//!
|
||||
//! ```
|
||||
//! use radicle_surf::vcs::git;
|
||||
//! use radicle_surf::git;
|
||||
//! use radicle_surf::file_system::{Label, Path, SystemType};
|
||||
//! use radicle_surf::file_system::unsound;
|
||||
//! use pretty_assertions::assert_eq;
|
||||
@@ -36,17 +37,10 @@
|
||||
//!
|
||||
//! # fn main() -> Result<(), Box<dyn Error>> {
|
||||
//! // We're going to point to this repo.
|
||||
//! let repo = git::Repository::new("./data/git-platinum")?;
|
||||
//!
|
||||
//! // Here we initialise a new Broswer for a the git repo.
|
||||
//! let mut browser = git::Browser::new(&repo, git::Branch::local("master"))?;
|
||||
//!
|
||||
//! // Set the history to a particular commit
|
||||
//! let commit = git::Oid::from_str("80ded66281a4de2889cc07293a8f10947c6d57fe")?;
|
||||
//! browser.commit(commit)?;
|
||||
//! let repo = git::Repository::open("./data/git-platinum")?;
|
||||
//!
|
||||
//! // Get the snapshot of the directory for our current HEAD of history.
|
||||
//! let directory = browser.get_directory()?;
|
||||
//! let directory = repo.root_dir("80ded66281a4de2889cc07293a8f10947c6d57fe")?;
|
||||
//!
|
||||
//! // Let's get a Path to the memory.rs file
|
||||
//! let memory = unsound::path::new("src/memory.rs");
|
||||
|
||||
@@ -29,7 +29,7 @@ use serde::{
|
||||
use crate::{
|
||||
commit,
|
||||
file_system,
|
||||
git::RepositoryRef,
|
||||
git::Repository,
|
||||
object::{Error, Info, ObjectType},
|
||||
revision::Revision,
|
||||
};
|
||||
@@ -115,7 +115,7 @@ impl Serialize for BlobContent {
|
||||
/// Will return [`Error`] if the project doesn't exist or a surf interaction
|
||||
/// fails.
|
||||
pub fn blob(
|
||||
repo: &RepositoryRef,
|
||||
repo: &Repository,
|
||||
maybe_revision: Option<Revision>,
|
||||
path: &str,
|
||||
) -> Result<Blob, Error> {
|
||||
@@ -123,7 +123,7 @@ pub fn blob(
|
||||
}
|
||||
|
||||
fn make_blob<C>(
|
||||
repo: &RepositoryRef,
|
||||
repo: &Repository,
|
||||
maybe_revision: Option<Revision>,
|
||||
path: &str,
|
||||
content: C,
|
||||
|
||||
@@ -30,7 +30,7 @@ use serde::{
|
||||
use crate::{
|
||||
commit,
|
||||
file_system::{self, DirectoryEntry},
|
||||
git::RepositoryRef,
|
||||
git::Repository,
|
||||
object::{Error, Info, ObjectType},
|
||||
revision::Revision,
|
||||
};
|
||||
@@ -87,7 +87,7 @@ impl Serialize for TreeEntry {
|
||||
///
|
||||
/// Will return [`Error`] if any of the surf interactions fail.
|
||||
pub fn tree(
|
||||
repo: &RepositoryRef,
|
||||
repo: &Repository,
|
||||
maybe_revision: Option<Revision>,
|
||||
maybe_prefix: Option<String>,
|
||||
) -> Result<Tree, Error> {
|
||||
|
||||
@@ -26,7 +26,7 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use radicle_git_ext::Oid;
|
||||
|
||||
use crate::git::{self, Error, Glob, RepositoryRef};
|
||||
use crate::git::{self, Error, Glob, Repository};
|
||||
|
||||
/// Types of a peer.
|
||||
pub enum Category<P, U> {
|
||||
@@ -79,7 +79,7 @@ pub enum Revision {
|
||||
impl git::Revision for &Revision {
|
||||
type Error = git2::Error;
|
||||
|
||||
fn object_id(&self, repo: &RepositoryRef) -> Result<Oid, Self::Error> {
|
||||
fn object_id(&self, repo: &Repository) -> Result<Oid, Self::Error> {
|
||||
match self {
|
||||
Revision::Tag { name } => match name.qualified() {
|
||||
None => Qualified::from(lit::refs_tags(name)).object_id(repo),
|
||||
@@ -118,7 +118,7 @@ pub struct Revisions<P, U> {
|
||||
/// # Errors
|
||||
///
|
||||
/// * If we cannot get the branches from the `Browser`
|
||||
pub fn remote<P, U>(repo: &RepositoryRef, peer_id: P, user: U) -> Result<Revisions<P, U>, Error>
|
||||
pub fn remote<P, U>(repo: &Repository, peer_id: P, user: U) -> Result<Revisions<P, U>, Error>
|
||||
where
|
||||
P: Clone + ToString,
|
||||
{
|
||||
@@ -144,7 +144,7 @@ where
|
||||
/// # Errors
|
||||
///
|
||||
/// * If we cannot get the branches from the `Browser`
|
||||
pub fn local<P, U>(repo: &RepositoryRef, peer_id: P, user: U) -> Result<Revisions<P, U>, Error>
|
||||
pub fn local<P, U>(repo: &Repository, peer_id: P, user: U) -> Result<Revisions<P, U>, Error>
|
||||
where
|
||||
P: Clone + ToString,
|
||||
{
|
||||
@@ -175,7 +175,7 @@ where
|
||||
/// # Errors
|
||||
///
|
||||
/// * If we cannot get the branches from the `Browser`
|
||||
pub fn revisions<P, U>(repo: &RepositoryRef, peer: Category<P, U>) -> Result<Revisions<P, U>, Error>
|
||||
pub fn revisions<P, U>(repo: &Repository, peer: Category<P, U>) -> Result<Revisions<P, U>, Error>
|
||||
where
|
||||
P: Clone + ToString,
|
||||
{
|
||||
|
||||
@@ -42,7 +42,6 @@ mod directory {
|
||||
#[test]
|
||||
fn directory_get_path() {
|
||||
let repo = Repository::open(GIT_PLATINUM).unwrap();
|
||||
let repo = repo.as_ref();
|
||||
let root = repo.root_dir(&Branch::local(refname!("master"))).unwrap();
|
||||
|
||||
// get_path for a file.
|
||||
@@ -79,7 +78,6 @@ mod directory {
|
||||
#[test]
|
||||
fn directory_size() {
|
||||
let repo = Repository::open(GIT_PLATINUM).unwrap();
|
||||
let repo = repo.as_ref();
|
||||
let root = repo.root_dir(&Branch::local(refname!("master"))).unwrap();
|
||||
|
||||
/*
|
||||
|
||||
@@ -20,9 +20,7 @@ fn test_submodule_failure() {
|
||||
use git_ref_format::refname;
|
||||
|
||||
let repo = Repository::discover(".").unwrap();
|
||||
repo.as_ref()
|
||||
.root_dir(&Branch::local(refname!("main")))
|
||||
.unwrap();
|
||||
repo.root_dir(&Branch::local(refname!("main"))).unwrap();
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -34,7 +32,6 @@ mod namespace {
|
||||
#[test]
|
||||
fn switch_to_banana() -> Result<(), Error> {
|
||||
let repo = Repository::open(GIT_PLATINUM)?;
|
||||
let repo = repo.as_ref();
|
||||
let history_master = repo.history(&Branch::local(refname!("master")))?;
|
||||
repo.switch_namespace("golden")?;
|
||||
let history_banana = repo.history(&Branch::local(refname!("banana")))?;
|
||||
@@ -47,7 +44,6 @@ mod namespace {
|
||||
#[test]
|
||||
fn me_namespace() -> Result<(), Error> {
|
||||
let repo = Repository::open(GIT_PLATINUM)?;
|
||||
let repo = repo.as_ref();
|
||||
let history = repo.history(&Branch::local(refname!("master")))?;
|
||||
|
||||
assert_eq!(repo.which_namespace().unwrap(), None);
|
||||
@@ -83,7 +79,6 @@ mod namespace {
|
||||
#[test]
|
||||
fn golden_namespace() -> Result<(), Error> {
|
||||
let repo = Repository::open(GIT_PLATINUM)?;
|
||||
let repo = repo.as_ref();
|
||||
let history = repo.history(&Branch::local(refname!("master")))?;
|
||||
|
||||
assert_eq!(repo.which_namespace().unwrap(), None);
|
||||
@@ -127,7 +122,6 @@ mod namespace {
|
||||
#[test]
|
||||
fn silver_namespace() -> Result<(), Error> {
|
||||
let repo = Repository::open(GIT_PLATINUM)?;
|
||||
let repo = repo.as_ref();
|
||||
let history = repo.history(&Branch::local(refname!("master")))?;
|
||||
|
||||
assert_eq!(repo.which_namespace().unwrap(), None);
|
||||
@@ -173,7 +167,6 @@ mod rev {
|
||||
#[test]
|
||||
fn _master() -> Result<(), Error> {
|
||||
let repo = Repository::open(GIT_PLATINUM)?;
|
||||
let repo = repo.as_ref();
|
||||
let mut history =
|
||||
repo.history(&Branch::remote(component!("origin"), refname!("master")))?;
|
||||
|
||||
@@ -199,7 +192,6 @@ mod rev {
|
||||
#[test]
|
||||
fn commit() -> Result<(), Error> {
|
||||
let repo = Repository::open(GIT_PLATINUM)?;
|
||||
let repo = repo.as_ref();
|
||||
let rev = Oid::from_str("3873745c8f6ffb45c990eb23b491d4b4b6182f95")?;
|
||||
let mut history = repo.history(rev)?;
|
||||
|
||||
@@ -212,7 +204,6 @@ mod rev {
|
||||
#[test]
|
||||
fn commit_parents() -> Result<(), Error> {
|
||||
let repo = Repository::open(GIT_PLATINUM)?;
|
||||
let repo = repo.as_ref();
|
||||
let rev = Oid::from_str("3873745c8f6ffb45c990eb23b491d4b4b6182f95")?;
|
||||
let history = repo.history(rev)?;
|
||||
let commit = history.head();
|
||||
@@ -228,7 +219,6 @@ mod rev {
|
||||
#[test]
|
||||
fn commit_short() -> Result<(), Error> {
|
||||
let repo = Repository::open(GIT_PLATINUM)?;
|
||||
let repo = repo.as_ref();
|
||||
let rev = repo.oid("3873745c8")?;
|
||||
let mut history = repo.history(rev)?;
|
||||
|
||||
@@ -241,7 +231,6 @@ mod rev {
|
||||
#[test]
|
||||
fn tag() -> Result<(), Error> {
|
||||
let repo = Repository::open(GIT_PLATINUM)?;
|
||||
let repo = repo.as_ref();
|
||||
let rev = refname!("refs/tags/v0.2.0");
|
||||
let history = repo.history(&rev)?;
|
||||
|
||||
@@ -268,7 +257,6 @@ mod last_commit {
|
||||
|
||||
// memory.rs is commited later so it should not exist here.
|
||||
let memory_last_commit_oid = repo
|
||||
.as_ref()
|
||||
.last_commit(
|
||||
Path::with_root(&[unsound::label::new("src"), unsound::label::new("memory.rs")]),
|
||||
oid,
|
||||
@@ -280,7 +268,6 @@ mod last_commit {
|
||||
|
||||
// README.md exists in this commit.
|
||||
let readme_last_commit = repo
|
||||
.as_ref()
|
||||
.last_commit(Path::with_root(&[unsound::label::new("README.md")]), oid)
|
||||
.expect("Failed to get last commit")
|
||||
.map(|commit| commit.id);
|
||||
@@ -299,7 +286,6 @@ mod last_commit {
|
||||
let expected_commit_id = Oid::from_str("f3a089488f4cfd1a240a9c01b3fcc4c34a4e97b2").unwrap();
|
||||
|
||||
let folder_svelte = repo
|
||||
.as_ref()
|
||||
.last_commit(unsound::path::new("~/examples/Folder.svelte"), oid)
|
||||
.expect("Failed to get last commit")
|
||||
.map(|commit| commit.id);
|
||||
@@ -318,7 +304,6 @@ mod last_commit {
|
||||
let expected_commit_id = Oid::from_str("2429f097664f9af0c5b7b389ab998b2199ffa977").unwrap();
|
||||
|
||||
let nested_directory_tree_commit_id = repo
|
||||
.as_ref()
|
||||
.last_commit(
|
||||
unsound::path::new("~/this/is/a/really/deeply/nested/directory/tree"),
|
||||
oid,
|
||||
@@ -342,14 +327,12 @@ mod last_commit {
|
||||
let expected_commit_id = Oid::from_str("a0dd9122d33dff2a35f564d564db127152c88e02").unwrap();
|
||||
|
||||
let backslash_commit_id = repo
|
||||
.as_ref()
|
||||
.last_commit(unsound::path::new("~/special/faux\\path"), oid)
|
||||
.expect("Failed to get last commit")
|
||||
.map(|commit| commit.id);
|
||||
assert_eq!(backslash_commit_id, Some(expected_commit_id));
|
||||
|
||||
let ogre_commit_id = repo
|
||||
.as_ref()
|
||||
.last_commit(unsound::path::new("~/special/👹👹👹"), oid)
|
||||
.expect("Failed to get last commit")
|
||||
.map(|commit| commit.id);
|
||||
@@ -362,13 +345,11 @@ mod last_commit {
|
||||
.expect("Could not retrieve ./data/git-platinum as git repository");
|
||||
let rev = Branch::local(refname!("master"));
|
||||
let root_last_commit_id = repo
|
||||
.as_ref()
|
||||
.last_commit(Path::root(), &rev)
|
||||
.expect("Failed to get last commit")
|
||||
.map(|commit| commit.id);
|
||||
|
||||
let expected_oid = repo
|
||||
.as_ref()
|
||||
.history(&Branch::local(refname!("master")))
|
||||
.unwrap()
|
||||
.head()
|
||||
@@ -380,7 +361,6 @@ mod last_commit {
|
||||
fn binary_file() {
|
||||
let repo = Repository::open(GIT_PLATINUM)
|
||||
.expect("Could not retrieve ./data/git-platinum as git repository");
|
||||
let repo = repo.as_ref();
|
||||
let history = repo.history(&Branch::local(refname!("dev"))).unwrap();
|
||||
let file_commit = history.by_path(unsound::path::new("~/bin/cat")).next();
|
||||
assert!(file_commit.is_some());
|
||||
@@ -398,7 +378,6 @@ mod diff {
|
||||
#[test]
|
||||
fn test_initial_diff() -> Result<(), Error> {
|
||||
let repo = Repository::open(GIT_PLATINUM)?;
|
||||
let repo = repo.as_ref();
|
||||
let oid = Oid::from_str("d3464e33d75c75c99bfb90fa2e9d16efc0b7d0e3")?;
|
||||
let commit = repo.commit(oid).unwrap();
|
||||
assert!(commit.parents.is_empty());
|
||||
@@ -433,7 +412,6 @@ mod diff {
|
||||
#[test]
|
||||
fn test_diff_of_rev() -> Result<(), Error> {
|
||||
let repo = Repository::open(GIT_PLATINUM)?;
|
||||
let repo = repo.as_ref();
|
||||
let diff = repo.diff_from_parent("80bacafba303bf0cdf6142921f430ff265f25095")?;
|
||||
assert_eq!(diff.created.len(), 0);
|
||||
assert_eq!(diff.deleted.len(), 0);
|
||||
@@ -445,7 +423,6 @@ mod diff {
|
||||
#[test]
|
||||
fn test_diff() -> Result<(), Error> {
|
||||
let repo = Repository::open(GIT_PLATINUM)?;
|
||||
let repo = repo.as_ref();
|
||||
let oid = "80bacafba303bf0cdf6142921f430ff265f25095";
|
||||
let commit = repo.commit(oid).unwrap();
|
||||
let parent_oid = commit.parents.get(0).unwrap();
|
||||
@@ -479,7 +456,6 @@ mod diff {
|
||||
#[test]
|
||||
fn test_branch_diff() -> Result<(), Error> {
|
||||
let repo = Repository::open(GIT_PLATINUM)?;
|
||||
let repo = repo.as_ref();
|
||||
let diff = repo.diff(
|
||||
&Branch::local(refname!("master")),
|
||||
&Branch::local(refname!("dev")),
|
||||
@@ -600,7 +576,6 @@ mod threading {
|
||||
let shared_repo = Mutex::new(Repository::open(GIT_PLATINUM)?);
|
||||
let locked_repo: MutexGuard<Repository> = shared_repo.lock().unwrap();
|
||||
let mut branches = locked_repo
|
||||
.as_ref()
|
||||
.branches(&Glob::heads("*")?.and_remotes("*")?)?
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
branches.sort();
|
||||
@@ -700,7 +675,6 @@ mod reference {
|
||||
#[test]
|
||||
fn test_branches() {
|
||||
let repo = Repository::open(GIT_PLATINUM).unwrap();
|
||||
let repo = repo.as_ref();
|
||||
let branches = repo.branches(&Glob::heads("*").unwrap()).unwrap();
|
||||
for b in branches {
|
||||
println!("{}", b.unwrap().refname());
|
||||
@@ -716,21 +690,19 @@ mod reference {
|
||||
#[test]
|
||||
fn test_tag_snapshot() {
|
||||
let repo = Repository::open(GIT_PLATINUM).unwrap();
|
||||
let repo_ref = repo.as_ref();
|
||||
let tags = repo_ref
|
||||
let tags = repo
|
||||
.tags(&Glob::tags("*").unwrap())
|
||||
.unwrap()
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
.unwrap();
|
||||
assert_eq!(tags.len(), 6);
|
||||
let root_dir = repo_ref.root_dir(&tags[0]).unwrap();
|
||||
assert_eq!(root_dir.contents(&repo_ref).unwrap().iter().count(), 1);
|
||||
let root_dir = repo.root_dir(&tags[0]).unwrap();
|
||||
assert_eq!(root_dir.contents(&repo).unwrap().iter().count(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_namespaces() {
|
||||
let repo = Repository::open(GIT_PLATINUM).unwrap();
|
||||
let repo = repo.as_ref();
|
||||
let namespaces = repo.namespaces(&Glob::namespaces("*").unwrap()).unwrap();
|
||||
assert_eq!(namespaces.count(), 3);
|
||||
let namespaces = repo
|
||||
@@ -748,12 +720,11 @@ mod code_browsing {
|
||||
use super::*;
|
||||
|
||||
use git_ref_format::refname;
|
||||
use radicle_surf::{file_system::Directory, git::RepositoryRef};
|
||||
use radicle_surf::{file_system::Directory, git::Repository};
|
||||
|
||||
#[test]
|
||||
fn iterate_root_dir_recursive() {
|
||||
let repo = Repository::open(GIT_PLATINUM).unwrap();
|
||||
let repo = repo.as_ref();
|
||||
|
||||
let root_dir = repo.root_dir(&Branch::local(refname!("master"))).unwrap();
|
||||
let count = println_dir(&root_dir, &repo, 0);
|
||||
@@ -764,7 +735,7 @@ mod code_browsing {
|
||||
/// For sub-directories, will do Depth-First-Search and print
|
||||
/// recursively.
|
||||
/// Returns the number of items visited (i.e. printed)
|
||||
fn println_dir(dir: &Directory, repo: &RepositoryRef, indent_level: usize) -> i32 {
|
||||
fn println_dir(dir: &Directory, repo: &Repository, indent_level: usize) -> i32 {
|
||||
let mut count = 0;
|
||||
for item in dir.contents(repo).unwrap().iter() {
|
||||
println!("> {}{}", " ".repeat(indent_level * 4), &item.label());
|
||||
@@ -780,14 +751,13 @@ mod code_browsing {
|
||||
#[test]
|
||||
fn browse_repo_lazily() {
|
||||
let repo = Repository::open(GIT_PLATINUM).unwrap();
|
||||
let repo = repo.as_ref();
|
||||
let root_dir = repo.root_dir(&Branch::local(refname!("master"))).unwrap();
|
||||
let count = root_dir.contents(&repo).unwrap().iter().count();
|
||||
assert_eq!(count, 8);
|
||||
let count = traverse(&root_dir, &repo);
|
||||
assert_eq!(count, 36);
|
||||
|
||||
fn traverse(dir: &Directory, repo: &RepositoryRef) -> i32 {
|
||||
fn traverse(dir: &Directory, repo: &Repository) -> i32 {
|
||||
let mut count = 0;
|
||||
for item in dir.contents(repo).unwrap().iter() {
|
||||
count += 1;
|
||||
@@ -802,7 +772,6 @@ mod code_browsing {
|
||||
#[test]
|
||||
fn test_file_history() {
|
||||
let repo = Repository::open(GIT_PLATINUM).unwrap();
|
||||
let repo = repo.as_ref();
|
||||
let history = repo.history(&Branch::local(refname!("dev"))).unwrap();
|
||||
let path = unsound::path::new("README.md");
|
||||
let mut file_history = history.by_path(path);
|
||||
|
||||
Reference in New Issue
Block a user