[PATCH v2] git: add references for Git pull request heads
Andrew Shadura
andrew at shadura.me
Sat Apr 15 12:11:52 UTC 2017
# HG changeset patch
# User Andrew Shadura <andrew at shadura.me>
# Date 1492258239 -7200
# Sat Apr 15 14:10:39 2017 +0200
# Node ID 977c0cfec8c00806d4331ebf402ce492657cf34a
# Parent a1f8bf0428c5a3123da9c3ba2dbd8ada50be0b0e
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 the historis 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 --git a/kallithea/model/pull_request.py b/kallithea/model/pull_request.py
--- a/kallithea/model/pull_request.py
+++ b/kallithea/model/pull_request.py
@@ -39,8 +39,7 @@ from kallithea.lib import helpers as h
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 +138,12 @@ class PullRequestModel(object):
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 +233,7 @@ class CreatePullRequestAction(object):
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 +258,10 @@ class CreatePullRequestAction(object):
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
More information about the kallithea-general
mailing list