branches: GET /repos/{owner}/{repo}/branches/master 301-redirects to the current default branch; response semantics undocumented

Aperta Adatta ai principianti
#7,096 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
68/100
Tipo di issue
Documentazione
Chiarezza
Abbastanza chiara
Stato di attività
Attiva
Stack tecnologico
github, openapi
Ambito
api, documentation

Direzione di ricerca

Inizia con il riferimento REST per GET /repos/{owner}/{repo}/branches/{branch} e confronta la relativa risposta 301 con il changelog del 2020 e l’aggiornamento del 2023-02-07. Documenta quando si verifica il reindirizzamento e che Location può indicare un branch diverso, oppure riconcilia l’endpoint con il comportamento pubblicato; le osservazioni e la formulazione suggerita in questa issue definiscono quando il lavoro è completato.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

feature

Routed here from https://github.com/github/docs/issues/45642 — thanks to @subatoi for pointing at the right repo.

The API behaviour half is also open as a community discussion: https://github.com/orgs/community/discussions/206039


What the docs say vs what the API does

The REST reference for branches lists 301 Moved permanently among the responses for GET /repos/{owner}/{repo}/branches/{branch}, but does not say when that redirect fires, or that Location may name a different branch than the one requested.

The changelog entry Links to deleted branches now redirect to the default branch (2020-07-17) announced this redirect, and an update appended to that same entry on 2023-02-07 withdraws it:

This behavior conflicted with other GitHub URL patterns, so we removed it. GitHub does redirect renamed branches, but not deleted branches.

That entry concerns web links. The REST API today still redirects, and it redirects to branches that no rename plausibly relates to master.

Measured 2026-08-28, redirect-following disabled

symfony/symfony        /branches/master   ->  301  Location=.../branches/8.2
scala/scala            /branches/master   ->  301  Location=.../branches/2.13.x
twitter/finagle        /branches/master   ->  301  Location=.../branches/develop
pytorch/pytorch        /branches/master   ->  301  Location=.../branches/main
kubernetes/kubernetes  /branches/master   ->  200  name=master   (no redirect)
symfony/symfony        /branches/nope-xyz ->  404

Nobody renamed master to 8.2, 2.13.x, or develop. Those are simply the current default branches.

Boundary
question result
Other retired conventional names? No. trunk, develop, dev all 404 where absent — including trunk on nodejs/node. Only the literal master redirects.
Repos that plausibly never had a master? Yes, still fires. anthropics/claude-code (created 2025-02-22) and astral-sh/uv (created 2023-10-02) each 301 to main.
Does Location track the current default? Yes, in every repo measured.
Controls apache/subversion /branches/trunk200 (it is the default); twitter/finagle /branches/develop200 (it exists); a live master returns itself; a never-existing ref 404s.

I am not claiming to know the cause — GitHub does not expose deleted-branch history, so "never had a master" is inference from a creation date, not a measurement.

Why this is worth documenting

Every HTTP client that follows redirects by default (urllib, requests, curl -L, most SDKs) turns the 301 into a transparent 200 describing a branch the caller never asked for. The failure mode is a successful read of the wrong resource — no error, no warning.

Any tool resolving a historical branch name is exposed. A pull request records its base ref as it was at the time, so old PRs name branches that are now gone:

b = get(f"/repos/{repo}/branches/{pr['base']['ref']}")   # 200. Looks fine.
cmp = get(f"/repos/{repo}/compare/{b['name']}...{head}") # answers about the wrong branch

In my own use — comparing a PR's head against the branch it targeted — this silently defeated a fix that existed specifically to stop comparing against the default branch. Across a sample of 379 pull requests in 108 repositories, 46 of 48 resolution failures were this redirect.

The guard callers need is name equality, not HTTP status:

if b["name"] != ref:  # the requested ref is gone; this is a different branch

Suggested doc change

Any one of these would remove the surprise:

  1. Document on the branches endpoint when the 301 fires, and that Location may name a different branch.
  2. Reconcile with the 2023-02-07 withdrawal, which currently reads as though this redirect no longer exists.
  3. If the behaviour is intended to be renamed-branches-only, the observations above suggest it is broader than that.

Documentation alone would be enough. The behaviour is defensible; the contradiction with a published withdrawal is what makes it cost people time.

Lingua principale
Nessun dato sulla lingua
Stelle
1.6k
Fork
342
Merge medio
3h 33m
PR unite (30g)
51

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di github/rest-api-description

Tutte le issue di github/rest-api-description

Issue simili

Altre issue su Backend & API Design

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.