From 96fd55a15136355f936eee51687329980344684b Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Jul 21 2015 08:45:12 +0000 Subject: [PATCH 1/28] Make the PullRequest table ready for remote pull-request Remote pull-request are pull-request coming from a git repo that is not local to pagure (for example hosted on gitlab). So a PullRequest object may not have a project_id_from but may have instead a remote_git address. Anyway, either project_id_from or remote_git must be defined. --- diff --git a/pagure/lib/model.py b/pagure/lib/model.py index a1f09ac..baccebd 100644 --- a/pagure/lib/model.py +++ b/pagure/lib/model.py @@ -712,7 +712,10 @@ class PullRequest(BASE): sa.Integer, sa.ForeignKey( 'projects.id', ondelete='CASCADE', onupdate='CASCADE'), - nullable=False) + nullable=True) + remote_git = sa.Column( + sa.Text(), + nullable=True) branch_from = sa.Column( sa.Text(), nullable=False) @@ -752,6 +755,12 @@ class PullRequest(BASE): date_created = sa.Column(sa.DateTime, nullable=False, default=datetime.datetime.utcnow) + __table_args__ = ( + sa.CheckConstraint( + 'NOT(project_id_from IS NULL AND remote_git IS NULL)' + ), + ) + project = relation( 'Project', foreign_keys=[project_id], remote_side=[Project.id], backref=backref( From 5d25e703a8ca8bc9df6e919243de34d2264e53bf Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Jul 21 2015 08:54:00 +0000 Subject: [PATCH 2/28] Add a couple of properties to the PullRequest for remote PR --- diff --git a/pagure/lib/model.py b/pagure/lib/model.py index baccebd..eb3d06f 100644 --- a/pagure/lib/model.py +++ b/pagure/lib/model.py @@ -16,6 +16,8 @@ import logging import json import sqlalchemy as sa +import werkzeug + from sqlalchemy import create_engine from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.ext.declarative import declarative_base @@ -822,6 +824,19 @@ class PullRequest(BASE): return len(positive) - len(negative) + @property + def remote(self): + ''' Return whether the current PullRequest is a remote pull-request + or not. + ''' + return not self.remote_git is None + + @property + def remote_git_path(self): + ''' Return the path to the local clone of the remote git repo. ''' + return '%s_%s' % ( + self.uid, werkzeug.secure_filename(self.remote_git)) + def to_json(self, public=False, api=False): ''' Returns a dictionnary representation of the pull-request. From 6509a2a5c1793fca13fe5e19e791a6b2a63fc046 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Jul 21 2015 09:14:25 +0000 Subject: [PATCH 3/28] Split the logic to get info for a PR to a dedicated method This should allow to re-use this logic for the remote pull-request --- diff --git a/pagure/ui/fork.py b/pagure/ui/fork.py index 6407c09..0c60780 100644 --- a/pagure/ui/fork.py +++ b/pagure/ui/fork.py @@ -38,6 +38,75 @@ def _get_parent_repo_path(repo): return parentpath +def _get_pr_info(repo_obj, orig_repo, branch_from, branch_to): + ''' Return the info needed to see a diff or make a Pull-Request between + the two specified repo. + ''' + frombranch = repo_obj.lookup_branch(branch_from) + if not frombranch and not repo_obj.is_empty: + flask.abort( + 400, + 'Branch %s does not exist' % branch_from) + + branch = orig_repo.lookup_branch(branch_to) + if not branch and not orig_repo.is_empty: + flask.abort( + 400, + 'Branch %s could not be found in the target repo' % branch_to) + + branch = repo_obj.lookup_branch(branch_from) + commitid = None + if branch: + commitid = branch.get_object().hex + + diff_commits = [] + diff = None + if not repo_obj.is_empty and not orig_repo.is_empty: + orig_commit = orig_repo[ + orig_repo.lookup_branch(branch_to).get_object().hex] + + master_commits = [ + commit.oid.hex + for commit in orig_repo.walk( + orig_commit.oid.hex, pygit2.GIT_SORT_TIME) + ] + + repo_commit = repo_obj[commitid] + + for commit in repo_obj.walk( + repo_commit.oid.hex, pygit2.GIT_SORT_TIME): + if commit.oid.hex in master_commits: + break + diff_commits.append(commit) + + if diff_commits: + first_commit = repo_obj[diff_commits[-1].oid.hex] + diff = repo_obj.diff( + repo_obj.revparse_single(first_commit.parents[0].oid.hex), + repo_obj.revparse_single(diff_commits[0].oid.hex) + ) + + elif orig_repo.is_empty and not repo_obj.is_empty: + orig_commit = None + if 'master' in repo_obj.listall_branches(): + repo_commit = repo_obj[repo_obj.head.target] + else: + branch = repo_obj.lookup_branch(branch_from) + repo_commit = branch.get_object() + + for commit in repo_obj.walk( + repo_commit.oid.hex, pygit2.GIT_SORT_TIME): + diff_commits.append(commit) + + diff = repo_commit.tree.diff_to_tree(swap=True) + else: + raise pagure.exceptions.PagureException( + 'Fork is empty, there are no commits to request pulling' + ) + + return (diff, diff_commits, orig_commit) + + @APP.route('//pull-requests/') @APP.route('//pull-requests') @APP.route('/fork///pull-requests/') @@ -633,67 +702,11 @@ def new_request_pull(repo, branch_to, branch_from, username=None): parentpath = _get_parent_repo_path(repo) orig_repo = pygit2.Repository(parentpath) - frombranch = repo_obj.lookup_branch(branch_from) - if not frombranch and not repo_obj.is_empty: - flask.abort( - 400, - 'Branch %s does not exist' % branch_from) - - branch = orig_repo.lookup_branch(branch_to) - if not branch and not orig_repo.is_empty: - flask.abort( - 400, - 'Branch %s could not be found in the target repo' % branch_to) - - branch = repo_obj.lookup_branch(branch_from) - commitid = None - if branch: - commitid = branch.get_object().hex - - diff_commits = [] - diff = None - if not repo_obj.is_empty and not orig_repo.is_empty: - orig_commit = orig_repo[ - orig_repo.lookup_branch(branch_to).get_object().hex] - - master_commits = [ - commit.oid.hex - for commit in orig_repo.walk( - orig_commit.oid.hex, pygit2.GIT_SORT_TIME) - ] - - repo_commit = repo_obj[commitid] - - for commit in repo_obj.walk( - repo_commit.oid.hex, pygit2.GIT_SORT_TIME): - if commit.oid.hex in master_commits: - break - diff_commits.append(commit) - - if diff_commits: - first_commit = repo_obj[diff_commits[-1].oid.hex] - diff = repo_obj.diff( - repo_obj.revparse_single(first_commit.parents[0].oid.hex), - repo_obj.revparse_single(diff_commits[0].oid.hex) - ) - - elif orig_repo.is_empty and not repo_obj.is_empty: - orig_commit = None - if 'master' in repo_obj.listall_branches(): - repo_commit = repo_obj[repo_obj.head.target] - else: - branch = repo_obj.lookup_branch(branch_from) - repo_commit = branch.get_object() - - for commit in repo_obj.walk( - repo_commit.oid.hex, pygit2.GIT_SORT_TIME): - diff_commits.append(commit) - - diff = repo_commit.tree.diff_to_tree(swap=True) - else: - flask.flash( - 'Fork is empty, there are no commits to request pulling', - 'error') + try: + diff, diff_commits, orig_commit = _get_pr_info( + repo_obj, orig_repo, branch_from, branch_to) + except pagure.exceptions.PagureException as err: + flask.flash(err.message, 'error') return flask.redirect(flask.url_for( 'view_repo', username=username, repo=repo.name)) From df808d6f3fe3b764a25e773e53106d3dc7d510bd Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Jul 21 2015 10:09:21 +0000 Subject: [PATCH 4/28] Correct typo in the docstring of get_repo_path --- diff --git a/pagure/__init__.py b/pagure/__init__.py index d4983b4..977f3eb 100644 --- a/pagure/__init__.py +++ b/pagure/__init__.py @@ -386,7 +386,7 @@ def __get_file_in_tree(repo_obj, tree, filepath): def get_repo_path(repo): - """ Return the pat of the git repository corresponding to the provided + """ Return the path of the git repository corresponding to the provided Repository object from the DB. """ if repo.is_fork: From a4c07ec7ae8a384e9514370c37e533028bc7f2dc Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Jul 21 2015 10:09:36 +0000 Subject: [PATCH 5/28] Add a method to pull changes from a remote repo into the local one --- diff --git a/pagure/lib/repo.py b/pagure/lib/repo.py index 12dbd66..105b5b9 100644 --- a/pagure/lib/repo.py +++ b/pagure/lib/repo.py @@ -11,6 +11,8 @@ import pygit2 +import pagure.exceptions + class PagureRepo(pygit2.Repository): """ An utility class allowing to go around pygit2's inability to be @@ -25,3 +27,34 @@ class PagureRepo(pygit2.Repository): remote.push([refname]) else: remote.push(refname) + + def pull(self, remote_name='origin', branch='master'): + ''' pull changes for the specified remote (defaults to origin). + + Code from MichaelBoselowitz at: + https://github.com/MichaelBoselowitz/pygit2-examples/blob/ + 68e889e50a592d30ab4105a2e7b9f28fac7324c8/examples.py#L58 + licensed under the MIT license. + ''' + + for remote in self.remotes: + if remote.name == remote_name: + remote.fetch() + remote_master_id = self.lookup_reference( + 'refs/remotes/origin/%s' % branch).target + merge_result, _ = self.merge_analysis(remote_master_id) + # Up to date, do nothing + if merge_result & pygit2.GIT_MERGE_ANALYSIS_UP_TO_DATE: + return + # We can just fastforward + elif merge_result & pygit2.GIT_MERGE_ANALYSIS_FASTFORWARD: + self.checkout_tree(self.get(remote_master_id)) + master_ref = self.lookup_reference( + 'refs/heads/%s' % branch) + master_ref.set_target(remote_master_id) + self.head.set_target(remote_master_id) + elif merge_result & pygit2.GIT_MERGE_ANALYSIS_NORMAL: + raise pagure.exceptions.PagureException( + 'Pulling remote changes leads to a conflict') + else: + raise AssertionError('Unknown merge analysis result') From 608cdb52e179d6494fc5f88120a792a38747b164 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Jul 21 2015 10:09:58 +0000 Subject: [PATCH 6/28] Add a form to create remote pull-requests --- diff --git a/pagure/forms.py b/pagure/forms.py index cdd8e5d..8a8d06f 100644 --- a/pagure/forms.py +++ b/pagure/forms.py @@ -93,6 +93,26 @@ class RequestPullForm(wtf.Form): ) +class RemoteRequestPullForm(wtf.Form): + ''' Form to create a remote request pull. ''' + title = wtforms.TextField( + 'Title*', + [wtforms.validators.Required()] + ) + git_repo = wtforms.TextField( + 'Git repo address*', + [wtforms.validators.Required()] + ) + branch_from = wtforms.TextField( + 'Git branch*', + [wtforms.validators.Required()] + ) + branch_to = wtforms.TextField( + 'Git branch to merge in*', + [wtforms.validators.Required()] + ) + + class AddIssueTagForm(wtf.Form): ''' Form to add a comment to an issue. ''' tag = wtforms.TextField( From 756250c297d4f8d9e118c9ddc9a94607c8decc5a Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Jul 21 2015 10:11:51 +0000 Subject: [PATCH 7/28] Drop the remote_git_path property of PullRequest as don't need it in the model --- diff --git a/pagure/lib/model.py b/pagure/lib/model.py index eb3d06f..1df3900 100644 --- a/pagure/lib/model.py +++ b/pagure/lib/model.py @@ -16,7 +16,6 @@ import logging import json import sqlalchemy as sa -import werkzeug from sqlalchemy import create_engine from sqlalchemy.exc import SQLAlchemyError @@ -831,12 +830,6 @@ class PullRequest(BASE): ''' return not self.remote_git is None - @property - def remote_git_path(self): - ''' Return the path to the local clone of the remote git repo. ''' - return '%s_%s' % ( - self.uid, werkzeug.secure_filename(self.remote_git)) - def to_json(self, public=False, api=False): ''' Returns a dictionnary representation of the pull-request. From fa50fc4350ed4c8ff3e354d482e33d51890ac26c Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Jul 21 2015 10:12:34 +0000 Subject: [PATCH 8/28] Add a method to find the local path of a remote repo --- diff --git a/pagure/__init__.py b/pagure/__init__.py index 977f3eb..ddd978b 100644 --- a/pagure/__init__.py +++ b/pagure/__init__.py @@ -26,6 +26,7 @@ from logging.handlers import SMTPHandler import flask import pygit2 import redis +import werkzeug from pagure.flask_fas_openid import FAS from functools import wraps from sqlalchemy.exc import SQLAlchemyError @@ -400,6 +401,33 @@ def get_repo_path(repo): return repopath +def get_remote_repo_path(remote_git, branch_from): + """ Return the path of the remote git repository corresponding to the + provided information. + """ + repopath = os.path.join( + APP.config['REMOTE_GIT_FOLDER'], + werkzeug.secure_filename('%s_%s' % (remote_git, branch_from)) + ) + + if not os.path.exists(repopath): + try: + pygit2.clone_repository( + remote_git, repopath, checkout_branch=branch_from) + except Exception as err: + LOG.debug(err) + LOG.exception(err) + flask.abort(500, 'Could not clone the remote git repository') + else: + repo = pagure.lib.repo.PagureRepo(repopath) + try: + repo.pull(branch=branch_from) + except pagure.exceptions.PagureException as err: + flask.abort(500, err.message) + + return repopath + + # Import the application import pagure.ui.app import pagure.ui.admin From 036a5579eea97a67d917fb779a60f62b715d4ee7 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Jul 21 2015 10:13:06 +0000 Subject: [PATCH 9/28] Add a default location for the local clone of the remote pull-requests --- diff --git a/pagure/default_config.py b/pagure/default_config.py index 8314098..30f2ebd 100644 --- a/pagure/default_config.py +++ b/pagure/default_config.py @@ -89,6 +89,14 @@ REQUESTS_FOLDER = os.path.join( 'requests' ) +# Folder containing the clones for the remote pull-requests +REMOTE_GIT_FOLDER = os.path.join( + os.path.abspath(os.path.dirname(__file__)), + '..', + 'remotes' +) + + # Configuration file for gitolite GITOLITE_CONFIG = os.path.join( os.path.abspath(os.path.dirname(__file__)), From 09cda59b62b0cb9f6bf5ae2ff97ad4a1c8acf3a1 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Jul 21 2015 10:13:29 +0000 Subject: [PATCH 10/28] Adjust pagure.lib.new_pull_request to support creating remote pull-request --- diff --git a/pagure/lib/__init__.py b/pagure/lib/__init__.py index 4216207..ab03a04 100644 --- a/pagure/lib/__init__.py +++ b/pagure/lib/__init__.py @@ -954,18 +954,25 @@ def drop_issue(session, issue, user, ticketfolder): return issue -def new_pull_request(session, repo_from, branch_from, +def new_pull_request(session, branch_from, repo_to, branch_to, title, user, - requestfolder, requestuid=None, requestid=None, + requestfolder, repo_from=None, remote_git=None, + requestuid=None, requestid=None, status='Open', notify=True): ''' Create a new pull request on the specified repo. ''' + if not repo_from and not remote_git: + pagure.exceptions.PagureException( + 'Invalid input, you must specify either a local repo or a ' + 'remote one') + user_obj = __get_user(session, user) request = model.PullRequest( id=requestid or get_next_id(session, repo_to.id), uid=requestuid or uuid.uuid4().hex, project_id=repo_to.id, - project_id_from=repo_from.id, + project_id_from=repo_from.id if repo_from else None, + remote_git=remote_git if remote_git else None, branch=branch_to, branch_from=branch_from, title=title, From 28fa3de0b57bc6a79e36fe1fcb993731643ff3c1 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Jul 21 2015 10:14:04 +0000 Subject: [PATCH 11/28] Adjust merge_pull_request to be able to handle remote pull-requests --- diff --git a/pagure/lib/git.py b/pagure/lib/git.py index 8301de6..017c31a 100644 --- a/pagure/lib/git.py +++ b/pagure/lib/git.py @@ -859,12 +859,19 @@ def merge_pull_request( session, request, username, request_folder, domerge=True): ''' Merge the specified pull-request. ''' - # Get the fork - repopath = pagure.get_repo_path(request.project_from) - fork_obj = PagureRepo(repopath) + if request.remote: + # Get the fork + repopath = pagure.get_remote_repo_path( + request.remote_git, request.branch_from) + # Get the original repo + parentpath = pagure.get_repo_path(request.project) + else: + # Get the fork + repopath = pagure.get_repo_path(request.project_from) + # Get the original repo + parentpath = _get_parent_repo_path(repo_from) - # Get the original repo - parentpath = pagure.get_repo_path(request.project) + fork_obj = PagureRepo(repopath) # Clone the original repo into a temp folder newpath = tempfile.mkdtemp(prefix='pagure-pr-merge') @@ -900,13 +907,15 @@ def merge_pull_request( raise pagure.exceptions.BranchNotFoundException( 'Branch %s could not be found in the repo %s' % ( request.branch_from, request.project_from.fullname + if request.project_from else request.remote_git )) repo_commit = fork_obj[branch.get_object().hex] ori_remote = new_repo.remotes[0] # Add the fork as remote repo - reponame = '%s_%s' % (request.user.user, request.project_from.name) + reponame = '%s_%s' % (request.user.user, request.uid) + remote = new_repo.create_remote(reponame, repopath) # Fetch the commits From f8812d8e2e4a681391f41f93bacffff10f0e9782 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Jul 21 2015 10:14:20 +0000 Subject: [PATCH 12/28] Adjust the PullRequest JSON representation to account for remote pull-requests --- diff --git a/pagure/lib/model.py b/pagure/lib/model.py index 1df3900..f5cd459 100644 --- a/pagure/lib/model.py +++ b/pagure/lib/model.py @@ -841,7 +841,9 @@ class PullRequest(BASE): 'branch': self.branch, 'project': self.project.to_json(public=public, api=api), 'branch_from': self.branch_from, - 'repo_from': self.project_from.to_json(public=public, api=api), + 'repo_from': self.project_from.to_json( + public=public, api=api) if self.project_from else None, + 'remote_git': self.remote_git, 'date_created': self.date_created.strftime('%s'), 'user': self.user.to_json(public=public), 'assignee': self.assignee.to_json( From 24e217dd5a5a959a0de034f9944982313ffdf57d Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Jul 21 2015 10:15:03 +0000 Subject: [PATCH 13/28] Adjust request_pull to be able to display remote pull-requests --- diff --git a/pagure/ui/fork.py b/pagure/ui/fork.py index 0c60780..b9b4d76 100644 --- a/pagure/ui/fork.py +++ b/pagure/ui/fork.py @@ -194,11 +194,16 @@ def request_pull(repo, requestid, username=None): if not request: flask.abort(404, 'Pull-request not found') - repo_from = request.project_from - repopath = pagure.get_repo_path(repo_from) - repo_obj = pygit2.Repository(repopath) + if request.remote: + repopath = pagure.get_remote_repo_path( + request.remote_git, request.branch_from) + parentpath = pagure.get_repo_path(request.project) + else: + repo_from = request.project_from + repopath = pagure.get_repo_path(repo_from) + parentpath = _get_parent_repo_path(repo_from) - parentpath = _get_parent_repo_path(repo_from) + repo_obj = pygit2.Repository(repopath) orig_repo = pygit2.Repository(parentpath) diff_commits = [] From e117636e7f45c8024e0268701337890440f8b9eb Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Jul 21 2015 10:15:48 +0000 Subject: [PATCH 14/28] Add a new endpoint used to create remote pull-requests --- diff --git a/pagure/templates/remote_pull_request.html b/pagure/templates/remote_pull_request.html new file mode 100644 index 0000000..f903992 --- /dev/null +++ b/pagure/templates/remote_pull_request.html @@ -0,0 +1,46 @@ +{% extends "repo_master.html" %} +{% from "_formhelper.html" import render_field_in_row %} + +{% block title %}Remote Pull request {{ repo.name }}{% endblock %} +{%block tag %}home{% endblock %} + +{% block repo %} + + +

New remote pull-request

+ +{% if form and repo_admin %} +
+
+ + {{ render_field_in_row(form.title) }} + {{ render_field_in_row(form.git_repo) }} + {{ render_field_in_row(form.branch_from) }} + + + + +
To branch + +
+

+ + {{ form.csrf_token }} + + + +

+
+
+{% endif %} + +{% endblock %} + diff --git a/pagure/ui/fork.py b/pagure/ui/fork.py index b9b4d76..86c7127 100644 --- a/pagure/ui/fork.py +++ b/pagure/ui/fork.py @@ -792,3 +792,133 @@ def new_request_pull(repo, branch_to, branch_from, username=None): branch_from=branch_from, repo_admin=repo_admin, ) + + +@APP.route('//diff/remote/', methods=('GET', 'POST')) +@APP.route('//diff/remote', methods=('GET', 'POST')) +@APP.route( + '/fork///diff/remote/', methods=('GET', 'POST')) +@APP.route( + '/fork///diff/remote', methods=('GET', 'POST')) +@cla_required +def new_remote_request_pull(repo, username=None): + """ Request pulling the changes from a remote fork into the project. + """ + repo = pagure.lib.get_project(SESSION, repo, user=username) + confirm = flask.request.values.get('confirm', False) + + if not repo: + flask.abort(404) + + if not repo.settings.get('pull_requests', True): + flask.abort(404, 'No pull-requests found for this project') + + parentpath = pagure.get_repo_path(repo) + orig_repo = pygit2.Repository(parentpath) + + repo_admin = is_repo_admin(repo) + + form = pagure.forms.RemoteRequestPullForm() + if form.validate_on_submit() and repo_admin: + branch_from = form.branch_from.data.strip() + branch_to = form.branch_to.data.strip() + remote_git = form.git_repo.data.strip() + + repopath = pagure.get_remote_repo_path(remote_git, branch_from) + repo_obj = pygit2.Repository(repopath) + + try: + diff, diff_commits, orig_commit = _get_pr_info( + repo_obj, orig_repo, branch_from, branch_to) + except pagure.exceptions.PagureException as err: + flask.flash(err.message, 'error') + return flask.redirect(flask.url_for( + 'view_repo', username=username, repo=repo.name)) + + if not confirm: + return flask.render_template( + 'pull_request.html', + select='requests', + repo=repo, + username=username, + repo_obj=repo_obj, + orig_repo=orig_repo, + diff_commits=diff_commits, + diff=diff, + form=form, + branches=sorted(orig_repo.listall_branches()), + branch_to=branch_to, + branch_from=branch_from, + repo_admin=repo_admin, + remote_git=remote_git, + ) + + try: + if repo.settings.get( + 'Enforce_signed-off_commits_in_pull-request', False): + for commit in diff_commits: + if 'signed-off-by' not in commit.message.lower(): + raise pagure.exceptions.PagureException( + 'This repo enforces that all commits are ' + 'signed off by their author. ') + + if orig_commit: + orig_commit = orig_commit.oid.hex + + parent = repo + if repo.parent: + parent = repo.parent + + request = pagure.lib.new_pull_request( + SESSION, + repo_to=parent, + branch_to=branch_to, + branch_from=branch_from, + repo_from=None, + remote_git=remote_git, + title=form.title.data, + user=flask.g.fas_user.username, + requestfolder=APP.config['REQUESTS_FOLDER'], + ) + try: + SESSION.commit() + flask.flash('Request created') + except SQLAlchemyError as err: # pragma: no cover + SESSION.rollback() + APP.logger.exception(err) + flask.flash( + 'Could not register this pull-request in ' + 'the database', 'error') + + if not parent.is_fork: + url = flask.url_for( + 'request_pull', requestid=request.id, + username=None, repo=parent.name) + else: + url = flask.url_for( + 'request_pull', requestid=request.id, + username=parent.user, repo=parent.name) + + return flask.redirect(url) + except pagure.exceptions.PagureException, err: # pragma: no cover + # There could be a PagureException thrown if the + # flask.g.fas_user wasn't in the DB but then it shouldn't + # be recognized as a repo admin and thus, if we ever are + # here, we are in trouble. + flask.flash(str(err), 'error') + except SQLAlchemyError, err: # pragma: no cover + SESSION.rollback() + flask.flash(str(err), 'error') + + if not is_repo_admin(repo): + form = None + + return flask.render_template( + 'remote_pull_request.html', + select='requests', + repo=repo, + username=username, + form=form, + branches=sorted(orig_repo.listall_branches()), + repo_admin=repo_admin, + ) From 74b58589934dff4551e49057d1199b42d4c10263 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Jul 21 2015 10:15:57 +0000 Subject: [PATCH 15/28] Adjust the pull-request template to work with remote pull-requests as well --- diff --git a/pagure/templates/pull_request.html b/pagure/templates/pull_request.html index dd125ff..44f61fa 100644 --- a/pagure/templates/pull_request.html +++ b/pagure/templates/pull_request.html @@ -62,13 +62,30 @@ {% if form and repo_admin %}
+ {% if remote_git %} +
+ + + {% else %} + {% endif %} {{ render_field_in_row(form.title) }} - + + + + {% if remote_git %} + + + + + {% endif %} + +
To branchFrom branch:{{ branch_from }}
Git repo:{{ remote_git }}
To branch: