async def fetch_master_subroutine(self, group_name: str): """Fetches any remote changes but doesn't do anything with them. """ server = self.get_server_routines().get_server() local_path = self.get_server_routines().local_path_for_type_registry( server.get_name(), group_name, self.get_typename()) server_url = self.get_server_routines( ).remote_path_for_entity_registry(group_name=group_name, type_name=self.get_typename()) if not RepoExists(local_path): raise RuntimeError("No local worktree.") repo = git.Repo(local_path) master_branch = None # check for branches and create local if needed. for branch in repo.heads: assert isinstance(branch, git.Head) if branch.name == "master": master_branch = branch if master_branch is None: raise RuntimeError("There is no master branch.") remote = create_update_remote(repo, server.get_name(), server_url) remote.fetch("master")
async def push_lfs_objects_subroutine(self, feedback_ui: AbstractFeedbackUI, branch: str): """Push lfs objects to the remote. lfs is smart about only pushing objects that need to be pushed. Failure will throw. Therefore, a succesful run of this subroutine guarontees lfs objects exist.""" server = self.get_server_routines().get_server() remote_url = self.get_remote_url() local_path = self.get_local_repo_path() await feedback_ui.output("Pushing LFS objects: " + local_path + " to: " + remote_url) if not RepoExists(local_path): await feedback_ui.error( "No local worktree. You might need to create or pull it first." ) return False repo = git.Repo(local_path) remote = create_update_remote(repo, server.get_name(), remote_url) assert isinstance(remote, git.Remote) push_output = repo.git.lfs("push", server.get_name(), branch) await feedback_ui.output(push_output) await feedback_ui.output("Done pushing LFS objects.")
async def remote_exists(self, feedback_ui: AbstractFeedbackUI) -> bool: server = self.get_server_routines().get_server() remote_url = self.get_remote_url() local_path = self.get_local_repo_path() repo = git.Repo(local_path) server_name = server.get_name() await feedback_ui.output("Updating remote " + server_name + " to: " + remote_url) create_update_remote(repo, server_name, remote_url) ret = exists(repo, server_name) if ret: await feedback_ui.output("Remote exists.") else: await feedback_ui.output("Remote doesn't exist.") return ret
async def is_behind_remote(self, feedback_ui: AbstractFeedbackUI) -> bool: server = self.get_server_routines().get_server() remote_url = self.get_remote_url() local_path = self.get_local_repo_path() repo = git.Repo(local_path) server_name = server.get_name() await feedback_ui.output("Updating remote " + server_name + " to: " + remote_url) create_update_remote(repo, server_name, remote_url) commits_behind = get_commits_behind(repo, "master", server_name) ret = len(commits_behind) != 0 if ret: await feedback_ui.output("Local is behind Remote") else: await feedback_ui.output("Local is up to date.") return ret
async def push_commits_subroutine(self, feedback_ui, group_name): server = self.get_server_routines().get_server() server_url = self.get_server_routines( ).remote_path_for_entity_registry(group_name=group_name, type_name=self.get_typename()) local_path = self.get_server_routines().local_path_for_type_registry( server.get_name(), group_name, self.get_typename()) repo = git.Repo(local_path) # we push to the server even if there was no commit because this is a "push" command. Server could be behind for other reasons. remote = create_update_remote(repo, server.get_name(), server_url) #this could fail if you don't have permission to write container changes. And that's okay because securityis handled by gitlab after all. remote.push("master")
async def pull_sub_routine(self, feedback_ui: AbstractFeedbackUI, branch: str) -> bool: server = self.get_server_routines().get_server() local_repo_path = self.get_local_repo_path() remote_url = self.get_remote_url() await feedback_ui.output("Pulling: " + local_repo_path + " from: " + remote_url) if RepoExists(local_repo_path): repo = git.Repo(local_repo_path) remote = create_update_remote(repo, "origin", remote_url) remote = create_update_remote(repo, server.get_name(), remote_url) assert isinstance(remote, git.Remote) await feedback_ui.output(("Pulling " + branch + ": " + local_repo_path + " <- " + remote_url)) remote.pull(branch) return True else: await feedback_ui.error( "Local repository doesn't exist. Cannot pull. You might want to clone it or init it?" ) return False
async def clone_local_routine(self, feedback_ui: AbstractFeedbackUI, group_name: str, source_server_name: str): server = self.get_server_routines().get_server() server_routines = self.get_server_routines() local_path = server_routines.local_path_for_type_registry( server.get_name(), group_name, self.get_typename()) source_server_routines = GitLabServerRoutines(source_server_name) source_local_path = source_server_routines.local_path_for_type_registry( source_server_name, group_name, self.get_typename()) os.makedirs(local_path, exist_ok=True) git.Repo.clone_from(source_local_path, local_path) #we push now, because we want to create it ASAP, or fail trying. repo = git.Repo(local_path) server_url = server_routines.remote_path_for_entity_registry( group_name=group_name, type_name=self.get_typename()) remote = create_update_remote(repo, server.get_name(), server_url) #this could fail if you don't have permission to write container changes. And that's okay because securityis handled by gitlab after all. And we don't want to diverge from the net either. push_output = repo.git.push(server_routines.get_server_name(), 'master') await feedback_ui.output(push_output)
async def push_sub_routine(self, feedback_ui: AbstractFeedbackUI, branch: str, fail_on_dirty: bool) -> bool: """Meant to be called by other routines. Provides feedback. Returns True on success, False on failure.""" server = self.get_server_routines().get_server() remote_url = self.get_remote_url() local_path = self.get_local_repo_path() await feedback_ui.output("Pushing: " + local_path + " to: " + remote_url) if not RepoExists(local_path): await feedback_ui.error( "No local worktree. You might need to create or pull it first." ) return False repo = git.Repo(local_path) if repo.is_dirty(index=True, working_tree=True, untracked_files=True, submodules=True) and fail_on_dirty: await feedback_ui.error("Worktree is dirty. Aborting.") return False # we push to the server even if there was no commit because this is a "push" command. # this works for submodules too, we think. Maybe? remote = create_update_remote(repo, server.get_name(), remote_url) assert isinstance(remote, git.Remote) await feedback_ui.output("Pushing " + branch + ": " + local_path + " -> " + remote_url) remote.push(branch) return True