Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Shape the future of the Fabric Community! Your insights matter. That’s why we created a quick survey to learn about your experience finding answers to technical questions. Take survey.

Reply
The_PBI_Chef
Regular Visitor

Power BI developer mode (.pbip) merge conflict issues

I'm trying to implement version control in PBI using .pbip files, but I have an issue. When I create 2 different branches from main, and create one DAX measure in each of these branches, I can only merge one of those branches back to main. When I try to merge the other, I get a merge conflict. It seems that model.bim gets edited on the same lines in both of these branches (doesn't matter that the measures are named differently). Does this mean that every time 2+ developers make changes on their branches from the same main branch, the only way to merge both of these branches back is to use VSCode (for example) and edit model.bim manually?

8 REPLIES 8
v-yiruan-msft
Community Support
Community Support

Hi @The_PBI_Chef ,

When using Power BI’s developer mode with .pbip files, the model.bim file can indeed cause merge conflicts when multiple developers are making changes on their own branches. This is because the model.bim file contains the metadata for your Power BI project, including all tables, columns, measures, and relationships. When two developers add different measures on their own branches, these changes are likely to occur on the same lines in the model.bim file, leading to a merge conflict. To resolve this issue, you would indeed need to manually resolve the conflicts in a text or code editor like Visual Studio Code. This process involves comparing the changes between the two versions of the model.bim file and deciding which changes to keep.

Power BI Desktop projects (PBIP) - Power BI | Microsoft Learn

It’s important to note that this is a common challenge when working with version control systems and isn’t unique to Power BI. It’s always a good practice for teams to communicate well and coordinate their work to minimize the occurrence of such conflicts. Also, frequent commits and pulls from the main branch can help keep everyone’s local copies up-to-date and reduce the likelihood of conflicts.

Best Regards

Community Support Team _ Rena
If this post helps, then please consider Accept it as the solution to help the other members find it more quickly.

@v-yiruan-msft That's true, but you left something out. I've been working with version control in Power BI since it was introduced and released last summer. And it has one problem that should have been solved before the release, but hasn't been solved yet. If any changes were made to the pbip. file, no matter what, Power BI will randomly swap different code blocks that have nothing to do with the changes made. And this is actually a big pain in the ass, because it basically not only breaks the whole concept of version control but also leads to unjustified conflicts any time you are trying to merge changes.

Let me know if you find a solution to this problem. Right now its really stopping me from fully using versioning, because I need to do a manual copy-over merge every now and then.

I'm still not aware of any solutions to this problem. Every release becomes hell and comes down to numerous merges/cherry picks flavored with manual edits.

That sounds awful.
During my research on this issue, I found this "project" to improve exactly the sorting issues we are experiencing.
I haven't checked in detail, but maybe this is relevant and might even be a viable workaround:
https://richardswinbank.net/ssas/ssas_tabular_merge_conflicts

Do let me know if this could work

@sausaged Thanks a lot for sharing this! In essence model.bim turned out to be a json file, so we can actually play around with its content just as with report.json. I took the idea you shared as a basis and wrote my own simple Python code that sorts the contents of all nested structures, just because it's easier for us to maintain it in Python rather than with shell. We've been testing this approach for a couple of weeks now and I must say that now if conflicts do arise, they are intuitive and resolved in the code editor, so thank you again.

@igorplotnikov That's great to hear. Are you able to share a working version of this python script? This might be helpful for many users!

@sausaged Sure. Below is the version that works for us so far:

 

import json
import sys



def process(obj):
    """
    Recursively sorts lists containing dictionaries with the 'name' attribute by the 'name' key,
    and strips trailing \r from string values.
    """
    if isinstance(obj, list):
        # If all elements are dictionaries with a 'name' key, sort them
        if all(isinstance(item, dict) and 'name' in item for item in obj):
            # Sort the list of dictionaries by the 'name' key and recursively process each item in the list
            return sorted([process(item) for item in obj], key=lambda x: x['name'])
        else:
            # Recursively process each item in the list
            return [process(item) for item in obj]
    elif isinstance(obj, dict):
        # Recursively process each value in the dictionary
        return {key: process(value) for key, value in obj.items()}
    elif isinstance(obj, str):
        # Strip trailing \r from strings
        return obj.rstrip('\r')
    else:
        return obj


def main():
    # Check if filename is provided as command-line argument
    if len(sys.argv) < 2:
        print("Usage: python reorder_content.py <file_name>")
        sys.exit(1)
    # Get filename from command-line argument
    file_name = sys.argv[1]
    try:
        with open(file_name, 'r') as file:
            content = json.load(file)
        processed_content = process(content)
        with open(file_name, 'w') as file:
            json.dump(processed_content, file, indent=4)
        print(f"Processed {file_name}")
    except FileNotFoundError:
        print(f"File not found: {file_name}")
    except json.JSONDecodeError:
        print(f"Error decoding JSON in file: {file_name}")


if __name__ == '__main__':
    main()

 

The script should be located at `.\pre-commit\reorder-content.py` and triggered by `.\.git\hooks\pre-commit` content of which is as follows:

 

#!/bin/bash

FILE="./[Project Name].SemanticModel/model.bim"
python.exe ./pre-commit/reorder-content.py "$FILE"
git add "$FILE"

 

 Don't forget to substitute [Project Name] respectively in the pre-commit script.

Helpful resources

Announcements
November Carousel

Fabric Community Update - November 2024

Find out what's new and trending in the Fabric Community.

Dec Fabric Community Survey

We want your feedback!

Your insights matter. That’s why we created a quick survey to learn about your experience finding answers to technical questions.

Live Sessions with Fabric DB

Be one of the first to start using Fabric Databases

Starting December 3, join live sessions with database experts and the Fabric product team to learn just how easy it is to get started.