Skip to content

bug: explicit branch is discarded when default_branch_from_git is enabled #1295

Description

@pthmas

Component

Python SDK, infrahubctl

Infrahub SDK version

1.23.0

Current Behavior

When default_branch_from_git is enabled, a branch supplied as an argument is discarded and the
local Git branch is used instead. This affects both client.clone(branch=...) and --branch on
the command line.

The requested branch is not carried as a request. infrahub_sdk/ctl/client.py:71-72 writes it
into the config field that the flag governs:

if branch:
    client_config["default_branch"] = branch

ConfigBase.default_infrahub_branch, infrahub_sdk/config.py:224, then ignores that field
whenever the flag is on:

branch: str | None = None
if not self.default_branch_from_git:
    branch = self.default_branch
return get_branch(branch=branch)

default_branch carries two different meanings — "configured fallback" and "the branch this
caller asked for" — and the flag cannot tell them apart, so the requested value is dropped at
InfrahubClient.__init__, infrahub_sdk/client.py:199. Config.clone,
infrahub_sdk/config.py:285, loses its branch argument the same way, since it copies
default_branch_from_git through and the new client recomputes from it.

The result is a client whose default_branch is the local Git branch. Any call that does not
pass a branch explicitly then targets that branch: client.get, client.create, node saves,
start_tracking, and anything user generator or transform code does.

For generators and transforms this splits a single run across two branches. The operation's
branch_name holds the requested branch, so calls that pass it explicitly are correct, while
its client defaults to the Git branch:

local Git branch                : issue-1290
transform.branch_name           : test
transform client default_branch : issue-1290

A generator invoked with --branch test under this flag reads from test and writes to the
local Git branch, with no error.

Both InfrahubClient and InfrahubClientSync are affected.

Expected Behavior

A branch supplied as an argument is honoured regardless of default_branch_from_git. The flag
governs what to target when no branch was requested; it is not expected to override one that was.

A single generator or transform run targets one branch for both reads and writes.

Steps to Reproduce

No server required:

from infrahub_sdk import Config, InfrahubClient
from infrahub_sdk.node import InfrahubNode
from infrahub_sdk.transforms import InfrahubTransform
from infrahub_sdk.utils import get_branch


class T(InfrahubTransform):
    query = "q"

    def transform(self, data: dict) -> dict:
        return data


client = InfrahubClient(
    config=Config(address="http://mock", default_branch="main", default_branch_from_git=True)
)

print(get_branch())                                 # local Git branch
print(client.clone(branch="test").default_branch)   # local Git branch, not "test"

transform = T(client=client, infrahub_node=InfrahubNode, branch="test")
print(transform.branch_name)                        # "test"
print(transform._init_client.default_branch)        # local Git branch

Equivalent via the CLI:

  1. export INFRAHUB_DEFAULT_BRANCH_FROM_GIT=true
  2. Put the local Git checkout on a branch that differs from the target Infrahub branch
  3. Run any generator with infrahubctl generator <name> --branch test <var>=<value>
  4. Nodes are created on the Git branch rather than on test

Additional Information

Found while fixing #1290 and deliberately left out of its fix (#1293), which addresses the
opposite case: no branch requested, flag off. That fix does not change this behaviour — a branch
passed as an argument was dropped identically before it.

Silent divergence rather than an error is the notable part: the run appears to succeed and writes
land on the wrong branch.

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