mirror git: el poblador reporta el error real de git, no una conjetura
Imprimía siempre «upstream no da el commit» pasara lo que pasara. En la primera tanda marcó así a diffutils, findutils-xargs y kustomize, cuyos commits se traen a mano sin problema: era transitorio. Ahora bundle() devuelve (ruta, motivo) con el stderr del paso que falló. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016v9ozVm44p6DB7EMXeZK4o
This commit is contained in:
@@ -40,22 +40,37 @@ def ya_en_mirror():
|
||||
return {l.strip()[:-7] for l in r.stdout.splitlines() if l.strip().endswith(".bundle")}
|
||||
|
||||
def bundle(e, tmpdir):
|
||||
"""Clona --depth 1 el commit exacto y emite un bundle. None si upstream no lo da."""
|
||||
"""Clona --depth 1 el commit exacto y emite un bundle.
|
||||
|
||||
Devuelve (ruta, None) si sale bien y (None, motivo) si no. El motivo es el stderr REAL de git,
|
||||
no una conjetura: un fallo acá puede ser el servidor negando el fetch por sha suelto, pero
|
||||
tambien un timeout, DNS, o un rate-limit, y cada uno se arregla distinto. Ver ADR 0013.
|
||||
"""
|
||||
d = os.path.join(tmpdir, "r")
|
||||
shutil.rmtree(d, ignore_errors=True)
|
||||
os.makedirs(d)
|
||||
def git(*a, **kw):
|
||||
return subprocess.run(["git", "-C", d] + list(a), capture_output=True, text=True,
|
||||
timeout=kw.get("t", 900))
|
||||
if git("init", "-q").returncode != 0: return None
|
||||
if git("remote", "add", "origin", e["repo"]).returncode != 0: return None
|
||||
# --depth 1 del SHA exacto: el servidor debe permitir fetch por sha (uploadpack.allowReachableSHA1).
|
||||
if git("fetch", "-q", "--depth", "1", "origin", e["commit"], t=1800).returncode != 0:
|
||||
return None
|
||||
if git("update-ref", "refs/heads/hammer", e["commit"]).returncode != 0: return None
|
||||
def paso(etiqueta, *a, **kw):
|
||||
try:
|
||||
r = git(*a, **kw)
|
||||
except subprocess.TimeoutExpired:
|
||||
return f"{etiqueta}: timeout"
|
||||
return None if r.returncode == 0 else f"{etiqueta}: {(r.stderr or r.stdout).strip().splitlines()[-1][:160] if (r.stderr or r.stdout).strip() else 'rc=' + str(r.returncode)}"
|
||||
|
||||
out = os.path.join(tmpdir, f'{e["commit"]}.bundle')
|
||||
if git("bundle", "create", out, "refs/heads/hammer", t=1800).returncode != 0: return None
|
||||
return out if os.path.exists(out) else None
|
||||
for etiqueta, args, kw in (
|
||||
("init", ("init", "-q"), {}),
|
||||
("remote", ("remote", "add", "origin", e["repo"]), {}),
|
||||
# --depth 1 del SHA exacto: el servidor debe permitir fetch por sha (uploadpack.allowReachableSHA1).
|
||||
("fetch", ("fetch", "-q", "--depth", "1", "origin", e["commit"]), {"t": 1800}),
|
||||
("update-ref",("update-ref", "refs/heads/hammer", e["commit"]), {}),
|
||||
("bundle", ("bundle", "create", out, "refs/heads/hammer"), {"t": 1800}),
|
||||
):
|
||||
motivo = paso(etiqueta, *args, **kw)
|
||||
if motivo: return None, motivo
|
||||
return (out, None) if os.path.exists(out) else (None, "bundle: git dijo OK pero no hay fichero")
|
||||
|
||||
def main():
|
||||
fs = fuentes_git()
|
||||
@@ -76,10 +91,10 @@ def main():
|
||||
tmpdir = tempfile.mkdtemp(prefix="hammer-git-mirror-")
|
||||
try:
|
||||
for i, e in enumerate(faltan, 1):
|
||||
b = bundle(e, tmpdir)
|
||||
b, motivo = bundle(e, tmpdir)
|
||||
if not b:
|
||||
fallo += 1
|
||||
print(f" [{i}/{len(faltan)}] {e['receta']:<24} ✗ upstream no da el commit", flush=True)
|
||||
print(f" [{i}/{len(faltan)}] {e['receta']:<24} ✗ {motivo}", flush=True)
|
||||
continue
|
||||
mb = os.path.getsize(b) / 1e6
|
||||
r = subprocess.run(["rsync", "-a", "-e", " ".join(SSH), b,
|
||||
|
||||
Reference in New Issue
Block a user