Git remote fetch and push operations (#3096)

This commit is contained in:
Bruno Postle
2023-05-19 00:27:37 +01:00
parent 894a688bd8
commit 88ba6514e8
6 changed files with 118 additions and 3 deletions
@@ -28,7 +28,9 @@ classes = (
operator.DiscardUncommitted,
operator.DisplayRevision,
operator.DisplayUncommitted,
operator.Fetch,
operator.Merge,
operator.Push,
operator.RefreshGit,
operator.SwitchRevision,
prop.IfcGitTag,
@@ -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()
@@ -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"}
@@ -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"),
@@ -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"""
+33
View File
@@ -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
---------------------