Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions gitpure.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,9 @@ class Repo:
"""
...

def branches(self) -> list[str]:
"""Return the names of all local branches in the repository."""
@property
def branches(self) -> list[Head]:
"""Return all local branches as Head objects."""
...

@property
Expand Down
34 changes: 7 additions & 27 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ struct Repo {
inner: gix::Repository,
}

fn path_to_python(py: Python<'_>, path: &Path) -> PyResult<PyObject> {
fn path_to_python(py: Python<'_>, path: &Path) -> PyResult<Py<PyAny>> {
let pathlib = py.import("pathlib")?;
let path_class = pathlib.getattr("Path")?;
Ok(path_class.call1((path.as_os_str(),))?.into())
Expand All @@ -138,13 +138,13 @@ fn shorten_reference_name(reference: &gix::Reference) -> String {
impl Repo {
/// The path to the `.git` directory of the repository.
#[getter]
fn git_dir(&self, py: Python) -> PyResult<PyObject> {
fn git_dir(&self, py: Python) -> PyResult<Py<PyAny>> {
path_to_python(py, self.inner.git_dir())
}

/// The path to the working tree directory, if present.
#[getter]
fn working_tree_dir(&self, py: Python) -> PyResult<Option<PyObject>> {
fn working_tree_dir(&self, py: Python) -> PyResult<Option<Py<PyAny>>> {
match self.inner.workdir() {
Some(path) => Ok(Some(path_to_python(py, path)?)),
None => Ok(None),
Expand Down Expand Up @@ -202,30 +202,10 @@ impl Repo {
}
}

/// Return the names of all local branches in the repository.
fn branches(&self) -> PyResult<Vec<String>> {
let platform = self.inner.references().map_err(|err| {
PyRuntimeError::new_err(format!("Failed to access references: {err}"))
})?;

let iter = platform.local_branches().map_err(|err| {
PyRuntimeError::new_err(format!("Failed to list local branches: {err}"))
})?;

let branches: BTreeSet<String> = iter
.map(|reference_result| {
reference_result.map_err(|err| {
PyRuntimeError::new_err(format!(
"Failed to load branch reference: {err}"
))
})
})
.collect::<Result<Vec<_>, _>>()?
.into_iter()
.map(|reference| shorten_reference_name(&reference))
.collect();

Ok(branches.into_iter().collect())
/// Return all local branches in the repository.
#[getter]
fn branches(&self) -> PyResult<Vec<Head>> {
self.heads()
}

/// Return the path to the current active branch, if any.
Expand Down
10 changes: 5 additions & 5 deletions tests/test_repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,15 +164,15 @@ def test_branch_listing_matches_gitpython():
repo_path = Path(tmpdir) / "gitpure"
repo = Repo.clone_from(repo_url, str(repo_path))

gitpure_branches = repo.branches()
gitpure_branches = repo.branches
assert isinstance(gitpure_branches, list)
assert all(isinstance(branch, str) for branch in gitpure_branches)
assert all(hasattr(branch, "name") and hasattr(branch, "commit") for branch in gitpure_branches)

gitpython_repo = GitPythonRepo(str(repo_path))
gitpython_branches = sorted(head.name for head in gitpython_repo.branches)

assert gitpure_branches == gitpython_branches
assert [branch.name for branch in gitpure_branches] == gitpython_branches

# heads property should mirror branches()
# branches property should mirror heads property
gitpure_heads = repo.heads
assert [head.name for head in gitpure_heads] == gitpure_branches
assert [head.name for head in gitpure_heads] == [branch.name for branch in gitpure_branches]