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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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