Mercurial > kallithea
changeset 6602:2cf6d49b6073
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.
author | Andrew Shadura <andrew@shadura.me> |
---|---|
date | Sat, 15 Apr 2017 14:10:39 +0200 |
parents | 6f6ee1cfe2d6 |
children | fd9b2d83d52b |
files | kallithea/model/pull_request.py |
diffstat | 1 files changed, 12 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- 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