diff --git a/src/bonsai/bonsai/bim/module/ifcgit/__init__.py b/src/bonsai/bonsai/bim/module/ifcgit/__init__.py index d48f6e285d..ae946e4e9d 100644 --- a/src/bonsai/bonsai/bim/module/ifcgit/__init__.py +++ b/src/bonsai/bonsai/bim/module/ifcgit/__init__.py @@ -38,6 +38,7 @@ classes = ( operator.RefreshGit, operator.SwitchRevision, operator.InstallGit, + operator.RunGitDiff, prop.IfcGitTag, prop.IfcGitListItem, prop.IfcGitProperties, diff --git a/src/bonsai/bonsai/bim/module/ifcgit/operator.py b/src/bonsai/bonsai/bim/module/ifcgit/operator.py index de339c111c..4b71a33fa1 100644 --- a/src/bonsai/bonsai/bim/module/ifcgit/operator.py +++ b/src/bonsai/bonsai/bim/module/ifcgit/operator.py @@ -409,3 +409,25 @@ class InstallGit(bpy.types.Operator): core.install_git(tool.IfcGit, self) refresh() return {"FINISHED"} + + +class RunGitDiff(bpy.types.Operator): + """Run `git diff` for the current version of IFC file and the last saved one.""" + + bl_label = "Git Diff" + bl_idname = "ifcgit.git_diff" + bl_options = set() + + @classmethod + def poll(cls, context): + if not tool.Ifc.get(): + cls.poll_message_set("No IFC file loaded.") + return False + if not tool.Ifc.get_path(): + cls.poll_message_set("Current IFC file was never saved.") + return False + return True + + def execute(self, context): + core.run_git_diff(tool.IfcGit, self) + return {"FINISHED"} diff --git a/src/bonsai/bonsai/bim/module/ifcgit/ui.py b/src/bonsai/bonsai/bim/module/ifcgit/ui.py index b8d288c77b..760d719a60 100644 --- a/src/bonsai/bonsai/bim/module/ifcgit/ui.py +++ b/src/bonsai/bonsai/bim/module/ifcgit/ui.py @@ -283,3 +283,5 @@ class IFCGIT_PT_revision_inspector(bpy.types.Panel): "ifcgit.object_log", icon="TEXT", ) + row = layout.row() + row.operator("ifcgit.git_diff") diff --git a/src/bonsai/bonsai/core/ifcgit.py b/src/bonsai/bonsai/core/ifcgit.py index 404bd8df9b..6d37a5c5c9 100644 --- a/src/bonsai/bonsai/core/ifcgit.py +++ b/src/bonsai/bonsai/core/ifcgit.py @@ -142,3 +142,7 @@ def install_git(ifcgit: tool.IfcGit, operator: bpy.types.Operator) -> None: ifcgit.install_git_windows(operator=operator) else: print("install_git() not implemented") + + +def run_git_diff(ifcgit: tool.IfcGit, operator: bpy.types.Operator) -> None: + ifcgit.run_git_diff(operator) diff --git a/src/bonsai/bonsai/tool/ifcgit.py b/src/bonsai/bonsai/tool/ifcgit.py index 48dc212915..6b1c8c309d 100644 --- a/src/bonsai/bonsai/tool/ifcgit.py +++ b/src/bonsai/bonsai/tool/ifcgit.py @@ -570,6 +570,29 @@ class IfcGit: except FileNotFoundError: operator.report({"ERROR"}, "Winget is not available. Make sure Windows Package Manager is installed.") + @classmethod + def run_git_diff(cls, operator: bpy.types.Operator) -> None: + path = tool.Ifc.get_path() + ifc_file = tool.Ifc.get() + ifc_str = ifc_file.to_string() + + # Avoid `text=True` as it's causing issues with colorful output. + result = subprocess.run( + ("git", "diff", "--no-index", "--color=always", "--", path, "-"), + input=ifc_str.encode(), + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) + if result.returncode == 0: + operator.report({"INFO"}, "No changes since last save.") + return + elif result.returncode == 1: + print(result.stdout.decode()) + operator.report({"INFO"}, "See system console for git diff output.") + return + print(result) + raise Exception("Error running git diff, see system console.") + class IfcGitRepo: repo: git.Repo = None