Fix Update-Banner hing endlos: git-Warnzeile wurde als Ziel-Commit gelesen (t_50a07d4b-Live-Bug, Meldung Sly 20.10.)
git_run mischt stdout+stderr; bei der HTTP-Umleitung der Forgejo-URL schreibt git zuerst 'warning: Umleitung nach ...'. Die alte Fassung nahm die ERSTE Zeile und hielt 'warning' fuer den Remote-SHA -> Banner 'Update verfuegbar: <sha> -> warning' blieb fuer immer, obwohl der Klon auf origin/main stand (live auf dem PC belegt: STDOUT korrekt, STDERR Warnung). Jetzt: sha_aus_ls_remote() liest nur echte '<sha>\t<refs/heads/...>'-Zeilen (Warnungen/hints/fatal uebersprungen, SHA muss Hex sein), Notnagel = erste hex-artige Zeile; 'kein Commit in der Ausgabe' gilt als unreachable statt update_available. Regressionstest: 6 neue Checks in test_updater.gd.
This commit is contained in:
parent
d0d4fbd221
commit
437f6bf368
2 changed files with 78 additions and 2 deletions
|
|
@ -124,7 +124,7 @@ static func remote_sha(git_exe: String, project_dir: String, branch: String) ->
|
||||||
var text := str(r["output"]).strip_edges()
|
var text := str(r["output"]).strip_edges()
|
||||||
if text.is_empty():
|
if text.is_empty():
|
||||||
return ""
|
return ""
|
||||||
return text.split("\n")[0].strip_edges().split("\t")[0]
|
return sha_aus_ls_remote(text, branch)
|
||||||
|
|
||||||
|
|
||||||
## Update-Check: lokaler HEAD vs. origin/main.
|
## Update-Check: lokaler HEAD vs. origin/main.
|
||||||
|
|
@ -152,12 +152,65 @@ static func check_update(git_exe: String, project_dir: String) -> Dictionary:
|
||||||
if text2.is_empty():
|
if text2.is_empty():
|
||||||
return {"status": "unreachable", "local": local, "remote": "",
|
return {"status": "unreachable", "local": local, "remote": "",
|
||||||
"error": "Origin nicht erreichbar (offline oder Tunnel weg)."}
|
"error": "Origin nicht erreichbar (offline oder Tunnel weg)."}
|
||||||
var remote := text2.split("\n")[0].strip_edges().split("\t")[0]
|
var remote := sha_aus_ls_remote(text2, BRANCH)
|
||||||
|
if remote.is_empty():
|
||||||
|
# Kein echter Commit in der Ausgabe (nur Warnungen/leer) — NICHT als
|
||||||
|
# Update deuten, sonst hängt das Banner endlos (Karte t_50a07d4b-Live-Bug).
|
||||||
|
return {"status": "unreachable", "local": local, "remote": "",
|
||||||
|
"error": "Origin lieferte keinen Commit (nur Warnungen)."}
|
||||||
if local == remote:
|
if local == remote:
|
||||||
return {"status": "up_to_date", "local": local, "remote": remote, "error": ""}
|
return {"status": "up_to_date", "local": local, "remote": remote, "error": ""}
|
||||||
return {"status": "update_available", "local": local, "remote": remote, "error": ""}
|
return {"status": "update_available", "local": local, "remote": remote, "error": ""}
|
||||||
|
|
||||||
|
|
||||||
|
## Aus der gemischten ls-remote-Ausgabe den Commit für `branch` lesen.
|
||||||
|
## WARUM: `git_run` mischt stdout+stderr, und der git-Client schreibt bei einer
|
||||||
|
## HTTP-Umleitung zuerst "warning: Umleitung nach ..." — die alte Fassung nahm
|
||||||
|
## stumpf die ERSTE Zeile und hielt "warning" für den Ziel-Commit. Ergebnis war
|
||||||
|
## ein Banner "Update verfügbar: <sha> → warning", das nie verschwand, obwohl
|
||||||
|
## der Pull korrekt lief (live belegt 20.10., Klon stand auf origin/main).
|
||||||
|
## Regeln: nur Zeilen "<sha>\t<ref>" zählen, sha = echter Hex-String.
|
||||||
|
static func sha_aus_ls_remote(text: String, branch: String) -> String:
|
||||||
|
var ziel := "refs/heads/%s" % branch
|
||||||
|
var locker := ""
|
||||||
|
for zeile in text.split("\n"):
|
||||||
|
var z := zeile.strip_edges()
|
||||||
|
if z.is_empty():
|
||||||
|
continue
|
||||||
|
var klein := z.to_lower()
|
||||||
|
if klein.begins_with("warning") or klein.begins_with("hint") \
|
||||||
|
or klein.begins_with("fatal") or klein.begins_with("error"):
|
||||||
|
continue
|
||||||
|
var teile := z.split("\t")
|
||||||
|
if teile.size() < 2:
|
||||||
|
continue
|
||||||
|
var sha := teile[0].strip_edges()
|
||||||
|
if not ist_sha(sha):
|
||||||
|
continue
|
||||||
|
if teile[1].strip_edges() == ziel:
|
||||||
|
return sha
|
||||||
|
if locker.is_empty():
|
||||||
|
locker = sha
|
||||||
|
return locker
|
||||||
|
|
||||||
|
|
||||||
|
## Sieht der Text wie ein Git-Objekt-Hash aus (7-40 Hex-Zeichen)?
|
||||||
|
static func ist_sha(text: String) -> bool:
|
||||||
|
var t := text.strip_edges()
|
||||||
|
if t.length() < 7 or t.length() > 40:
|
||||||
|
return false
|
||||||
|
for i in t.length():
|
||||||
|
var c := t[i]
|
||||||
|
if c >= "0" and c <= "9":
|
||||||
|
continue
|
||||||
|
if c >= "a" and c <= "f":
|
||||||
|
continue
|
||||||
|
if c >= "A" and c <= "F":
|
||||||
|
continue
|
||||||
|
return false
|
||||||
|
return true
|
||||||
|
|
||||||
|
|
||||||
## Kurzer SHA für Anzeigen (7 Zeichen, wie git log --oneline).
|
## Kurzer SHA für Anzeigen (7 Zeichen, wie git log --oneline).
|
||||||
static func short_sha(sha: String) -> String:
|
static func short_sha(sha: String) -> String:
|
||||||
return sha.substr(0, 7)
|
return sha.substr(0, 7)
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ func _init() -> void:
|
||||||
TEST_DIR_PREFIX + "_" + str(Time.get_ticks_msec()))
|
TEST_DIR_PREFIX + "_" + str(Time.get_ticks_msec()))
|
||||||
DirAccess.make_dir_recursive_absolute(base)
|
DirAccess.make_dir_recursive_absolute(base)
|
||||||
_run_tests()
|
_run_tests()
|
||||||
|
_test_ls_remote_warnzeile()
|
||||||
_cleanup_dir(base) # best effort — git-Pack-Dateien können read-only sein
|
_cleanup_dir(base) # best effort — git-Pack-Dateien können read-only sein
|
||||||
if failures == 0:
|
if failures == 0:
|
||||||
print("ALL OK: %d checks" % checks)
|
print("ALL OK: %d checks" % checks)
|
||||||
|
|
@ -336,3 +337,25 @@ func _run_tests() -> void:
|
||||||
var self_args := EditorUpdater.self_restart_args("/pfad/zum/klon")
|
var self_args := EditorUpdater.self_restart_args("/pfad/zum/klon")
|
||||||
_check(str(self_args[0]) == "--path" and str(self_args[1]) == "/pfad/zum/klon",
|
_check(str(self_args[0]) == "--path" and str(self_args[1]) == "/pfad/zum/klon",
|
||||||
"Selbst-Restart: --path <klon> (startet die Map-Editor-APP, nicht die Godot-Editor-Shell)")
|
"Selbst-Restart: --path <klon> (startet die Map-Editor-APP, nicht die Godot-Editor-Shell)")
|
||||||
|
|
||||||
|
|
||||||
|
## Regression (20.10., Live-Bug im Map-Builder): git schreibt bei einer
|
||||||
|
## HTTP-Umleitung zuerst "warning: Umleitung nach ..." in die GEMISCHTE
|
||||||
|
## Ausgabe (git_run mischt stdout+stderr). Die alte Fassung nahm die ERSTE
|
||||||
|
## Zeile als Ziel-Commit → Banner "Update verfügbar: <sha> → warning" hing
|
||||||
|
## endlos, obwohl der Klon aktuell war. Erwartung: echte "<sha>\t<ref>"-Zeile
|
||||||
|
## gewinnt, Warnzeilen werden nie als SHA gelesen.
|
||||||
|
func _test_ls_remote_warnzeile() -> void:
|
||||||
|
var sha := "d0d4fbd2213e596d117b779c6d931629bf9b20ed"
|
||||||
|
var mit_warnung := "warning: Umleitung nach http://127.0.0.1:13020/x.git/\n%s\trefs/heads/main\n" % sha
|
||||||
|
_check(EditorUpdater.sha_aus_ls_remote(mit_warnung, "main") == sha,
|
||||||
|
"Warnzeile ignoriert, echter Commit gelesen")
|
||||||
|
_check(not EditorUpdater.ist_sha("warning"), "'warning' gilt nicht als SHA")
|
||||||
|
_check(EditorUpdater.sha_aus_ls_remote("warning: Umleitung nach x\n", "main") == "",
|
||||||
|
"nur Warnzeilen → leerer Commit (kein Update-Banner)")
|
||||||
|
_check(EditorUpdater.sha_aus_ls_remote("fatal: could not read Username\n", "main") == "",
|
||||||
|
"fatal-Zeile wird nicht als SHA gelesen")
|
||||||
|
_check(EditorUpdater.sha_aus_ls_remote("%s\trefs/heads/main" % sha, "main") == sha,
|
||||||
|
"normale Zeile funktioniert weiterhin")
|
||||||
|
_check(EditorUpdater.sha_aus_ls_remote("%s\trefs/heads/anderer" % sha, "main") == sha,
|
||||||
|
"anderer Branch: SHA bleibt als Notnagel nutzbar")
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue