# HG changeset patch # User RhodeCode Admin # Date 2022-09-01 21:18:42 # Node ID 1ce1ca3f4fb67a333dd9f8374edbb43a4f44e3a9 # Parent 7597323fb27d18c13e2939612cb7ff323d2b33dd vcsserver: implement set head ref and optimize deletion of filenodes diff --git a/vcsserver/git.py b/vcsserver/git.py --- a/vcsserver/git.py +++ b/vcsserver/git.py @@ -452,11 +452,22 @@ class GitRemote(RemoteBase): # TODO: this is quite complex, check if that can be simplified @reraise_safe_exceptions def commit(self, wire, commit_data, branch, commit_tree, updated, removed): + # Defines the root tree + class _Root(object): + def __repr__(self): + return 'ROOT TREE' + ROOT = _Root() + repo = self._factory.repo(wire) object_store = repo.object_store # Create tree and populates it with blobs - commit_tree = commit_tree and repo[commit_tree] or objects.Tree() + + if commit_tree and repo[commit_tree]: + git_commit = repo[commit_data['parents'][0]] + commit_tree = repo[git_commit.tree] # root tree + else: + commit_tree = objects.Tree() for node in updated: # Compute subdirs if needed @@ -515,21 +526,34 @@ class GitRemote(RemoteBase): for node_path in removed: paths = node_path.split('/') - tree = commit_tree - trees = [tree] + tree = commit_tree # start with top-level + trees = [{'tree': tree, 'path': ROOT}] # Traverse deep into the forest... + # resolve final tree by iterating the path. + # e.g a/b/c.txt will get + # - root as tree then + # - 'a' as tree, + # - 'b' as tree, + # - stop at c as blob. for path in paths: try: obj = repo[tree[path][1]] if isinstance(obj, objects.Tree): - trees.append(obj) + trees.append({'tree': obj, 'path': path}) tree = obj except KeyError: break + #PROBLEM: + """ + We're not editing same reference tree object + """ # Cut down the blob and all rotten trees on the way back... - for path, tree in reversed(zip(paths, trees)): - del tree[path] - if tree: + for path, tree_data in reversed(zip(paths, trees)): + tree = tree_data['tree'] + tree.__delitem__(path) + # This operation edits the tree, we need to mark new commit back + + if len(tree) > 0: # This tree still has elements - don't remove it or any # of it's parents break @@ -539,7 +563,7 @@ class GitRemote(RemoteBase): # Create commit commit = objects.Commit() commit.tree = commit_tree.id - for k, v in commit_data.iteritems(): + for k, v in commit_data.items(): setattr(commit, k, v) object_store.add_object(commit) @@ -1203,13 +1227,6 @@ class GitRemote(RemoteBase): return install_git_hooks(path, bare, force_create=force) @reraise_safe_exceptions - def set_head_ref(self, wire, head_name): - log.debug('Setting refs/head to `%s`', head_name) - cmd = ['symbolic-ref', 'HEAD', 'refs/heads/%s' % head_name] - output, __ = self.run_git_command(wire, cmd) - return [head_name] + output.splitlines() - - @reraise_safe_exceptions def get_hooks_info(self, wire): from vcsserver.hook_utils import ( get_git_pre_hook_version, get_git_post_hook_version) @@ -1221,6 +1238,13 @@ class GitRemote(RemoteBase): } @reraise_safe_exceptions + def set_head_ref(self, wire, head_name): + log.debug('Setting refs/head to `%s`', head_name) + cmd = ['symbolic-ref', 'HEAD', 'refs/heads/%s' % head_name] + output, __ = self.run_git_command(wire, cmd) + return [head_name] + output.splitlines() + + @reraise_safe_exceptions def archive_repo(self, wire, archive_dest_path, kind, mtime, archive_at_path, archive_dir_name, commit_id): diff --git a/vcsserver/hg.py b/vcsserver/hg.py --- a/vcsserver/hg.py +++ b/vcsserver/hg.py @@ -1017,6 +1017,10 @@ class HgRemote(RemoteBase): } @reraise_safe_exceptions + def set_head_ref(self, wire, head_name): + pass + + @reraise_safe_exceptions def archive_repo(self, wire, archive_dest_path, kind, mtime, archive_at_path, archive_dir_name, commit_id): diff --git a/vcsserver/svn.py b/vcsserver/svn.py --- a/vcsserver/svn.py +++ b/vcsserver/svn.py @@ -537,6 +537,10 @@ class SvnRemote(RemoteBase): } @reraise_safe_exceptions + def set_head_ref(self, wire, head_name): + pass + + @reraise_safe_exceptions def archive_repo(self, wire, archive_dest_path, kind, mtime, archive_at_path, archive_dir_name, commit_id):