feat: follow a fork's base as its upstream head

For a port that is a GitHub fork of its upstream, the upstream code it
carries is the merge base of the two, not upstream's HEAD. The bump moved
upstream_commit to upstream HEAD on snes9x, kronos, np2kai and others
whose pin was that base. The upstream view's head is now the merge base
GitHub's compare names, the way _follow_submodule already reads a
vendored submodule. Outside a fork network the HEAD stays.
This commit is contained in:
Abdessamad Derraz committed 2026-10-23 16:25:56 +02:00
1 parent 01a6daf653
commit 861b89dd44
4 files changed
+116 -1

No files matched your search

+20
View File
@@ -840,6 +840,26 @@ def _commits_ahead(payload: object, family: str) -> int | None:
return value if isinstance(value, int) else None
def fork_base(
repo: Repo, sha: str, fork: Repo, fork_sha: str, cache_dir: str,
offline: bool = False,
) -> str | None:
"""The commit of ``repo`` that ``fork`` at ``fork_sha`` has merged up to.
GitHub compares across a fork network and names the merge base. Two
repositories outside one network answer 404, and None is returned.
"""
if repo.family != "github" or fork.family != "github":
return None
payload = _api(
f"{repo.api_base}/repos/{repo.slug}/compare/"
f"{sha}...{fork.owner}:{fork.name}:{fork_sha}",
cache_dir, offline,
)
base = payload.get("merge_base_commit") if isinstance(payload, dict) else None
return base.get("sha") if isinstance(base, dict) else None
def ancestry(
repo: Repo, base: str, head: str, cache_dir: str, offline: bool = False
) -> tuple[int, int] | None: