How does branching work in the parent repo?

Here is my scenario and I’d like to better understand if this is working correctly and why.

  1. I have a parent repo and module repo both synced to their respective main branch.
  2. I then checkout a feature branch off the parent main branch.
  3. New files are committed to the module main branch.
  4. I do a pull on the parent feature branch expecting the new module files to appear since I assumed it was also still synced to the module main branch. But the new files don’t appear.

Thanks for any help!

Hello Ted,
when you checkout a feature branch off the parent main branch, the module in it becomes fixed, i.e. pegged to a specific module commit instead of tracking the module branch. It stays in this state until you explicitly set it up to follow some branch.

Why does gitx.dev have this behaviour?
This is because usually when someone checks out a new branch, especially not from the latest commit but from some older commit, the user expects this new branch to be a snapshot of that commit. Otherwise, if you would checkout a new branch from older commit and gitx.dev were set up the module branch, it would then apply all the newer module commits since that older state. It’s very likely that they would be inconsistent with the parent content, leading to compilation errors. That’s why we decided to make it the user’s responsibility to apply the newer module commits manually.

How is it reflected in the UI?
If you open your parent repository page on gitx.dev and switch the branch to the feature branch and pay attention to “Module Location” section, you’ll see that the branch is not selected there. This means that the module in this branch points to a fixed commit. Once you change this branch to some branch, e.g. to the main branch of the module repository, the module will receive newer commits from the module repository (if there’re any) and follow the module’s branch. In other words, they will become in sync again.

The mental model
Internally, the module settings (they are per commit, i.e. each commit in the parent repository has its own settings) contain something that we call “module rules”. The module rules look like

if this commit is reached from branch X, then the module should follow branch Y in repository Z

or

if this commit is reached from branch X, then the module should be fixed to commit with that SHA-1

Originally when ‘main’ branch in the parent repository had a module tracking ‘main’ branch in the module repository, you had the following settings:

if this commit is reached from 'main' branch in parent, then the module should follow 'main' branch in the module repository

This rule was applicable when you had ‘main’ branch in the parent. Once you created a feature branch, the same setting became not applicable because “if this commit is reached from ‘main’ branch” is not true in the feature branch. When no rule is applicable, no synchronization happens. But if you edit the “Module Location” in the UI to specify to some branch (e.g. ‘main’ branch in the module repository), you’ll implicitly add the rule:

if this commit is reached from 'feature' branch in parent, then the module should follow 'main' branch in the module repository

Then the synchronization is enabled again.

These branch rules may seem to be an overcomplication, but they are not. We plan to extend the UI to edit the rules more explicitly. This would allow to use masks in the branch rules like:

if this commit is reached from 'feature-*' branch in parent, then the module should follow 'some-*' branch in the module repository

where “*” can be any substring not containing slash(/) or forbidden character. In this example, the module from “feature-10” branch in parent will track “some-10” branch of the module repository, and “feature-xxx” branch in parent will track “some-xxx” branch of the module repository, etc.

1 Like

Thanks for the very detailed explanation. This makes perfect sense.

The reason we are evaluating X-Modules is for this exact scenario. We have an infrastructure module that we’d like to be able to update and then have it applied to all active feature branches in the main repo. Currently this is all in a monorepo so each of the feature branches have to be rebased after the infrastructure change. Since some of the feature branches might be off an epic branch that would also have to be rebased prior to any child features being rebased. With 15-20 features typically in development at once this can become pretty cumbersome to maintain.

It sounds like with X-Modules we’d just have to go into each of the feature branches in the UI and reselect the correct module branch.

Yes, and once we implement “advanced module rules” editor UI, you’ll be able to use a rule containing an asterisk (refs/heads/*) applying automatically to all the branches you’ll ever create, without having to select correct module manually.