def repack(repo_path, ignore_alternates=False, single=False, prune=False, no_reuse_delta=False, window=None, depth=None): """Repack a repository with git-repack. :param ignore_alternates: Only repack local refs (git repack --local). :param single: Create a single packfile (git repack -a). :param prune: Remove redundant packs. (git repack -d) :param no_reuse_delta: Force delta recalculation. """ ensure_config(repo_path) repack_args = ['git', 'repack', '-q'] if ignore_alternates: repack_args.append('-l') if no_reuse_delta: repack_args.append('-f') if prune: repack_args.append('-d') if single: repack_args.append('-a') if window: repack_args.append('--window', window) if depth: repack_args.append('--depth', depth) return subprocess.check_call( repack_args, cwd=repo_path, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
def requestReceived(self, command, raw_pathname, params): path = compose_path(self.factory.root, raw_pathname) if command == b'git-upload-pack': subcmd = b'upload-pack' elif command == b'git-receive-pack': subcmd = b'receive-pack' else: self.die(b'Unsupported command in request') return cmd = b'git' args = [b'git', subcmd] if params.pop(b'turnip-stateless-rpc', None): args.append(b'--stateless-rpc') if params.pop(b'turnip-advertise-refs', None): args.append(b'--advertise-refs') args.append(path) env = {} if subcmd == b'receive-pack' and self.factory.hookrpc_handler: # This is a write operation, so prepare config, hooks, the hook # RPC server, and the environment variables that link them up. ensure_config(path) self.hookrpc_key = str(uuid.uuid4()) self.factory.hookrpc_handler.registerKey( self.hookrpc_key, raw_pathname, []) ensure_hooks(path) env[b'TURNIP_HOOK_RPC_SOCK'] = self.factory.hookrpc_sock env[b'TURNIP_HOOK_RPC_KEY'] = self.hookrpc_key self.peer = GitProcessProtocol(self) reactor.spawnProcess(self.peer, cmd, args, env=env)
def init_repo(repo_path, clone_from=None, clone_refs=False, alternate_repo_paths=None, is_bare=True): """Initialise a new git repository or clone from existing.""" assert is_valid_new_path(repo_path) init_repository(repo_path, is_bare) if clone_from: # The clone_from's objects and refs are in fact cloned into a # subordinate tree that's then set as an alternate for the real # repo. This lets git-receive-pack expose available commits as # extra haves without polluting refs in the real repo. sub_path = os.path.join(repo_path, 'turnip-subordinate') clone_repository(clone_from, sub_path, True) assert is_bare alt_path = os.path.join(repo_path, 'objects/info/alternates') with open(alt_path, 'w') as f: f.write('../turnip-subordinate/objects\n') if clone_refs: # With the objects all accessible via the subordinate, we # can just copy all refs from the origin. Unlike # pygit2.clone_repository, this won't set up a remote. # TODO: Filter out internal (eg. MP) refs. from_repo = Repository(clone_from) to_repo = Repository(repo_path) for ref in from_repo.listall_references(): to_repo.create_reference( ref, from_repo.lookup_reference(ref).target) if alternate_repo_paths: write_alternates(repo_path, alternate_repo_paths) ensure_config(repo_path) # set repository configuration defaults return repo_path
def test_preserves_existing(self): # If the configuration file is already in the correct state, then # the file is left unchanged; for efficiency we do not even write # out a new file. (Currently, pygit2/libgit2 take care of this; if # they ever stop doing so then we should take extra care ourselves.) helpers.ensure_config(self.repo_dir) now = time.time() os.utime(self.config_path, (now - 60, now - 60)) old_mtime = os.stat(self.config_path).st_mtime self.assertWritesCorrectConfig() self.assertEqual(old_mtime, os.stat(self.config_path).st_mtime)
def assertWritesCorrectConfig(self): helpers.ensure_config(self.repo_dir) config = Config(path=self.config_path) self.assertTrue(config['core.logallrefupdates']) self.assertTrue(config['repack.writeBitmaps'])