# HG changeset patch # User Andrew Shadura # Date 1492258239 -7200 # Node ID 2cf6d49b6073621299eef8f6e522cb3a2e745414 # Parent 6f6ee1cfe2d6716db26141615d268e8d27bb6474 git: add references for Git pull request heads When a pull request is created, stick a reference to it in the refs/pull namespace, similarly to what GitHub does, and remove it when the pull request is deleted. That reference guarantees the commits stay around and don't get garbage-collected when a PR is rebased or revised. Also, that makes it possible to access head of historic pull requests using Git by fetching a ref from the source repository. Unlike GitHub though, we don't put the ref into the destination repository and don't copy commits there to prevent undesired repository growth. Kallithea uses global pull request identifiers, so there should not be any confusion as to what pull request the ref corresponds to. We may later provide a shim to redirect users to the source repository if that deems needed. diff -r 6f6ee1cfe2d6 -r 2cf6d49b6073 kallithea/model/pull_request.py --- a/kallithea/model/pull_request.py Wed May 03 03:41:11 2017 +0200 +++ b/kallithea/model/pull_request.py Sat Apr 15 14:10:39 2017 +0200 @@ -39,7 +39,7 @@ from kallithea.model.db import PullRequest, PullRequestReviewer, Notification, \ ChangesetStatus, User from kallithea.model.notification import NotificationModel -from kallithea.lib.utils2 import extract_mentioned_users, safe_unicode +from kallithea.lib.utils2 import extract_mentioned_users, safe_str, safe_unicode log = logging.getLogger(__name__) @@ -139,6 +139,12 @@ def delete(self, pull_request): pull_request = PullRequest.guess_instance(pull_request) Session().delete(pull_request) + if pull_request.org_repo.scm_instance.alias == 'git': + # remove a ref under refs/pull/ so that commits can be garbage-collected + try: + del pull_request.org_repo.scm_instance._repo["refs/pull/%d/head" % pull_request.pull_request_id] + except KeyError: + pass def close_pull_request(self, pull_request): pull_request = PullRequest.guess_instance(pull_request) @@ -228,6 +234,7 @@ self.org_repo = org_repo self.other_repo = other_repo self.org_ref = org_ref + self.org_rev = org_rev self.other_ref = other_ref self.title = title self.description = description @@ -252,6 +259,10 @@ Session().add(pr) Session().flush() # make database assign pull_request_id + if self.org_repo.scm_instance.alias == 'git': + # create a ref under refs/pull/ so that commits don't get garbage-collected + self.org_repo.scm_instance._repo["refs/pull/%d/head" % pr.pull_request_id] = safe_str(self.org_rev) + #reset state to under-review from kallithea.model.changeset_status import ChangesetStatusModel from kallithea.model.comment import ChangesetCommentsModel