def test_simple(self): outstream = BytesIO() errstream = BytesIO() # create a file for initial commit handle, fullpath = tempfile.mkstemp(dir=self.repo.path) os.close(handle) filename = os.path.basename(fullpath) porcelain.add(repo=self.repo.path, paths=filename) porcelain.commit(repo=self.repo.path, message=b"test", author=b"test", committer=b"test") # Setup target repo target_path = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, target_path) target_repo = porcelain.clone(self.repo.path, target=target_path, errstream=errstream) # create a second file to be pushed handle, fullpath = tempfile.mkstemp(dir=self.repo.path) os.close(handle) filename = os.path.basename(fullpath) porcelain.add(repo=self.repo.path, paths=filename) porcelain.commit(repo=self.repo.path, message=b"test2", author=b"test2", committer=b"test2") self.assertFalse(self.repo[b"HEAD"].id in target_repo) target_repo.close() # Fetch changes into the cloned repo porcelain.fetch(target_path, self.repo.path, outstream=outstream, errstream=errstream) # Check the target repo for pushed changes with closing(Repo(target_path)) as r: self.assertTrue(self.repo[b"HEAD"].id in r)
def test_simple(self): outstream = BytesIO() errstream = BytesIO() # create a file for initial commit handle, fullpath = tempfile.mkstemp(dir=self.repo.path) filename = os.path.basename(fullpath) porcelain.add(repo=self.repo.path, paths=filename) porcelain.commit(repo=self.repo.path, message='test', author='test', committer='test') # Setup target repo target_path = tempfile.mkdtemp() target_repo = porcelain.clone(self.repo.path, target=target_path, outstream=outstream) # create a second file to be pushed handle, fullpath = tempfile.mkstemp(dir=self.repo.path) filename = os.path.basename(fullpath) porcelain.add(repo=self.repo.path, paths=filename) porcelain.commit(repo=self.repo.path, message='test2', author='test2', committer='test2') self.assertFalse(self.repo['HEAD'].id in target_repo) # Fetch changes into the cloned repo porcelain.fetch(target_path, self.repo.path, outstream=outstream, errstream=errstream) # Check the target repo for pushed changes r = Repo(target_path) self.assertTrue(self.repo['HEAD'].id in r)
def test_simple(self): outstream = BytesIO() errstream = BytesIO() # create a file for initial commit handle, fullpath = tempfile.mkstemp(dir=self.repo.path) filename = os.path.basename(fullpath) porcelain.add(repo=self.repo.path, paths=filename) porcelain.commit(repo=self.repo.path, message=b'test', author=b'test', committer=b'test') # Setup target repo target_path = tempfile.mkdtemp() target_repo = porcelain.clone(self.repo.path, target=target_path, errstream=errstream) # create a second file to be pushed handle, fullpath = tempfile.mkstemp(dir=self.repo.path) filename = os.path.basename(fullpath) porcelain.add(repo=self.repo.path, paths=filename) porcelain.commit(repo=self.repo.path, message=b'test2', author=b'test2', committer=b'test2') self.assertFalse(self.repo[b'HEAD'].id in target_repo) # Fetch changes into the cloned repo porcelain.fetch(target_path, self.repo.path, outstream=outstream, errstream=errstream) # Check the target repo for pushed changes r = Repo(target_path) self.assertTrue(self.repo[b'HEAD'].id in r)
def update_app(self, _=None): """Perform app update.""" assert self._git_url is not None with self._show_busy(): fetch(repo=self._repo, remote_location=self._git_url) tracked_branch = self._repo.get_tracked_branch() check_output(['git', 'reset', '--hard', tracked_branch], cwd=self.path, stderr=STDOUT) self.refresh_async()
def check_branches(): repo = porcelain.open_repo(database) porcelain.fetch(repo) head_id = repo[b'refs/heads/master'].id origin_id = repo[b'refs/remotes/origin/master'].id if head_id == origin_id: print("Branches are the same ...") return True else: print("Branches diverge ...") return False
def git_reset_repo_to_origin(): try: repo = porcelain.Repo(database) porcelain.fetch(repo) tree_head_id = repo[repo[b'refs/heads/master'].tree].id tree_origin_master_id = repo[ repo[b'refs/remotes/origin/master'].tree].id store = repo.object_store list_all_files_head = list_all_files(store, tree_head_id) list_all_files_origin_master = list_all_files(store, tree_origin_master_id) deleted_files = list( set(list_all_files_head) - set(list_all_files_origin_master)) # print(deleted_files) if deleted_files != []: for all in deleted_files: file_path = os.path.join(database, all.decode('utf-8')) os.remove(file_path) status = porcelain.status(repo) repo.stage(status.unstaged) porcelain.commit(repo, message="delete files") ###working### porcelain.reset(repo, "hard", treeish=b"refs/remotes/origin/master") porcelain.clean(repo=repo, target_dir=database) resolve_divergence() ######## return True except MaxRetryError: print('MaxRetryError') return False except ProtocolError: print('ProtocolError') return False
def test_with_remote_name(self): remote_name = b'origin' outstream = BytesIO() errstream = BytesIO() # create a file for initial commit handle, fullpath = tempfile.mkstemp(dir=self.repo.path) os.close(handle) porcelain.add(repo=self.repo.path, paths=fullpath) porcelain.commit(repo=self.repo.path, message=b'test', author=b'test <email>', committer=b'test <email>') # Setup target repo target_path = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, target_path) target_repo = porcelain.clone(self.repo.path, target=target_path, errstream=errstream) # Capture current refs target_refs = target_repo.get_refs() # create a second file to be pushed handle, fullpath = tempfile.mkstemp(dir=self.repo.path) os.close(handle) porcelain.add(repo=self.repo.path, paths=fullpath) porcelain.commit(repo=self.repo.path, message=b'test2', author=b'test2 <email>', committer=b'test2 <email>') self.assertFalse(self.repo[b'HEAD'].id in target_repo) target_repo.close() # Fetch changes into the cloned repo porcelain.fetch(target_path, self.repo.path, remote_name=remote_name, outstream=outstream, errstream=errstream) # Assert that fetch updated the local image of the remote self.assert_correct_remote_refs( target_repo.get_refs(), self.repo.get_refs()) # Check the target repo for pushed changes, as well as updates # for the refs with Repo(target_path) as r: self.assertTrue(self.repo[b'HEAD'].id in r) self.assertNotEqual(self.repo.get_refs(), target_refs)
def new(self, org: bool = False) -> int: """ Create a new GitHub repository for this project. :param org: Whether the repository should be created for the organization set as ``username``, or for the authenticated user (default). :rtype: .. versionchanged:: 0.3.0 * Removed the ``verbose`` option. Provide it to the class constructor instead. * Added the ``org`` argument. """ with self.echo_rate_limit(): user = self.get_org_or_user(org) repo_name = self.templates.globals["repo_name"] repo: Optional[repos.Repository] if org: repo = user.create_repository(repo_name, **self.get_repo_kwargs()) else: repo = self.github.create_repository(repo_name, **self.get_repo_kwargs()) if repo is None: raise ErrorCreatingRepository(user.login, repo_name, org=org) self.update_topics(repo) click.echo(f"Success! View the repository online at {repo.html_url}") try: dulwich_repo = Repo(self.target_repo) except NotGitRepository: return 0 config = dulwich_repo.get_config() config.set(("remote", "origin"), "url", repo.ssh_url.encode("UTF-8")) config.set(("remote", "origin"), "fetch", b"+refs/heads/*:refs/remotes/origin/*") config.write_to_path() fetch(dulwich_repo, remote_location="origin") return 0
def __pull_beq(repo, local_dir): ''' pulls the git repo but does not use dulwich pull as it has file lock issues on windows ''' from dulwich import porcelain, index with porcelain.open_repo_closing(local_dir) as local_repo: remote_refs = porcelain.fetch(local_repo, repo) local_repo[b"HEAD"] = remote_refs[b"refs/heads/master"] index_file = local_repo.index_path() tree = local_repo[b"HEAD"].tree index.build_index_from_tree(local_repo.path, index_file, local_repo.object_store, tree)
def _update_app(self, _): """Perform app update.""" cannot_modify = self.cannot_modify_app() if cannot_modify: self.install_info.value = """<i class="fa fa-times" style="color:red;font-size:4em;" > </i>Can not update the repository: {}""".format(cannot_modify) sleep(3) self.install_info.value = '' return self.install_info.value = """<i class="fa fa-spinner fa-pulse" style="color:#337ab7;font-size:4em;" ></i> <font size="1"><blink>Updating the app...</blink></font>""" fetch(repo=self.repo, remote_location=self._git_url) pull(repo=self.repo, remote_location=self._git_url, refspecs=self.version.selected.label) self.install_info.value = """<i class="fa fa-check" style="color:#337ab7;font-size:4em;" ></i> <font size="1">Success</font>""" self._refresh_update_button() sleep(1) self.install_info.value = ''
def __init__(self, url): """ initialize dulwich magic """ self.repo_url = url # We have two repository handles, one for reading and one for writing. self.rorepo = MemoryRepo() self.rwrepo = MemoryRepo() self.rorepo.refs.set_symbolic_ref(b'HEAD', b'refs/heads/master') self.rwrepo.refs.set_symbolic_ref(b'HEAD', b'refs/heads/master') porcelain.fetch(self.rorepo, self.repo_url) porcelain.fetch(self.rwrepo, self.repo_url) self.rorepo[b'refs/heads/master'] = self.rorepo[ b'refs/remotes/origin/master'] self.rwrepo[b'refs/heads/master'] = self.rwrepo[ b'refs/remotes/origin/master'] self.rotree = self.rorepo[self.rorepo[b'HEAD'].tree] self.rwtree = self.rwrepo[self.rwrepo[b'HEAD'].tree]
def git_fetch(args): parser = argparse.ArgumentParser( prog='git fetch', usage= 'git fetch [http(s)://<remote repo> or remotename] [-u username[:password]]', description="Push to a remote repository") parser.add_argument('url', type=str, nargs='?', help='URL to push to') parser.add_argument('-u', metavar='username[:password]', type=str, required=False, help='username[:password]') result = parser.parse_args(args) repo = _get_repo() origin = 'origin' if not result.url: result.url = repo.remotes.get('origin', '') if result.url in repo.remotes: origin = result.url result.url = repo.remotes.get(origin) if not urlparse.urlparse(result.url).scheme: raise Exception( 'url must match a remote name, or must start with http:// or https://' ) print('Starting fetch, this could take a while') remote_refs = porcelain.fetch(repo.repo.path, result.url) print('Fetch successful. Importing refs') remote_tags = gittle.utils.git.subrefs(remote_refs, 'refs/tags') remote_heads = gittle.utils.git.subrefs(remote_refs, 'refs/heads') # Filter refs clean_remote_tags = gittle.utils.git.clean_refs(remote_tags) clean_remote_heads = gittle.utils.git.clean_refs(remote_heads) # Base of new refs heads_base = 'refs/remotes/' + origin # Import branches repo.import_refs(heads_base, clean_remote_heads) for k, v in clean_remote_heads.items(): print('imported {}/{} {}'.format(heads_base, k, v)) # Import tags repo.import_refs('refs/tags', clean_remote_tags) for k, v in clean_remote_tags.items(): print('imported {}/{} {}'.format('refs/tags', k, v)) print('Checking for deleted remote refs') #delete unused remote refs for k in gittle.utils.git.subrefs(repo.refs, heads_base): if k not in clean_remote_heads: print('Deleting {}'.format('/'.join([heads_base, k]))) del repo.refs['/'.join([heads_base, k])] print('Fetch complete')
def test_simple(self): outstream = BytesIO() errstream = BytesIO() # create a file for initial commit handle, fullpath = tempfile.mkstemp(dir=self.repo.path) os.close(handle) porcelain.add(repo=self.repo.path, paths=fullpath) porcelain.commit(repo=self.repo.path, message=b'test', author=b'test <email>', committer=b'test <email>') # Setup target repo target_path = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, target_path) target_repo = porcelain.clone(self.repo.path, target=target_path, errstream=errstream) # create a second file to be pushed handle, fullpath = tempfile.mkstemp(dir=self.repo.path) os.close(handle) porcelain.add(repo=self.repo.path, paths=fullpath) porcelain.commit(repo=self.repo.path, message=b'test2', author=b'test2 <email>', committer=b'test2 <email>') self.assertFalse(self.repo[b'HEAD'].id in target_repo) target_repo.close() # Fetch changes into the cloned repo porcelain.fetch(target_path, self.repo.path, outstream=outstream, errstream=errstream) # Check the target repo for pushed changes with Repo(target_path) as r: self.assertTrue(self.repo[b'HEAD'].id in r)
def git_fetch(args): parser = argparse.ArgumentParser(prog='git fetch' , usage='git fetch [http(s)://<remote repo> or remotename] [-u username[:password]]' , description="Push to a remote repository") parser.add_argument('url', type=str, nargs='?', help='URL to push to') parser.add_argument('-u', metavar='username[:password]', type=str, required=False, help='username[:password]') result = parser.parse_args(args) repo = _get_repo() origin='origin' if not result.url: result.url = repo.remotes.get('origin','') if result.url in repo.remotes: origin=result.url result.url=repo.remotes.get(origin) if not urlparse.urlparse(result.url).scheme: raise Exception('url must match a remote name, or must start with http:// or https://') print 'Starting fetch, this could take a while' remote_refs=porcelain.fetch(repo.repo.path,result.url) print 'Fetch successful. Importing refs' remote_tags = gittle.utils.git.subrefs(remote_refs, 'refs/tags') remote_heads = gittle.utils.git.subrefs(remote_refs, 'refs/heads') # Filter refs clean_remote_tags = gittle.utils.git.clean_refs(remote_tags) clean_remote_heads = gittle.utils.git.clean_refs(remote_heads) # Base of new refs heads_base = 'refs/remotes/' + origin # Import branches repo.import_refs( heads_base, clean_remote_heads ) for k,v in clean_remote_heads.items(): print 'imported {}/{} {}'.format(heads_base,k,v) # Import tags repo.import_refs( 'refs/tags', clean_remote_tags ) for k,v in clean_remote_tags.items(): print 'imported {}/{} {}'.format('refs/tags',k,v) print 'Checking for deleted remote refs' #delete unused remote refs for k in gittle.utils.git.subrefs(repo.refs,heads_base): if k not in clean_remote_heads: print 'Deleting {}'.format('/'.join([heads_base,k])) del repo.refs['/'.join([heads_base,k])] print 'Fetch complete'
def _FetchRepo(target_dir, url): """Fetch a git repository from 'url' into 'target_dir'. See InstallRuntimeDef() for information on which version is selected. Args: target_dir: (str) Directory name. url: (str) Git repository URL. Raises: errors.HangupException: Hangup during communication to a remote repository. """ if os.path.exists(target_dir): # If the target directory exists, just update it. log.debug('Fetching from %s into existing directory.', url) try: porcelain.fetch(target_dir, url) except (IOError, OSError) as ex: raise InvalidTargetDirectoryError('Unable to fetch into target ' 'directory {0}: {1}'.format( target_dir, ex.message)) else: try: log.debug('Cloning from %s into %s', url, target_dir) porcelain.clone(url, target_dir, checkout=False) except (errors.NotGitRepository, OSError) as ex: # This gets thrown for an invalid directory, e.g. if the base base # directory doesn't exist. raise InvalidTargetDirectoryError('Unable to clone into target ' 'directory {0}: {1}'.format( target_dir, ex.message)) except KeyError as ex: # When we try to clone an empty git repo, we get KeyError('HEAD') when # clone tries to look up the head tag. if ex.message == 'HEAD': raise InvalidRepositoryError() else: raise
def git_fetch(args): parser = argparse.ArgumentParser( prog="git fetch", usage="git fetch [http(s)://<remote repo> or remotename] [-u username[:password]]", description="Push to a remote repository", ) parser.add_argument("url", type=str, nargs="?", help="URL to push to") parser.add_argument("-u", metavar="username[:password]", type=str, required=False, help="username[:password]") result = parser.parse_args(args) repo = _get_repo() origin = "origin" if not result.url: result.url = repo.remotes.get("origin", "") if result.url in repo.remotes: origin = result.url result.url = repo.remotes.get(origin) if not urlparse.urlparse(result.url).scheme: raise Exception("url must match a remote name, or must start with http:// or https://") print "Starting fetch, this could take a while" remote_refs = porcelain.fetch(repo.repo.path, result.url) print "Fetch successful. Importing refs" remote_tags = gittle.utils.git.subrefs(remote_refs, "refs/tags") remote_heads = gittle.utils.git.subrefs(remote_refs, "refs/heads") # Filter refs clean_remote_tags = gittle.utils.git.clean_refs(remote_tags) clean_remote_heads = gittle.utils.git.clean_refs(remote_heads) # Base of new refs heads_base = "refs/remotes/" + origin # Import branches repo.import_refs(heads_base, clean_remote_heads) for k, v in clean_remote_heads.items(): print "imported {}/{} {}".format(heads_base, k, v) # Import tags repo.import_refs("refs/tags", clean_remote_tags) for k, v in clean_remote_tags.items(): print "imported {}/{} {}".format("refs/tags", k, v) print "Checking for deleted remote refs" # delete unused remote refs for k in gittle.utils.git.subrefs(repo.refs, heads_base): if k not in clean_remote_heads: print "Deleting {}".format("/".join([heads_base, k])) del repo.refs["/".join([heads_base, k])] print "Fetch complete"
def git_fetch(args): parser = argparse.ArgumentParser(prog='git fetch' , usage='git fetch [http(s)://<remote repo> or remotename] [-u username[:password]]' , description="Push to a remote repository") parser.add_argument('url', type=str, nargs='?', help='URL to push to') parser.add_argument('-u', metavar='username[:password]', type=str, required=False, help='username[:password]') result = parser.parse_args(args) repo = _get_repo() origin='origin' if not result.url: result.url = repo.remotes.get('origin','') if result.url in repo.remotes: origin=result.url result.url=repo.remotes.get(origin) remote_refs=porcelain.fetch(repo.repo.path,result.url) remote_tags = gittle.utils.git.subrefs(remote_refs, 'refs/tags') remote_heads = gittle.utils.git.subrefs(remote_refs, 'refs/heads') # Filter refs clean_remote_tags = gittle.utils.git.clean_refs(remote_tags) clean_remote_heads = gittle.utils.git.clean_refs(remote_heads) # Base of new refs heads_base = 'refs/remotes/' + origin # Import branches repo.import_refs( heads_base, clean_remote_heads ) for k,v in clean_remote_heads.items(): print 'imported {}/{} {}'.format(heads_base,k,v) # Import tags repo.import_refs( 'refs/tags', clean_remote_tags ) for k,v in clean_remote_tags.items(): print 'imported {}/{} {}'.format('refs/tags',k,v) #delete unused remote refs for k in gittle.utils.git.subrefs(repo.refs,heads_base): if k not in gittle.utils.git.subrefs(clean_remote_heads,origin): del repo.refs['/'.join([heads_base,k])]
def __clone_repo(self, repo_url, destination): """ This is to replicate the functionality of cloning/pulling a repo """ try: with open('/dev/null', 'wb') as devnull: porcelain.pull(destination, repo_url, outstream=devnull, errstream=devnull) repo = porcelain.open_repo(destination) except dulwich.errors.NotGitRepository: with open('/dev/null', 'wb') as devnull: repo = porcelain.clone(repo_url, destination, outstream=devnull, errstream=devnull) remote_refs = porcelain.fetch(repo, repo_url) ref = f'refs/heads/{self.branch}'.encode() try: repo[ref] = remote_refs[ref] except KeyError: ref = b'refs/heads/master' msgs = [ f'\nBranch {self.branch} does not exist at {repo_url}!', 'Using "master" branch for plugin, this may not work ' 'with your RELEASE' ] for msg in msgs: iocage_lib.ioc_common.logit({ 'level': 'INFO', 'message': msg }, _callback=self.callback) repo[ref] = remote_refs[ref] tree = repo[ref].tree # Let git reflect reality repo.reset_index(tree) repo.refs.set_symbolic_ref(b'HEAD', ref)
def __clone_repo(self, repo_url, destination): """ This is to replicate the functionality of cloning/pulling a repo """ try: with open('/dev/null', 'wb') as devnull: porcelain.pull(destination, repo_url, outstream=devnull, errstream=devnull) repo = porcelain.open_repo(destination) except dulwich.errors.NotGitRepository: with open('/dev/null', 'wb') as devnull: repo = porcelain.clone( repo_url, destination, outstream=devnull, errstream=devnull ) remote_refs = porcelain.fetch(repo, repo_url) ref = f'refs/heads/{self.branch}'.encode() try: repo[ref] = remote_refs[ref] except KeyError: ref = b'refs/heads/master' msgs = [ f'\nBranch {self.branch} does not exist at {repo_url}!', 'Using "master" branch for plugin, this may not work ' 'with your RELEASE' ] for msg in msgs: iocage_lib.ioc_common.logit( { 'level': 'INFO', 'message': msg }, _callback=self.callback) repo[ref] = remote_refs[ref] tree = repo[ref].tree # Let git reflect reality repo.reset_index(tree) repo.refs.set_symbolic_ref(b'HEAD', ref)
def _fetch_from_remote(self): with self._show_busy(): fetch(repo=self._repo, remote_location=urldefrag(self._registry_data.git_url).url)
# python examples/memoryrepo.py git+ssh://github.com/jelmer/testrepo import stat # import sys remote_url='https://gitee.com/qgbcs/gt.git' from dulwich import porcelain from dulwich.objects import Blob from dulwich.repo import MemoryRepo local_repo = MemoryRepo() local_repo.refs.set_symbolic_ref(b'HEAD', b'refs/heads/master') print(local_repo.refs.as_dict()) porcelain.fetch(local_repo, remote_url) local_repo[b'refs/heads/master'] = local_repo[b'refs/remotes/origin/master'] last_tree = local_repo[local_repo['HEAD'].tree] new_blob = Blob.from_string(b'Some contents') local_repo.object_store.add_object(new_blob) last_tree.add(b'test', stat.S_IFREG, new_blob.id) local_repo.object_store.add_object(last_tree) local_repo.do_commit( message=b'Add a file called \'test\'', ref=b'refs/heads/master', tree=last_tree.id) porcelain.push(local_repo, remote_url, 'master')
# # Example usage: # python examples/memoryrepo.py git+ssh://github.com/jelmer/testrepo import stat import sys from dulwich import porcelain from dulwich.objects import Blob from dulwich.repo import MemoryRepo local_repo = MemoryRepo() local_repo.refs.set_symbolic_ref(b'HEAD', b'refs/heads/master') print(local_repo.refs.as_dict()) porcelain.fetch(local_repo, sys.argv[1]) local_repo['refs/heads/master'] = local_repo['refs/remotes/origin/master'] last_tree = local_repo[local_repo['HEAD'].tree] new_blob = Blob.from_string(b'Some contents') local_repo.object_store.add_object(new_blob) last_tree.add(b'test', stat.S_IFREG, new_blob.id) local_repo.object_store.add_object(last_tree) local_repo.do_commit( message=b'Add a file called \'test\'', ref=b'refs/heads/master', tree=last_tree.id) porcelain.push(local_repo, sys.argv[1], 'master')
def fetch(self): remoteRefs = fetch(repo=self.repo, remote_location=self.getRemote()) for key, value in remoteRefs.items(): self.repo.refs[key] = value
# then adds a single file and pushes the result back. # # Example usage: # python examples/memoryrepo.py git+ssh://github.com/jelmer/testrepo import stat import sys from dulwich import porcelain from dulwich.objects import Blob from dulwich.repo import MemoryRepo local_repo = MemoryRepo() local_repo.refs.set_symbolic_ref(b'HEAD', b'refs/heads/master') print(local_repo.refs.as_dict()) porcelain.fetch(local_repo, sys.argv[1]) local_repo['refs/heads/master'] = local_repo['refs/remotes/origin/master'] last_tree = local_repo[local_repo['HEAD'].tree] new_blob = Blob.from_string(b'Some contents') local_repo.object_store.add_object(new_blob) last_tree.add(b'test', stat.S_IFREG, new_blob.id) local_repo.object_store.add_object(last_tree) local_repo.do_commit(message=b'Add a file called \'test\'', ref=b'refs/heads/master', tree=last_tree.id) porcelain.push(local_repo, sys.argv[1], 'master')
""" branches = porcelain.branch_list(repoPath) print "branches" for item in branches: print item elif command == "fetch": """ def fetch(repo, remote_location, outstream=sys.stdout, errstream=default_bytes_err_stream): Fetch objects from a remote server. Parameters repo Path to the repository remote_location String identifying a remote server outstream Output stream (defaults to stdout) errstream Error stream (defaults to stderr) Returns Dictionary with refs on the remote """ porcelain.fetch(repoPath, remote) # remote should be the host etc from a stanze elif command == "createbranch": """ def branch_create(repo, name, objectish=None, force=False): Create a branch. Parameters repo Path to the repository name Name of the new branch objectish Target object to point new branch at (defaults to HEAD) force Force creation of branch, even if it already exists """ porcelain.branch_create(repoPath, branch) elif command == "deletebranch": """ def branch_delete(repo, name): Delete a branch. Parameters repo Path to the repository
def test_git_loader(scheduler_host, git_origin): url = git_origin print(f"Retrieve references available at {url}") repo = MemoryRepo() gitrefs = porcelain.fetch(repo, url).refs print(f"Look for origin {url}") # use quote_plus to prevent urljoin from messing with the 'http://' part of # the url origin = apiget(f"origin/{quote_plus(url)}/get") assert origin["url"] == url visit = apiget(f"origin/{quote_plus(url)}/visit/latest") assert visit["status"] == "full" print("Check every identified git ref has been loaded") snapshot = apiget(f'snapshot/{visit["snapshot"]}') print(f'snapshot has {len(snapshot["branches"])} branches') branches = snapshot["branches"] # check every fetched branch is present in the snapshot for branch_name, rev in gitrefs.items(): # for tags, only check for final revision id if branch_name.startswith( b"refs/tags/") and not branch_name.endswith(b"^{}"): continue rev_desc = apiget(f"revision/{rev.decode()}") assert rev_desc["type"] == "git" tag_revision = {} tag_release = {} for tag, rev in gitrefs.items(): if tag.startswith(b"refs/tags/"): tag_str = tag.decode() rev_str = rev.decode() if tag.endswith(b"^{}"): tag_revision[tag_str[:-3]] = rev_str else: tag_release[tag_str] = rev_str for tag, revision in tag_revision.items(): # check that every release tag listed in the snapshot is known by the # archive and consistent release_id = tag_release[tag] release = apiget(f"release/{release_id}") assert release["id"] == release_id assert release["target_type"] == "revision" assert release["target"] == revision # and compare this with what git ls-remote reported tag_desc = branches[tag] assert tag_desc["target_type"] == "release" assert tag_desc["target"] == release_id print("Check every git object stored in the repository has been loaded") for sha1 in repo.object_store: obj = repo.get_object(sha1) sha1_str = sha1.decode() if obj.type_name == b"blob": apiget(f"content/sha1_git:{sha1_str}") elif obj.type_name == b"commit": apiget(f"revision/{sha1_str}") elif obj.type_name == b"tree": apiget(f"directory/{sha1_str}") elif obj.type_name == b"tag": apiget(f"release/{sha1_str}")