◐ Shell
reader mode source ↗
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
File filter
Conversations
Jump to
Diff view
Apply and reload
Show whitespace
Diff view
Apply and reload
6 changes: 4 additions & 2 deletions git/refs/log.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
__all__ = ["RefLog", "RefLogEntry"]

from mmap import mmap
import os.path as osp
import re
import time as _time

Expand Down Expand Up @@ -212,8 +211,11 @@ def path(cls, ref: "SymbolicReference") -> str:

:param ref:
:class:`~git.refs.symbolic.SymbolicReference` instance
"""
return osp.join(ref.repo.git_dir, "logs", to_native_path(ref.path))

@classmethod
def iter_entries(cls, stream: Union[str, "BytesIO", mmap]) -> Iterator[RefLogEntry]:
Expand Down
37 changes: 31 additions & 6 deletions git/refs/symbolic.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,32 @@ def name(self) -> str:
def abspath(self) -> PathLike:
return join_path_native(_git_dir(self.repo, self.path), self.path)

@classmethod
def _get_packed_refs_path(cls, repo: "Repo") -> str:
return os.path.join(repo.common_dir, "packed-refs")
Expand Down Expand Up @@ -485,7 +511,7 @@ def set_reference(
# END handle non-existing
# END retrieve old hexsha

fpath = self.abspath
assure_directory_exists(fpath, is_file=True)

lfd = LockedFD(fpath)
Expand Down Expand Up @@ -632,7 +658,7 @@ def delete(cls, repo: "Repo", path: PathLike) -> None:
Alternatively the symbolic reference to be deleted.
"""
full_ref_path = cls.to_full_path(path)
abs_path = os.path.join(repo.common_dir, full_ref_path)
if os.path.exists(abs_path):
os.remove(abs_path)
else:
Expand Down Expand Up @@ -695,9 +721,8 @@ def _create(
symbolic reference. Otherwise it will be resolved to the corresponding object
and a detached symbolic reference will be created instead.
"""
git_dir = _git_dir(repo, path)
full_ref_path = cls.to_full_path(path)
abs_ref_path = os.path.join(git_dir, full_ref_path)

# Figure out target data.
target = reference
Expand Down Expand Up @@ -789,8 +814,8 @@ def rename(self, new_path: PathLike, force: bool = False) -> "SymbolicReference"
if self.path == new_path:
return self

new_abs_path = os.path.join(_git_dir(self.repo, new_path), new_path)
cur_abs_path = os.path.join(_git_dir(self.repo, self.path), self.path)
if os.path.isfile(new_abs_path):
if not force:
# If they point to the same file, it's not an error.
Expand Down
2 changes: 1 addition & 1 deletion git/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ def join_path(a: PathLike, *p: PathLike) -> PathLike:

if sys.platform == "win32":

def to_native_path_windows(path: PathLike) -> PathLike:
path = os.fspath(path)
return path.replace("/", "\\")

Expand Down
123 changes: 123 additions & 0 deletions test/test_refs.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# This module is part of GitPython and is released under the
# 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/

from itertools import chain
import os.path as osp
from pathlib import Path
Expand All @@ -18,6 +19,7 @@
RefLog,
Reference,
RemoteReference,
SymbolicReference,
TagReference,
)
Expand All @@ -29,6 +31,18 @@


class TestRefs(TestBase):
def test_from_path(self):
# Should be able to create any reference directly.
for ref_type in (Reference, Head, TagReference, RemoteReference):
Expand Down Expand Up @@ -648,6 +662,115 @@ def test_refs_outside_repo(self):
ref_file_name = Path(ref_file.name).name
self.assertRaises(BadName, self.rorepo.commit, f"../../{ref_file_name}")

def test_validity_ref_names(self):
"""Ensure ref names are checked for validity.

Expand Down
Loading
Toggle all file notes Toggle all file annotations