Compare commits

...

2 Commits

Author SHA1 Message Date
9c53919802 Dereference refs when reading and writing 2024-06-29 18:48:21 +02:00
30ce8c84e4 Add change 33 to instructions 2024-06-29 18:47:23 +02:00
2 changed files with 27 additions and 3 deletions

17
how_to/Change_33.md Normal file
View File

@@ -0,0 +1,17 @@
data: Dereference refs when reading and writing
Now we'll dereference symbolic refs not only when reading them but also when
writing them.
We'll implement a helper function called `_get_ref_internal` which will return
the path and the value of the last ref pointed by a symbolic ref. In simple words:
- When given a non-symbolic ref, `_get_ref_internal` will return the ref name
and value.
- When given a symbolic ref, `_get_ref_internal` will dereference the ref
recursively, and then return the name of the last (non-symbolic) ref that points
to an OID, plus its value.
Now `update_ref` will use `_get_ref_internal` to know which ref it needs to update.
Additionally, we'll use `_get_ref_internal` in `get_ref`.

View File

@@ -18,6 +18,7 @@ RefValue = namedtuple("RefValue", ["symbolic", "value"])
def update_ref(ref, value):
assert not value.symbolic
ref = _get_ref_internal(ref)[0]
ref_path = f"{GIT_DIR}/{ref}"
Path.mkdir(ref_path, exist_ok=True)
with open(ref_path, "w") as f:
@@ -25,16 +26,22 @@ def update_ref(ref, value):
def get_ref(ref):
return _get_ref_internal(ref)[1]
def _get_ref_internal(ref):
ref_path = f"{GIT_DIR}/{ref}"
value = None
if Path.is_file(ref_path):
with open(ref_path) as f:
value = f.read().strip()
if value and value.startswith("ref:"):
return get_ref(value.split(":", 1)[1].strip())
symbolic = bool(value) and value.startswith("ref")
if symbolic:
value = value.split(":", 1)[1].strip()
return _get_ref_internal(value)
return RefValue(symbolic=False, value=value)
return ref, RefValue(symbolic=False, value=value)
def iter_refs():