Skip to content

Commit

Permalink
When #207 is detected, leave the repo in a state that prevents furthe…
Browse files Browse the repository at this point in the history
…r breakage
  • Loading branch information
glandium committed Apr 29, 2022
1 parent 16d1170 commit 56cdd1b
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 4 deletions.
7 changes: 7 additions & 0 deletions cinnabar/githg.py
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,7 @@ def __init__(self):
self._replace = Git._replace
self._tagcache_ref = None
self._metadata_sha1 = None
broken = None
# While doing a for_each_ref, ensure refs/notes/cinnabar is in the
# cache.
for sha1, ref in Git.for_each_ref('refs/cinnabar',
Expand All @@ -613,6 +614,10 @@ def __init__(self):
self._metadata_sha1 = sha1
elif ref == b'refs/cinnabar/tag_cache':
self._tagcache_ref = sha1
elif ref == b'refs/cinnabar/broken':
broken = sha1
self._broken = broken and self._metadata_sha1 and \
broken == self._metadata_sha1
self._replace = VersionedDict(self._replace)

self._tagcache = {}
Expand Down Expand Up @@ -1246,6 +1251,7 @@ def close(self, refresh=()):
) as commit:
for sha1, target in util.iteritems(self._replace):
commit.filemodify(sha1, target, b'commit')
self._metadata_sha1 = commit.sha1

for c in self._tagcache:
if c not in changeset_heads:
Expand Down Expand Up @@ -1326,6 +1332,7 @@ def tagset_lines(tags):
bundle = "Please keep a copy of the "
bundle += os.environ["GIT_DIR"] + "/cinnabar-last-bundle file"
bundle += " before doing the following.\n"
Git.update_ref(b'refs/cinnabar/broken', self._metadata_sha1)
raise Abort(
"It seems you have hit a known, rare, and difficult to "
"reproduce issue.\n"
Expand Down
17 changes: 13 additions & 4 deletions cinnabar/remote_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,10 @@ def list(self, arg=None):
self._helper.flush()

def import_(self, *refs):
if self._store._broken:
raise Abort('Cannot fetch with broken metadata. '
'Please fix your clone first.\n')

# If anything wrong happens at any time, we risk git picking
# the existing refs/cinnabar refs, so remove them preventively.
for sha1, ref in Git.for_each_ref('refs/cinnabar/refs/heads',
Expand Down Expand Up @@ -470,11 +474,16 @@ def push(self, *refspecs):
pushes = list((Git.resolve_ref(fsdecode(s.lstrip(b'+'))), d,
s.startswith(b'+'))
for s, d in (r.split(b':', 1) for r in refspecs))
if not self._repo.capable(b'unbundle'):
if self._store._broken or not self._repo.capable(b'unbundle'):
for source, dest, force in pushes:
self._helper.write(
b'error %s Remote does not support the "unbundle" '
b'capability\n' % dest)
if self._store._broken:
self._helper.write(
b'error %s Remote does not support the "unbundle" '
b'capability\n' % dest)
else:
self._helper.write(
b'error %s Cannot push with broken metadata. '
b'Please fix your clone first.\n' % dest)
self._helper.write(b'\n')
self._helper.flush()
else:
Expand Down

0 comments on commit 56cdd1b

Please sign in to comment.