Component
Git Integration
Infrahub version
1.9.6
Current Behavior
A read-write CoreRepository whose default_branch is not main (e.g. default_branch=staging) never imports new commits on its default branch via the periodic sync. The instance stays pinned to its last-imported commit while reporting sync_status: in-sync; new commits on the git default branch are silently never applied.
The periodic git_repositories_sync flow fails on every cycle with:
RepositoryError: Unable to get worktree : staging
ValueError: Unable to identify the worktree for the branch : staging
→ Flow run Finished in state Failed(...)
Expected Behavior
The periodic sync should use the repository's configured default_branch and import new commits on it into the instance's main (advancing CoreRepository.commit). It must never silently report in-sync while pinned to a stale commit.
Steps to Reproduce
- Deploy Infrahub 1.9.6.
- Add a read-write
CoreRepository and set default_branch to a non-main branch (e.g. staging) via CoreRepositoryCreate.
- Let it import (commit = C0).
- Push a new commit to the git
staging branch.
- Observe:
git_repositories_sync fails with Unable to identify the worktree for the branch : staging; CoreRepository.commit stays at C0; sync_status stays in-sync. The new commit is never imported.
Additional Information
Root cause
get_repositories_commit_per_branch (backend/infrahub/git/utils.py, ~line 40) does not request the default_branch attribute when it loads repositories for the sync flow:
repos = await NodeManager.query(
db=db, branch=branch, schema=kind, order=OrderModel(disable=True),
fields={"id": None, "name": None, "commit": None,
"internal_status": None, "location": None, "ref": None},
# ^^^ "default_branch" is missing
)
Because the attribute is not fetched, repository.default_branch.value in sync_remote_repositories (backend/infrahub/git/tasks.py, ~line 262/301) returns the schema default "main" (backend/infrahub/core/schema/definitions/core/repository.py, default_value="main") instead of the configured value. The repository is initialised with default_branch_name="main", so self.default_branch == "main" for the whole sync.
That breaks the default-branch → worktree mapping in pull() (backend/infrahub/git/base.py):
identifier = branch_name # "staging"
if branch_name == self.default_branch and branch_name != registry.default_branch:
identifier = "main" # ← skipped: self.default_branch is "main"
repo = self.get_git_repo_worktree(identifier="staging") # ← no worktree keyed "staging" → RepositoryError
The default branch's worktree is keyed main; with the wrong default_branch the code looks up a worktree named after the git branch (staging), which does not exist, and the flow raises.
Corroborating evidence (all consistent with self.default_branch == "main"):
validate_remote_branch logs Merging staging into main has no conflicts — it calls has_conflicting_changes(target_branch=self.default_branch, source="staging"), and the target is logged as main.
git_repositories_sync flow runs are all FAILED with the worktree : staging ValueError.
- A manual
git pull origin staging inside the worker's worktree fast-forwards cleanly — git, refspec, and credentials are all healthy; only the in-process default_branch is wrong.
- An instance with
default_branch=main is unaffected (the accidental default is correct).
Fix (verified)
Add default_branch to the fetched fields in get_repositories_commit_per_branch:
fields={"id": None, "name": None, "commit": None, "internal_status": None,
"location": None, "ref": None, "default_branch": None},
Verified live on 1.9.6: with this single change, the previously-stuck instance imported a fresh commit on its non-main default branch within ~30 s, the git_repositories_sync flow returned Completed, and the worktree : staging error disappeared. Without it, the instance stayed stuck across many cycles with FAILED sync flows.
Scope & relation to other issues
Component
Git Integration
Infrahub version
1.9.6
Current Behavior
A read-write
CoreRepositorywhosedefault_branchis notmain(e.g.default_branch=staging) never imports new commits on its default branch via the periodic sync. The instance stays pinned to its last-imported commit while reportingsync_status: in-sync; new commits on the git default branch are silently never applied.The periodic
git_repositories_syncflow fails on every cycle with:Expected Behavior
The periodic sync should use the repository's configured
default_branchand import new commits on it into the instance'smain(advancingCoreRepository.commit). It must never silently reportin-syncwhile pinned to a stale commit.Steps to Reproduce
CoreRepositoryand setdefault_branchto a non-mainbranch (e.g.staging) viaCoreRepositoryCreate.stagingbranch.git_repositories_syncfails withUnable to identify the worktree for the branch : staging;CoreRepository.commitstays at C0;sync_statusstaysin-sync. The new commit is never imported.Additional Information
Root cause
get_repositories_commit_per_branch(backend/infrahub/git/utils.py, ~line 40) does not request thedefault_branchattribute when it loads repositories for the sync flow:Because the attribute is not fetched,
repository.default_branch.valueinsync_remote_repositories(backend/infrahub/git/tasks.py, ~line 262/301) returns the schema default"main"(backend/infrahub/core/schema/definitions/core/repository.py,default_value="main") instead of the configured value. The repository is initialised withdefault_branch_name="main", soself.default_branch == "main"for the whole sync.That breaks the default-branch → worktree mapping in
pull()(backend/infrahub/git/base.py):The default branch's worktree is keyed
main; with the wrongdefault_branchthe code looks up a worktree named after the git branch (staging), which does not exist, and the flow raises.Corroborating evidence (all consistent with
self.default_branch == "main"):validate_remote_branchlogsMerging staging into main has no conflicts— it callshas_conflicting_changes(target_branch=self.default_branch, source="staging"), and the target is logged asmain.git_repositories_syncflow runs are allFAILEDwith theworktree : stagingValueError.git pull origin staginginside the worker's worktree fast-forwards cleanly — git, refspec, and credentials are all healthy; only the in-processdefault_branchis wrong.default_branch=mainis unaffected (the accidental default is correct).Fix (verified)
Add
default_branchto the fetched fields inget_repositories_commit_per_branch:Verified live on 1.9.6: with this single change, the previously-stuck instance imported a fresh commit on its non-
maindefault branch within ~30 s, thegit_repositories_syncflow returnedCompleted, and theworktree : stagingerror disappeared. Without it, the instance stayed stuck across many cycles withFAILEDsync flows.Scope & relation to other issues
maindefault_branchread-write repos;default_branch=mainis immune.maindefault_branchfamily as bug: Artifact generation fails for read-write repositories when default branch is not "main" #8749 (artifact generation) and bug: merge to non-main default_branch silently dropped on multi-worker pools #9568 (multi-worker write-back/push), but a distinct mechanism: this is the import/pull path and the wrong value comes from an under-fetched attribute. bug: Git merge skipped if Proposed Change merged before repo sync completes #9499 (merge skipped before sync) and bug: task workers diverge when upstream commit lands between sync start and fan-out git pulls #9349 (closed; multi-worker divergence) are unrelated code paths.