Summary
Running infrahub upgrade overwrites the status of already-merged branches from MERGED to NEED_UPGRADE_REBASE. Since MERGED is the terminal/read-only state used to represent a branch that has been merged (and should be treated as deleted from a user perspective), the upgrade effectively re-opens every previously merged branch and surfaces them as needing a rebase.
Steps to reproduce
- Create a branch, make changes, merge it. The branch ends up with
status = MERGED (set in backend/infrahub/core/branch/tasks.py:410).
- Run
infrahub upgrade against a database whose graph_version was bumped (i.e. branches were created on the previous version).
- Observe that the merged branch's status is now
NEED_UPGRADE_REBASE and it shows up in the "branches that need to be rebased" list.
Root cause
mark_branches_needing_rebase iterates over Branch.get_list(...) filtering only the default branch and GLOBAL_BRANCH_NAME. Any branch whose graph_version != GRAPH_VERSION then has its status overwritten unconditionally:
async def mark_branches_needing_rebase(db: InfrahubDatabase) -> list[Branch]:
branches = [b for b in await Branch.get_list(db=db) if b.name not in [registry.default_branch, GLOBAL_BRANCH_NAME]]
if not branches:
return []
branches_needing_rebase: list[Branch] = []
for branch in branches:
if branch.graph_version == GRAPH_VERSION:
continue
branch.status = BranchStatus.NEED_UPGRADE_REBASE
await branch.save(db=db)
branches_needing_rebase.append(branch)
return branches_needing_rebase
Branches with terminal status (MERGED, DELETING) are not excluded.
Expected behavior
Merged (and deleting) branches must be treated as already gone. infrahub upgrade should leave their status alone — they should not be marked NEED_UPGRADE_REBASE and should not appear in the rebase list.
Suggested fix
Skip branches in a terminal state. The codebase already has a helper for this: Branch.is_terminal returns True for MERGED and DELETING. Filter on it in mark_branches_needing_rebase (and also gate the status assignment, to be safe).
Summary
Running
infrahub upgradeoverwrites the status of already-merged branches fromMERGEDtoNEED_UPGRADE_REBASE. SinceMERGEDis the terminal/read-only state used to represent a branch that has been merged (and should be treated as deleted from a user perspective), the upgrade effectively re-opens every previously merged branch and surfaces them as needing a rebase.Steps to reproduce
status = MERGED(set inbackend/infrahub/core/branch/tasks.py:410).infrahub upgradeagainst a database whosegraph_versionwas bumped (i.e. branches were created on the previous version).NEED_UPGRADE_REBASEand it shows up in the "branches that need to be rebased" list.Root cause
mark_branches_needing_rebaseiterates overBranch.get_list(...)filtering only the default branch andGLOBAL_BRANCH_NAME. Any branch whosegraph_version != GRAPH_VERSIONthen has its status overwritten unconditionally:Branches with terminal status (
MERGED,DELETING) are not excluded.Expected behavior
Merged (and deleting) branches must be treated as already gone.
infrahub upgradeshould leave their status alone — they should not be markedNEED_UPGRADE_REBASEand should not appear in the rebase list.Suggested fix
Skip branches in a terminal state. The codebase already has a helper for this:
Branch.is_terminalreturnsTrueforMERGEDandDELETING. Filter on it inmark_branches_needing_rebase(and also gate the status assignment, to be safe).