# HG changeset patch # User RhodeCode Admin # Date 2023-11-22 13:29:25 # Node ID 76143c56ce3dde346918517188dda8ff7a67233e # Parent a2015e2cd60f38526335728e6cb10608572a3ff3 fix(git): fixed case when we want a set explicit ref instead of last one that is not stable diff --git a/vcsserver/remote/git_remote.py b/vcsserver/remote/git_remote.py --- a/vcsserver/remote/git_remote.py +++ b/vcsserver/remote/git_remote.py @@ -571,7 +571,10 @@ class GitRemote(RemoteBase): return blob.id @reraise_safe_exceptions - def create_commit(self, wire, author, committer, message, branch, new_tree_id, date_args: list[int, int] = None): + def create_commit(self, wire, author, committer, message, branch, new_tree_id, + date_args: list[int, int] = None, + parents: list | None = None): + repo_init = self._factory.repo_libgit2(wire) with repo_init as repo: @@ -590,16 +593,20 @@ class GitRemote(RemoteBase): # validate this tree is in the repo... tree = repo[safe_str(tree)].id - parents = [] - # ensure we COMMIT on top of given branch head - # check if this repo has ANY branches, otherwise it's a new branch case we need to make - if branch in repo.branches.local: - parents += [repo.branches[branch].target] - elif [x for x in repo.branches.local]: - parents += [repo.head.target] - #else: - # in case we want to commit on new branch we create it on top of HEAD - #repo.branches.local.create(branch, repo.revparse_single('HEAD')) + if parents: + # run via sha's and validate them in repo + parents = [repo[c].id for c in parents] + else: + parents = [] + # ensure we COMMIT on top of given branch head + # check if this repo has ANY branches, otherwise it's a new branch case we need to make + if branch in repo.branches.local: + parents += [repo.branches[branch].target] + elif [x for x in repo.branches.local]: + parents += [repo.head.target] + #else: + # in case we want to commit on new branch we create it on top of HEAD + #repo.branches.local.create(branch, repo.revparse_single('HEAD')) # # Create a new commit commit_oid = repo.create_commit( @@ -635,6 +642,12 @@ class GitRemote(RemoteBase): with repo_init as repo: repo_index = repo.index + commit_parents = None + if commit_tree and commit_data['parents']: + commit_parents = commit_data['parents'] + parent_commit = repo[commit_parents[0]] + repo_index.read_tree(parent_commit.tree) + for pathspec in updated: blob_id = repo.create_blob(pathspec['content']) ie = pygit2.IndexEntry(pathspec['path'], blob_id, mode2pygit(pathspec['mode'])) @@ -647,9 +660,9 @@ class GitRemote(RemoteBase): repo_index.write() # Create a tree from the updated index - commit_tree = repo_index.write_tree() + written_commit_tree = repo_index.write_tree() - new_tree_id = commit_tree + new_tree_id = written_commit_tree author = commit_data['author'] committer = commit_data['committer'] @@ -658,7 +671,7 @@ class GitRemote(RemoteBase): date_args = [int(commit_data['commit_time']), int(commit_data['commit_timezone'])] new_commit_id = self.create_commit(wire, author, committer, message, branch, - new_tree_id, date_args=date_args) + new_tree_id, date_args=date_args, parents=commit_parents) # libgit2, ensure the branch is there and exists self.create_branch(wire, branch, new_commit_id) @@ -680,12 +693,13 @@ class GitRemote(RemoteBase): repo = self._factory.repo(wire) determine_wants = repo.object_store.determine_wants_all + if refs: - refs = [ascii_bytes(x) for x in refs] + refs: list[bytes] = [ascii_bytes(x) for x in refs] - def determine_wants_requested(remote_refs): + def determine_wants_requested(_remote_refs): determined = [] - for ref_name, ref_hash in remote_refs.items(): + for ref_name, ref_hash in _remote_refs.items(): bytes_ref_name = safe_bytes(ref_name) if bytes_ref_name in refs: @@ -723,8 +737,13 @@ class GitRemote(RemoteBase): repo[k] = remote_refs[k] if refs and not update_after: + # update to ref # mikhail: explicitly set the head to the last ref. - repo[HEAD_MARKER] = remote_refs[refs[-1]] + update_to_ref = refs[-1] + if isinstance(update_after, str): + update_to_ref = update_after + + repo[HEAD_MARKER] = remote_refs[update_to_ref] if update_after: # we want to check out HEAD