Putting TMDL Under Source Control
A semantic model saved as a single .bim JSON file is technically "in Git,"
but nobody is reviewing a 4,000-line JSON diff in a pull request. TMDL
(Tabular Model Definition Language) exists specifically to fix that: it's a
folder-per-table, file-per-object format designed to be read and diffed by
humans, not just tools.
The layout that makes diffs readable
definition/
database.tmdl
model.tmdl
tables/
Sales.tmdl
Date.tmdl
Product.tmdl
relationships.tmdl
cultures/
en-US.tmdl
One table, one file. When a teammate adds a measure to Sales, the pull
request touches tables/Sales.tmdl and nothing else — no more "why did the
entire model file change because of one DAX edit."
A measure, as TMDL actually writes it
measure 'Total Sales' = SUMX ( Sales, Sales[Quantity] * Sales[Unit Price] )
formatString: $#,##0.00
displayFolder: Financials
That's the whole diff for adding a measure. Compare that to the equivalent
change in a .bim file, where the same edit is buried inside a nested JSON
array and Git's line-based diff can't tell you anything useful about what
changed.
Getting there from Power BI Desktop
Enable the Power BI Desktop developer mode / PBIP (Power BI Project) format,
which saves the report as a folder including a .SemanticModel directory —
that's where the TMDL definition lives. Point Git at the project root, and
treat the .SemanticModel folder like application source code: branch it,
review it, and let CI validate it before it reaches production.