diff --git a/src/blenderbim/blenderbim/bim/module/ifcgit/__init__.py b/src/blenderbim/blenderbim/bim/module/ifcgit/__init__.py index eba6e3af33..5fde698280 100644 --- a/src/blenderbim/blenderbim/bim/module/ifcgit/__init__.py +++ b/src/blenderbim/blenderbim/bim/module/ifcgit/__init__.py @@ -28,7 +28,9 @@ classes = ( operator.DiscardUncommitted, operator.DisplayRevision, operator.DisplayUncommitted, + operator.Fetch, operator.Merge, + operator.Push, operator.RefreshGit, operator.SwitchRevision, prop.IfcGitTag, diff --git a/src/blenderbim/blenderbim/bim/module/ifcgit/data.py b/src/blenderbim/blenderbim/bim/module/ifcgit/data.py index d9d99fefd3..4373aa8df5 100644 --- a/src/blenderbim/blenderbim/bim/module/ifcgit/data.py +++ b/src/blenderbim/blenderbim/bim/module/ifcgit/data.py @@ -19,7 +19,10 @@ class IfcGitData: def load(cls): cls.data = { "repo": cls.repo(), + "remotes": cls.remotes(), "branch_names": cls.branch_names(), + "remote_names": cls.remote_names(), + "remote_urls": cls.remote_urls(), "path_ifc": cls.path_ifc(), "branches_by_hexsha": cls.branches_by_hexsha(), "tags_by_hexsha": cls.tags_by_hexsha(), @@ -42,10 +45,28 @@ class IfcGitData: return tool.IfcGit.repo_from_path(path_ifc) return None + @classmethod + def remotes(cls): + if cls.repo(): + return cls.repo().remotes + return None + @classmethod def branch_names(cls): return [] + @classmethod + def remote_names(cls): + return [] + + @classmethod + def remote_urls(cls): + result = {} + if cls.repo(): + for remote in cls.repo().remotes: + result[remote.name] = remote.url + return result + @classmethod def path_ifc(cls): path_ifc = tool.Ifc.get_path() diff --git a/src/blenderbim/blenderbim/bim/module/ifcgit/operator.py b/src/blenderbim/blenderbim/bim/module/ifcgit/operator.py index 1df3063755..38dfe2c681 100644 --- a/src/blenderbim/blenderbim/bim/module/ifcgit/operator.py +++ b/src/blenderbim/blenderbim/bim/module/ifcgit/operator.py @@ -246,3 +246,35 @@ class Merge(bpy.types.Operator): return {"FINISHED"} else: return {"CANCELLED"} + + +class Push(bpy.types.Operator): + """Pushes the working branch to selected remote""" + + bl_label = "Push working branch" + bl_idname = "ifcgit.push" + bl_options = {"REGISTER"} + + def execute(self, context): + + props = context.scene.IfcGitProperties + repo = IfcGitData.data["repo"] + remote = repo.remotes[props.select_remote] + remote.push() + return {"FINISHED"} + + +class Fetch(bpy.types.Operator): + """Fetches from the selected remote""" + + bl_label = "Fetch from remote" + bl_idname = "ifcgit.fetch" + bl_options = {"REGISTER"} + + def execute(self, context): + + props = context.scene.IfcGitProperties + repo = IfcGitData.data["repo"] + remote = repo.remotes[props.select_remote] + remote.fetch() + return {"FINISHED"} diff --git a/src/blenderbim/blenderbim/bim/module/ifcgit/prop.py b/src/blenderbim/blenderbim/bim/module/ifcgit/prop.py index 88fcd68aaa..7a1655be24 100644 --- a/src/blenderbim/blenderbim/bim/module/ifcgit/prop.py +++ b/src/blenderbim/blenderbim/bim/module/ifcgit/prop.py @@ -21,9 +21,25 @@ def git_branches(self, context): IfcGitData.data["branch_names"].remove("main") IfcGitData.data["branch_names"] = ["main"] + IfcGitData.data["branch_names"] + if IfcGitData.data["remotes"]: + props = context.scene.IfcGitProperties + IfcGitData.data["branch_names"] += [r.name for r in IfcGitData.data["remotes"][props.select_remote].refs] + return [(myname, myname, myname) for myname in IfcGitData.data["branch_names"]] +def git_remotes(self, context): + """remotes enum""" + + IfcGitData.data["remote_names"] = sorted([remote.name for remote in IfcGitData.data["remotes"]]) + + if "origin" in IfcGitData.data["remote_names"]: + IfcGitData.data["remote_names"].remove("origin") + IfcGitData.data["remote_names"] = ["origin"] + IfcGitData.data["remote_names"] + + return [(myname, myname, myname) for myname in IfcGitData.data["remote_names"]] + + def update_revlist(self, context): """wrapper to trigger update of the revision list""" @@ -109,6 +125,7 @@ class IfcGitProperties(PropertyGroup): subtype="DIR_PATH", ) display_branch: EnumProperty(items=git_branches, update=update_revlist) + select_remote: EnumProperty(items=git_remotes) ifcgit_filter: EnumProperty( items=[ ("all", "All", "All revisions"), diff --git a/src/blenderbim/blenderbim/bim/module/ifcgit/ui.py b/src/blenderbim/blenderbim/bim/module/ifcgit/ui.py index f9b67cfc7c..e9a8ba5dd8 100644 --- a/src/blenderbim/blenderbim/bim/module/ifcgit/ui.py +++ b/src/blenderbim/blenderbim/bim/module/ifcgit/ui.py @@ -154,13 +154,23 @@ class IFCGIT_PT_panel(bpy.types.Panel): # TODO # item.operator("ifcgit.delete_tag", icon="PANEL_CLOSE") - row = layout.row() + box = layout.box() + row = box.row() row.prop(props, "new_tag_name") - row = layout.row() + row = box.row() row.prop(props, "new_tag_message") - row = layout.row() + row = box.row() row.operator("ifcgit.add_tag", icon="GREASEPENCIL") + if IfcGitData.data["remotes"]: + row = layout.row() + row.prop(props, "select_remote", text="Select remote") + urls = IfcGitData.data["remote_urls"] + row.label(text=urls[props.select_remote]) + row = layout.row() + row.operator("ifcgit.push", icon="EXPERIMENTAL") + row.operator("ifcgit.fetch", icon="IMPORT") + class COMMIT_UL_List(bpy.types.UIList): """List of Git commits""" diff --git a/src/blenderbim/docs/users/git_support.rst b/src/blenderbim/docs/users/git_support.rst index 0379750d4f..5ddc8ef235 100644 --- a/src/blenderbim/docs/users/git_support.rst +++ b/src/blenderbim/docs/users/git_support.rst @@ -156,6 +156,39 @@ optional message text. Similar to commit messages, tag messages should be 50 characters or less, though there is no practical limit. +Remote operations +----------------- + +Git is a *distributed revision control system*, your local repository can be a +version of a remote repository and vice-versa. This is conceptually similar to +local branching except this remote repository could belong to someone else or +could be hosted by an online Git-forge service. + +Your repository can have multiple remote repositories registered, each +can have potentially multiple branches. + +BlenderBIM allows you to make a local *clone* of a remote repository. You will +need to provide a URL *origin* to fetch, and an empty local folder to become +the local repository. + +The *Fetch* operator retrieves new data from the remote repository. This isn't +automatically merged, each branch fetched from the remote repository appears as +a branch that can be browsed, switched-to or merged just like a local branch. +These remote branches have prefixed names, eg. `origin/main`. + +Once you have committed changes to your local repository, the *Push* operator +tries to update the remote branch using changes from the selected local branch. + +.. Warning:: + + Remote repositories can be accessed in multiple ways; ssh, ftp or https + protocols, for example, can require authentication. This authentication may + expect you to generate and upload ssh keys, store API tokens, save + username/password pairs, or use some other form of credential. + BlenderBIM can't configure these credentials for you, follow the + configuration instructions provided by your online service before trying + actions that require authentication. + Using other Git tools ---------------------