Skip to content

bug: infrahub upgrade resets MERGED branches to NEED_UPGRADE_REBASE, effectively re-opening them #9103

@fatih-acar

Description

@fatih-acar

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

  1. Create a branch, make changes, merge it. The branch ends up with status = MERGED (set in backend/infrahub/core/branch/tasks.py:410).
  2. Run infrahub upgrade against a database whose graph_version was bumped (i.e. branches were created on the previous version).
  3. 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).

Metadata

Metadata

Assignees

No one assigned

    Labels

    type/bugSomething isn't working as expected

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions