shadow-repos: use numeric repo id for creation of shadow repos.
- Fixes a problem after rename or move into repository group.
This commit is contained in:
parent
d28aeae1b2
commit
42c80fe075
16 changed files with 174 additions and 114 deletions
|
|
@ -302,7 +302,7 @@ def merge_pull_request(
|
|||
request.environ, repo_name=target_repo.repo_name,
|
||||
username=apiuser.username, action='push',
|
||||
scm=target_repo.repo_type)
|
||||
merge_response = PullRequestModel().merge(
|
||||
merge_response = PullRequestModel().merge_repo(
|
||||
pull_request, apiuser, extras=extras)
|
||||
if merge_response.executed:
|
||||
PullRequestModel().close_pull_request(
|
||||
|
|
|
|||
|
|
@ -618,7 +618,7 @@ class TestPullrequestsView(object):
|
|||
|
||||
model_patcher = mock.patch.multiple(
|
||||
PullRequestModel,
|
||||
merge=mock.Mock(return_value=MergeResponse(
|
||||
merge_repo=mock.Mock(return_value=MergeResponse(
|
||||
True, False, 'STUB_COMMIT_ID', MergeFailureReason.PUSH_FAILED)),
|
||||
merge_status=mock.Mock(return_value=(True, 'WRONG_MESSAGE')))
|
||||
|
||||
|
|
|
|||
|
|
@ -340,7 +340,8 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView):
|
|||
# check merge capabilities
|
||||
_merge_check = MergeCheck.validate(
|
||||
pull_request_latest, user=self._rhodecode_user,
|
||||
translator=self.request.translate, force_shadow_repo_refresh=force_refresh)
|
||||
translator=self.request.translate,
|
||||
force_shadow_repo_refresh=force_refresh)
|
||||
c.pr_merge_errors = _merge_check.error_details
|
||||
c.pr_merge_possible = not _merge_check.failed
|
||||
c.pr_merge_message = _merge_check.merge_msg
|
||||
|
|
@ -1063,7 +1064,7 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView):
|
|||
|
||||
def _merge_pull_request(self, pull_request, user, extras):
|
||||
_ = self.request.translate
|
||||
merge_resp = PullRequestModel().merge(pull_request, user, extras=extras)
|
||||
merge_resp = PullRequestModel().merge_repo(pull_request, user, extras=extras)
|
||||
|
||||
if merge_resp.executed:
|
||||
log.debug("The merge was successful, closing the pull request.")
|
||||
|
|
|
|||
|
|
@ -204,13 +204,14 @@ class SimpleVCS(object):
|
|||
|
||||
# Only proceed if we got a pull request and if acl repo name from
|
||||
# URL equals the target repo name of the pull request.
|
||||
if pull_request and (acl_repo_name ==
|
||||
pull_request.target_repo.repo_name):
|
||||
if pull_request and \
|
||||
(acl_repo_name == pull_request.target_repo.repo_name):
|
||||
repo_id = pull_request.target_repo.repo_id
|
||||
# Get file system path to shadow repository.
|
||||
workspace_id = PullRequestModel()._workspace_id(pull_request)
|
||||
target_vcs = pull_request.target_repo.scm_instance()
|
||||
vcs_repo_name = target_vcs._get_shadow_repository_path(
|
||||
workspace_id)
|
||||
repo_id, workspace_id)
|
||||
|
||||
# Store names for later usage.
|
||||
self.vcs_repo_name = vcs_repo_name
|
||||
|
|
|
|||
|
|
@ -451,7 +451,7 @@ class BaseRepository(object):
|
|||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def merge(self, target_ref, source_repo, source_ref, workspace_id,
|
||||
def merge(self, repo_id, workspace_id, target_ref, source_repo, source_ref,
|
||||
user_name='', user_email='', message='', dry_run=False,
|
||||
use_rebase=False, close_branch=False):
|
||||
"""
|
||||
|
|
@ -465,13 +465,14 @@ class BaseRepository(object):
|
|||
'possible', 'executed', 'source_commit', 'target_commit',
|
||||
'merge_commit'.
|
||||
|
||||
:param repo_id: `repo_id` target repo id.
|
||||
:param workspace_id: `workspace_id` unique identifier.
|
||||
:param target_ref: `target_ref` points to the commit on top of which
|
||||
the `source_ref` should be merged.
|
||||
:param source_repo: The repository that contains the commits to be
|
||||
merged.
|
||||
:param source_ref: `source_ref` points to the topmost commit from
|
||||
the `source_repo` which should be merged.
|
||||
:param workspace_id: `workspace_id` unique identifier.
|
||||
:param user_name: Merge commit `user_name`.
|
||||
:param user_email: Merge commit `user_email`.
|
||||
:param message: Merge commit `message`.
|
||||
|
|
@ -492,12 +493,9 @@ class BaseRepository(object):
|
|||
if not message:
|
||||
raise ValueError('message cannot be empty')
|
||||
|
||||
shadow_repository_path = self._maybe_prepare_merge_workspace(
|
||||
workspace_id, target_ref, source_ref)
|
||||
|
||||
try:
|
||||
return self._merge_repo(
|
||||
shadow_repository_path, target_ref, source_repo,
|
||||
repo_id, workspace_id, target_ref, source_repo,
|
||||
source_ref, message, user_name, user_email, dry_run=dry_run,
|
||||
use_rebase=use_rebase, close_branch=close_branch)
|
||||
except RepositoryError:
|
||||
|
|
@ -507,14 +505,15 @@ class BaseRepository(object):
|
|||
return MergeResponse(
|
||||
False, False, None, MergeFailureReason.UNKNOWN)
|
||||
|
||||
def _merge_repo(self, shadow_repository_path, target_ref,
|
||||
def _merge_repo(self, repo_id, workspace_id, target_ref,
|
||||
source_repo, source_ref, merge_message,
|
||||
merger_name, merger_email, dry_run=False,
|
||||
use_rebase=False, close_branch=False):
|
||||
"""Internal implementation of merge."""
|
||||
raise NotImplementedError
|
||||
|
||||
def _maybe_prepare_merge_workspace(self, workspace_id, target_ref, source_ref):
|
||||
def _maybe_prepare_merge_workspace(
|
||||
self, repo_id, workspace_id, target_ref, source_ref):
|
||||
"""
|
||||
Create the merge workspace.
|
||||
|
||||
|
|
@ -522,10 +521,27 @@ class BaseRepository(object):
|
|||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def _get_shadow_repository_path(self, workspace_id):
|
||||
raise NotImplementedError
|
||||
def _get_legacy_shadow_repository_path(self, workspace_id):
|
||||
"""
|
||||
Legacy version that was used before. We still need it for
|
||||
backward compat
|
||||
"""
|
||||
return os.path.join(
|
||||
os.path.dirname(self.path),
|
||||
'.__shadow_%s_%s' % (os.path.basename(self.path), workspace_id))
|
||||
|
||||
def cleanup_merge_workspace(self, workspace_id):
|
||||
def _get_shadow_repository_path(self, repo_id, workspace_id):
|
||||
# The name of the shadow repository must start with '.', so it is
|
||||
# skipped by 'rhodecode.lib.utils.get_filesystem_repos'.
|
||||
legacy_repository_path = self._get_legacy_shadow_repository_path(workspace_id)
|
||||
if os.path.exists(legacy_repository_path):
|
||||
return legacy_repository_path
|
||||
else:
|
||||
return os.path.join(
|
||||
os.path.dirname(self.path),
|
||||
'.__shadow_repo_%s_%s' % (repo_id, workspace_id))
|
||||
|
||||
def cleanup_merge_workspace(self, repo_id, workspace_id):
|
||||
"""
|
||||
Remove merge workspace.
|
||||
|
||||
|
|
@ -534,7 +550,7 @@ class BaseRepository(object):
|
|||
|
||||
:param workspace_id: `workspace_id` unique identifier.
|
||||
"""
|
||||
shadow_repository_path = self._get_shadow_repository_path(workspace_id)
|
||||
shadow_repository_path = self._get_shadow_repository_path(repo_id, workspace_id)
|
||||
shadow_repository_path_del = '{}.{}.delete'.format(
|
||||
shadow_repository_path, time.time())
|
||||
|
||||
|
|
|
|||
|
|
@ -902,7 +902,19 @@ class GitRepository(BaseRepository):
|
|||
|
||||
return '%s%d' % (prefix, branch_id)
|
||||
|
||||
def _merge_repo(self, shadow_repository_path, target_ref,
|
||||
def _maybe_prepare_merge_workspace(
|
||||
self, repo_id, workspace_id, target_ref, source_ref):
|
||||
shadow_repository_path = self._get_shadow_repository_path(
|
||||
repo_id, workspace_id)
|
||||
if not os.path.exists(shadow_repository_path):
|
||||
self._local_clone(
|
||||
shadow_repository_path, target_ref.name, source_ref.name)
|
||||
log.debug(
|
||||
'Prepared shadow repository in %s', shadow_repository_path)
|
||||
|
||||
return shadow_repository_path
|
||||
|
||||
def _merge_repo(self, repo_id, workspace_id, target_ref,
|
||||
source_repo, source_ref, merge_message,
|
||||
merger_name, merger_email, dry_run=False,
|
||||
use_rebase=False, close_branch=False):
|
||||
|
|
@ -912,7 +924,10 @@ class GitRepository(BaseRepository):
|
|||
return MergeResponse(
|
||||
False, False, None, MergeFailureReason.TARGET_IS_NOT_HEAD)
|
||||
|
||||
shadow_repo = GitRepository(shadow_repository_path)
|
||||
shadow_repository_path = self._maybe_prepare_merge_workspace(
|
||||
repo_id, workspace_id, target_ref, source_ref)
|
||||
shadow_repo = self._get_shadow_instance(shadow_repository_path)
|
||||
|
||||
# checkout source, if it's different. Otherwise we could not
|
||||
# fetch proper commits for merge testing
|
||||
if source_ref.name != target_ref.name:
|
||||
|
|
@ -929,7 +944,7 @@ class GitRepository(BaseRepository):
|
|||
|
||||
# Need to reload repo to invalidate the cache, or otherwise we cannot
|
||||
# retrieve the last target commit.
|
||||
shadow_repo = GitRepository(shadow_repository_path)
|
||||
shadow_repo = self._get_shadow_instance(shadow_repository_path)
|
||||
if target_ref.commit_id != shadow_repo.branches[target_ref.name]:
|
||||
log.warning('Shadow Target ref %s commit mismatch %s vs %s',
|
||||
target_ref, target_ref.commit_id,
|
||||
|
|
@ -989,18 +1004,3 @@ class GitRepository(BaseRepository):
|
|||
return MergeResponse(
|
||||
merge_possible, merge_succeeded, merge_ref,
|
||||
merge_failure_reason)
|
||||
|
||||
def _get_shadow_repository_path(self, workspace_id):
|
||||
# The name of the shadow repository must start with '.', so it is
|
||||
# skipped by 'rhodecode.lib.utils.get_filesystem_repos'.
|
||||
return os.path.join(
|
||||
os.path.dirname(self.path),
|
||||
'.__shadow_%s_%s' % (os.path.basename(self.path), workspace_id))
|
||||
|
||||
def _maybe_prepare_merge_workspace(self, workspace_id, target_ref, source_ref):
|
||||
shadow_repository_path = self._get_shadow_repository_path(workspace_id)
|
||||
if not os.path.exists(shadow_repository_path):
|
||||
self._local_clone(
|
||||
shadow_repository_path, target_ref.name, source_ref.name)
|
||||
|
||||
return shadow_repository_path
|
||||
|
|
|
|||
|
|
@ -681,15 +681,10 @@ class MercurialRepository(BaseRepository):
|
|||
return ref.name
|
||||
return self._remote.ctx_branch(ref.commit_id)
|
||||
|
||||
def _get_shadow_repository_path(self, workspace_id):
|
||||
# The name of the shadow repository must start with '.', so it is
|
||||
# skipped by 'rhodecode.lib.utils.get_filesystem_repos'.
|
||||
return os.path.join(
|
||||
os.path.dirname(self.path),
|
||||
'.__shadow_%s_%s' % (os.path.basename(self.path), workspace_id))
|
||||
|
||||
def _maybe_prepare_merge_workspace(self, workspace_id, unused_target_ref, unused_source_ref):
|
||||
shadow_repository_path = self._get_shadow_repository_path(workspace_id)
|
||||
def _maybe_prepare_merge_workspace(
|
||||
self, repo_id, workspace_id, unused_target_ref, unused_source_ref):
|
||||
shadow_repository_path = self._get_shadow_repository_path(
|
||||
repo_id, workspace_id)
|
||||
if not os.path.exists(shadow_repository_path):
|
||||
self._local_clone(shadow_repository_path)
|
||||
log.debug(
|
||||
|
|
@ -697,7 +692,7 @@ class MercurialRepository(BaseRepository):
|
|||
|
||||
return shadow_repository_path
|
||||
|
||||
def _merge_repo(self, shadow_repository_path, target_ref,
|
||||
def _merge_repo(self, repo_id, workspace_id, target_ref,
|
||||
source_repo, source_ref, merge_message,
|
||||
merger_name, merger_email, dry_run=False,
|
||||
use_rebase=False, close_branch=False):
|
||||
|
|
@ -719,6 +714,8 @@ class MercurialRepository(BaseRepository):
|
|||
return MergeResponse(
|
||||
False, False, None, MergeFailureReason.MISSING_TARGET_REF)
|
||||
|
||||
shadow_repository_path = self._maybe_prepare_merge_workspace(
|
||||
repo_id, workspace_id, target_ref, source_ref)
|
||||
shadow_repo = self._get_shadow_instance(shadow_repository_path)
|
||||
|
||||
log.debug('Pulling in target reference %s', target_ref)
|
||||
|
|
|
|||
|
|
@ -1883,6 +1883,12 @@ class Repository(Base, BaseModel):
|
|||
return os.listdir(diff_cache_dir)
|
||||
return []
|
||||
|
||||
def shadow_repos(self):
|
||||
shadow_repos_pattern = '.__shadow_repo_{}'.format(self.repo_id)
|
||||
return [
|
||||
x for x in os.listdir(os.path.dirname(self.repo_full_path))
|
||||
if x.startswith(shadow_repos_pattern)]
|
||||
|
||||
def get_new_name(self, repo_name):
|
||||
"""
|
||||
returns new full repository name based on assigned group and new new
|
||||
|
|
@ -3762,7 +3768,7 @@ class PullRequest(Base, _PullRequestBase):
|
|||
workspace_id = self.workspace_id
|
||||
vcs_obj = self.target_repo.scm_instance()
|
||||
shadow_repository_path = vcs_obj._get_shadow_repository_path(
|
||||
workspace_id)
|
||||
self.target_repo.repo_id, workspace_id)
|
||||
if os.path.isdir(shadow_repository_path):
|
||||
return vcs_obj._get_shadow_instance(shadow_repository_path)
|
||||
|
||||
|
|
|
|||
|
|
@ -583,7 +583,7 @@ class PullRequestModel(BaseModel):
|
|||
|
||||
return commit_ids
|
||||
|
||||
def merge(self, pull_request, user, extras):
|
||||
def merge_repo(self, pull_request, user, extras):
|
||||
log.debug("Merging pull request %s", pull_request.pull_request_id)
|
||||
merge_state = self._merge_pull_request(pull_request, user, extras)
|
||||
if merge_state.executed:
|
||||
|
|
@ -616,6 +616,7 @@ class PullRequestModel(BaseModel):
|
|||
}
|
||||
|
||||
workspace_id = self._workspace_id(pull_request)
|
||||
repo_id = pull_request.target_repo.repo_id
|
||||
use_rebase = self._use_rebase_for_merging(pull_request)
|
||||
close_branch = self._close_branch_before_merging(pull_request)
|
||||
|
||||
|
|
@ -629,9 +630,10 @@ class PullRequestModel(BaseModel):
|
|||
target_vcs.config.set(
|
||||
'rhodecode', 'RC_SCM_DATA', json.dumps(extras))
|
||||
merge_state = target_vcs.merge(
|
||||
target_ref, source_vcs, pull_request.source_ref_parts,
|
||||
workspace_id, user_name=user.username,
|
||||
user_email=user.email, message=message, use_rebase=use_rebase,
|
||||
repo_id, workspace_id, target_ref, source_vcs,
|
||||
pull_request.source_ref_parts,
|
||||
user_name=user.username, user_email=user.email,
|
||||
message=message, use_rebase=use_rebase,
|
||||
close_branch=close_branch)
|
||||
return merge_state
|
||||
|
||||
|
|
@ -1328,11 +1330,13 @@ class PullRequestModel(BaseModel):
|
|||
def _refresh_merge_state(self, pull_request, target_vcs, target_reference):
|
||||
workspace_id = self._workspace_id(pull_request)
|
||||
source_vcs = pull_request.source_repo.scm_instance()
|
||||
repo_id = pull_request.target_repo.repo_id
|
||||
use_rebase = self._use_rebase_for_merging(pull_request)
|
||||
close_branch = self._close_branch_before_merging(pull_request)
|
||||
merge_state = target_vcs.merge(
|
||||
repo_id, workspace_id,
|
||||
target_reference, source_vcs, pull_request.source_ref_parts,
|
||||
workspace_id, dry_run=True, use_rebase=use_rebase,
|
||||
dry_run=True, use_rebase=use_rebase,
|
||||
close_branch=close_branch)
|
||||
|
||||
# Do not store the response if there was an unknown error.
|
||||
|
|
@ -1398,11 +1402,12 @@ class PullRequestModel(BaseModel):
|
|||
|
||||
def _cleanup_merge_workspace(self, pull_request):
|
||||
# Merging related cleanup
|
||||
repo_id = pull_request.target_repo.repo_id
|
||||
target_scm = pull_request.target_repo.scm_instance()
|
||||
workspace_id = 'pr-%s' % pull_request.pull_request_id
|
||||
workspace_id = self._workspace_id(pull_request)
|
||||
|
||||
try:
|
||||
target_scm.cleanup_merge_workspace(workspace_id)
|
||||
target_scm.cleanup_merge_workspace(repo_id, workspace_id)
|
||||
except NotImplementedError:
|
||||
pass
|
||||
|
||||
|
|
|
|||
|
|
@ -116,6 +116,13 @@ def get_new_dir(title):
|
|||
return get_normalized_path(path)
|
||||
|
||||
|
||||
def repo_id_generator(name):
|
||||
numeric_hash = 0
|
||||
for char in name:
|
||||
numeric_hash += (ord(char))
|
||||
return numeric_hash
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('app', 'index_location')
|
||||
class TestController(object):
|
||||
|
||||
|
|
|
|||
|
|
@ -333,7 +333,7 @@ class TestShadowRepoExposure(object):
|
|||
workspace_id = PullRequestModel()._workspace_id(pull_request)
|
||||
target_vcs = pull_request.target_repo.scm_instance()
|
||||
vcs_repo_name = target_vcs._get_shadow_repository_path(
|
||||
workspace_id)
|
||||
pull_request.target_repo.repo_id, workspace_id)
|
||||
|
||||
assert controller.vcs_repo_name == vcs_repo_name
|
||||
assert controller.url_repo_name == shadow_url
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ class TestPullRequestModel(object):
|
|||
self.source_commit = self.pull_request.source_ref_parts.commit_id
|
||||
self.target_commit = self.pull_request.target_ref_parts.commit_id
|
||||
self.workspace_id = 'pr-%s' % self.pull_request.pull_request_id
|
||||
self.repo_id = self.pull_request.target_repo.repo_id
|
||||
|
||||
@request.addfinalizer
|
||||
def cleanup_pull_request():
|
||||
|
|
@ -135,17 +136,19 @@ class TestPullRequestModel(object):
|
|||
assert pr_count == 1
|
||||
|
||||
def test_delete_calls_cleanup_merge(self, pull_request):
|
||||
repo_id = pull_request.target_repo.repo_id
|
||||
PullRequestModel().delete(pull_request, pull_request.author)
|
||||
|
||||
self.workspace_remove_mock.assert_called_once_with(
|
||||
self.workspace_id)
|
||||
repo_id, self.workspace_id)
|
||||
|
||||
def test_close_calls_cleanup_and_hook(self, pull_request):
|
||||
PullRequestModel().close_pull_request(
|
||||
pull_request, pull_request.author)
|
||||
repo_id = pull_request.target_repo.repo_id
|
||||
|
||||
self.workspace_remove_mock.assert_called_once_with(
|
||||
self.workspace_id)
|
||||
repo_id, self.workspace_id)
|
||||
self.hook_mock.assert_called_with(
|
||||
self.pull_request, self.pull_request.author, 'close')
|
||||
|
||||
|
|
@ -161,9 +164,10 @@ class TestPullRequestModel(object):
|
|||
assert status is True
|
||||
assert msg.eval() == 'This pull request can be automatically merged.'
|
||||
self.merge_mock.assert_called_with(
|
||||
self.repo_id, self.workspace_id,
|
||||
pull_request.target_ref_parts,
|
||||
pull_request.source_repo.scm_instance(),
|
||||
pull_request.source_ref_parts, self.workspace_id, dry_run=True,
|
||||
pull_request.source_ref_parts, dry_run=True,
|
||||
use_rebase=False, close_branch=False)
|
||||
|
||||
assert pull_request._last_merge_source_rev == self.source_commit
|
||||
|
|
@ -190,9 +194,10 @@ class TestPullRequestModel(object):
|
|||
msg.eval() ==
|
||||
'This pull request cannot be merged because of merge conflicts.')
|
||||
self.merge_mock.assert_called_with(
|
||||
self.repo_id, self.workspace_id,
|
||||
pull_request.target_ref_parts,
|
||||
pull_request.source_repo.scm_instance(),
|
||||
pull_request.source_ref_parts, self.workspace_id, dry_run=True,
|
||||
pull_request.source_ref_parts, dry_run=True,
|
||||
use_rebase=False, close_branch=False)
|
||||
|
||||
assert pull_request._last_merge_source_rev == self.source_commit
|
||||
|
|
@ -222,9 +227,10 @@ class TestPullRequestModel(object):
|
|||
'This pull request cannot be merged because of an unhandled'
|
||||
' exception.')
|
||||
self.merge_mock.assert_called_with(
|
||||
self.repo_id, self.workspace_id,
|
||||
pull_request.target_ref_parts,
|
||||
pull_request.source_repo.scm_instance(),
|
||||
pull_request.source_ref_parts, self.workspace_id, dry_run=True,
|
||||
pull_request.source_ref_parts, dry_run=True,
|
||||
use_rebase=False, close_branch=False)
|
||||
|
||||
assert pull_request._last_merge_source_rev is None
|
||||
|
|
@ -281,7 +287,7 @@ class TestPullRequestModel(object):
|
|||
True, True, merge_ref, MergeFailureReason.NONE)
|
||||
|
||||
merge_extras['repository'] = pull_request.target_repo.repo_name
|
||||
PullRequestModel().merge(
|
||||
PullRequestModel().merge_repo(
|
||||
pull_request, pull_request.author, extras=merge_extras)
|
||||
|
||||
message = (
|
||||
|
|
@ -295,9 +301,10 @@ class TestPullRequestModel(object):
|
|||
)
|
||||
)
|
||||
self.merge_mock.assert_called_with(
|
||||
self.repo_id, self.workspace_id,
|
||||
pull_request.target_ref_parts,
|
||||
pull_request.source_repo.scm_instance(),
|
||||
pull_request.source_ref_parts, self.workspace_id,
|
||||
pull_request.source_ref_parts,
|
||||
user_name=user.username, user_email=user.email, message=message,
|
||||
use_rebase=False, close_branch=False
|
||||
)
|
||||
|
|
@ -320,7 +327,7 @@ class TestPullRequestModel(object):
|
|||
False, False, merge_ref, MergeFailureReason.MERGE_FAILED)
|
||||
|
||||
merge_extras['repository'] = pull_request.target_repo.repo_name
|
||||
PullRequestModel().merge(
|
||||
PullRequestModel().merge_repo(
|
||||
pull_request, pull_request.author, extras=merge_extras)
|
||||
|
||||
message = (
|
||||
|
|
@ -334,9 +341,10 @@ class TestPullRequestModel(object):
|
|||
)
|
||||
)
|
||||
self.merge_mock.assert_called_with(
|
||||
self.repo_id, self.workspace_id,
|
||||
pull_request.target_ref_parts,
|
||||
pull_request.source_repo.scm_instance(),
|
||||
pull_request.source_ref_parts, self.workspace_id,
|
||||
pull_request.source_ref_parts,
|
||||
user_name=user.username, user_email=user.email, message=message,
|
||||
use_rebase=False, close_branch=False
|
||||
)
|
||||
|
|
@ -392,7 +400,7 @@ class TestIntegrationMerge(object):
|
|||
Session().commit()
|
||||
|
||||
with mock.patch.dict(rhodecode.CONFIG, extra_config, clear=False):
|
||||
merge_state = PullRequestModel().merge(
|
||||
merge_state = PullRequestModel().merge_repo(
|
||||
pull_request, user_admin, extras=merge_extras)
|
||||
|
||||
assert merge_state.executed
|
||||
|
|
@ -409,7 +417,7 @@ class TestIntegrationMerge(object):
|
|||
|
||||
with mock.patch('rhodecode.EXTENSIONS.PRE_PUSH_HOOK') as pre_pull:
|
||||
pre_pull.side_effect = RepositoryError("Disallow push!")
|
||||
merge_status = PullRequestModel().merge(
|
||||
merge_status = PullRequestModel().merge_repo(
|
||||
pull_request, user_admin, extras=merge_extras)
|
||||
|
||||
assert not merge_status.executed
|
||||
|
|
@ -429,7 +437,7 @@ class TestIntegrationMerge(object):
|
|||
merge_extras['repository'] = pull_request.target_repo.repo_name
|
||||
# TODO: johbo: Needed for sqlite, try to find an automatic way for it
|
||||
Session().commit()
|
||||
merge_status = PullRequestModel().merge(
|
||||
merge_status = PullRequestModel().merge_repo(
|
||||
pull_request, user_regular, extras=merge_extras)
|
||||
assert not merge_status.executed
|
||||
|
||||
|
|
|
|||
|
|
@ -566,7 +566,7 @@ TODO: To be written...
|
|||
|
||||
def test_maybe_prepare_merge_workspace(self):
|
||||
workspace = self.repo._maybe_prepare_merge_workspace(
|
||||
'pr2', Reference('branch', 'master', 'unused'),
|
||||
2, 'pr2', Reference('branch', 'master', 'unused'),
|
||||
Reference('branch', 'master', 'unused'))
|
||||
|
||||
assert os.path.isdir(workspace)
|
||||
|
|
@ -575,13 +575,13 @@ TODO: To be written...
|
|||
|
||||
# Calling it a second time should also succeed
|
||||
workspace = self.repo._maybe_prepare_merge_workspace(
|
||||
'pr2', Reference('branch', 'master', 'unused'),
|
||||
2, 'pr2', Reference('branch', 'master', 'unused'),
|
||||
Reference('branch', 'master', 'unused'))
|
||||
assert os.path.isdir(workspace)
|
||||
|
||||
def test_maybe_prepare_merge_workspace_different_refs(self):
|
||||
workspace = self.repo._maybe_prepare_merge_workspace(
|
||||
'pr2', Reference('branch', 'master', 'unused'),
|
||||
2, 'pr2', Reference('branch', 'master', 'unused'),
|
||||
Reference('branch', 'develop', 'unused'))
|
||||
|
||||
assert os.path.isdir(workspace)
|
||||
|
|
@ -590,22 +590,22 @@ TODO: To be written...
|
|||
|
||||
# Calling it a second time should also succeed
|
||||
workspace = self.repo._maybe_prepare_merge_workspace(
|
||||
'pr2', Reference('branch', 'master', 'unused'),
|
||||
2, 'pr2', Reference('branch', 'master', 'unused'),
|
||||
Reference('branch', 'develop', 'unused'))
|
||||
assert os.path.isdir(workspace)
|
||||
|
||||
def test_cleanup_merge_workspace(self):
|
||||
workspace = self.repo._maybe_prepare_merge_workspace(
|
||||
'pr3', Reference('branch', 'master', 'unused'),
|
||||
2, 'pr3', Reference('branch', 'master', 'unused'),
|
||||
Reference('branch', 'master', 'unused'))
|
||||
self.repo.cleanup_merge_workspace('pr3')
|
||||
self.repo.cleanup_merge_workspace(2, 'pr3')
|
||||
|
||||
assert not os.path.exists(workspace)
|
||||
|
||||
def test_cleanup_merge_workspace_invalid_workspace_id(self):
|
||||
# No assert: because in case of an inexistent workspace this function
|
||||
# should still succeed.
|
||||
self.repo.cleanup_merge_workspace('pr4')
|
||||
self.repo.cleanup_merge_workspace(1, 'pr4')
|
||||
|
||||
def test_set_refs(self):
|
||||
test_ref = 'refs/test-refs/abcde'
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ from rhodecode.lib.vcs.backends.hg import MercurialRepository, MercurialCommit
|
|||
from rhodecode.lib.vcs.exceptions import (
|
||||
RepositoryError, VCSError, NodeDoesNotExistError, CommitDoesNotExistError)
|
||||
from rhodecode.lib.vcs.nodes import FileNode, NodeKind, NodeState
|
||||
from rhodecode.tests import TEST_HG_REPO, TEST_HG_REPO_CLONE
|
||||
from rhodecode.tests import TEST_HG_REPO, TEST_HG_REPO_CLONE, repo_id_generator
|
||||
|
||||
|
||||
pytestmark = pytest.mark.backends("hg")
|
||||
|
|
@ -46,7 +46,6 @@ def repo_path_generator():
|
|||
i += 1
|
||||
yield '%s-%d' % (TEST_HG_REPO_CLONE, i)
|
||||
|
||||
|
||||
REPO_PATH_GENERATOR = repo_path_generator()
|
||||
|
||||
|
||||
|
|
@ -553,7 +552,7 @@ TODO: To be written...
|
|||
|
||||
def test_maybe_prepare_merge_workspace(self):
|
||||
workspace = self.repo._maybe_prepare_merge_workspace(
|
||||
'pr2', 'unused', 'unused2')
|
||||
1, 'pr2', 'unused', 'unused2')
|
||||
|
||||
assert os.path.isdir(workspace)
|
||||
workspace_repo = MercurialRepository(workspace)
|
||||
|
|
@ -561,20 +560,22 @@ TODO: To be written...
|
|||
|
||||
# Calling it a second time should also succeed
|
||||
workspace = self.repo._maybe_prepare_merge_workspace(
|
||||
'pr2', 'unused', 'unused2')
|
||||
1, 'pr2', 'unused', 'unused2')
|
||||
assert os.path.isdir(workspace)
|
||||
|
||||
def test_cleanup_merge_workspace(self):
|
||||
workspace = self.repo._maybe_prepare_merge_workspace(
|
||||
'pr3', 'unused', 'unused2')
|
||||
self.repo.cleanup_merge_workspace('pr3')
|
||||
1, 'pr3', 'unused', 'unused2')
|
||||
|
||||
assert os.path.isdir(workspace)
|
||||
self.repo.cleanup_merge_workspace(1, 'pr3')
|
||||
|
||||
assert not os.path.exists(workspace)
|
||||
|
||||
def test_cleanup_merge_workspace_invalid_workspace_id(self):
|
||||
# No assert: because in case of an inexistent workspace this function
|
||||
# should still succeed.
|
||||
self.repo.cleanup_merge_workspace('pr4')
|
||||
self.repo.cleanup_merge_workspace(1, 'pr4')
|
||||
|
||||
def test_merge_target_is_bookmark(self, vcsbackend_hg):
|
||||
target_repo = vcsbackend_hg.create_repo(number_of_commits=1)
|
||||
|
|
@ -594,10 +595,10 @@ TODO: To be written...
|
|||
target_repo.bookmark(bookmark_name)
|
||||
target_ref = Reference('book', bookmark_name, target_commit.raw_id)
|
||||
source_ref = Reference('branch', default_branch, source_commit.raw_id)
|
||||
workspace = 'test-merge'
|
||||
|
||||
workspace_id = 'test-merge'
|
||||
repo_id = repo_id_generator(target_repo.path)
|
||||
merge_response = target_repo.merge(
|
||||
target_ref, source_repo, source_ref, workspace,
|
||||
repo_id, workspace_id, target_ref, source_repo, source_ref,
|
||||
'test user', 'test@rhodecode.com', 'merge message 1',
|
||||
dry_run=False)
|
||||
expected_merge_response = MergeResponse(
|
||||
|
|
@ -638,10 +639,10 @@ TODO: To be written...
|
|||
source_repo._update(default_branch)
|
||||
source_repo.bookmark(bookmark_name)
|
||||
source_ref = Reference('book', bookmark_name, source_commit.raw_id)
|
||||
workspace = 'test-merge'
|
||||
|
||||
workspace_id = 'test-merge'
|
||||
repo_id = repo_id_generator(target_repo.path)
|
||||
merge_response = target_repo.merge(
|
||||
target_ref, source_repo, source_ref, workspace,
|
||||
repo_id, workspace_id, target_ref, source_repo, source_ref,
|
||||
'test user', 'test@rhodecode.com', 'merge message 1',
|
||||
dry_run=False)
|
||||
expected_merge_response = MergeResponse(
|
||||
|
|
@ -677,14 +678,15 @@ TODO: To be written...
|
|||
|
||||
target_ref = Reference('branch', default_branch, target_commit.raw_id)
|
||||
source_ref = Reference('branch', default_branch, source_commit.raw_id)
|
||||
workspace = 'test-merge'
|
||||
workspace_id = 'test-merge'
|
||||
|
||||
assert len(target_repo._heads(branch='default')) == 2
|
||||
expected_merge_response = MergeResponse(
|
||||
False, False, None,
|
||||
MergeFailureReason.HG_TARGET_HAS_MULTIPLE_HEADS)
|
||||
repo_id = repo_id_generator(target_repo.path)
|
||||
merge_response = target_repo.merge(
|
||||
target_ref, source_repo, source_ref, workspace,
|
||||
repo_id, workspace_id, target_ref, source_repo, source_ref,
|
||||
'test user', 'test@rhodecode.com', 'merge message 1',
|
||||
dry_run=False)
|
||||
assert merge_response == expected_merge_response
|
||||
|
|
@ -711,10 +713,11 @@ TODO: To be written...
|
|||
|
||||
target_ref = Reference('branch', default_branch, target_commit.raw_id)
|
||||
source_ref = Reference('book', bookmark_name, source_commit.raw_id)
|
||||
workspace = 'test-merge'
|
||||
repo_id = repo_id_generator(target_repo.path)
|
||||
workspace_id = 'test-merge'
|
||||
|
||||
merge_response = target_repo.merge(
|
||||
target_ref, source_repo, source_ref, workspace,
|
||||
repo_id, workspace_id, target_ref, source_repo, source_ref,
|
||||
'test user', 'test@rhodecode.com', 'merge message 1',
|
||||
dry_run=False, use_rebase=True)
|
||||
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ class TestMercurialRemoteRepoInvalidation(object):
|
|||
references.
|
||||
"""
|
||||
from rhodecode.model.pull_request import PullRequestModel
|
||||
|
||||
repo_id = pull_request.target_repo
|
||||
target_vcs = pull_request.target_repo.scm_instance()
|
||||
target_ref = pull_request.target_ref_parts
|
||||
source_ref = pull_request.source_ref_parts
|
||||
|
|
@ -104,7 +104,7 @@ class TestMercurialRemoteRepoInvalidation(object):
|
|||
pr = PullRequestModel()
|
||||
workspace_id = pr._workspace_id(pull_request)
|
||||
shadow_repository_path = target_vcs._maybe_prepare_merge_workspace(
|
||||
workspace_id, target_ref, source_ref)
|
||||
repo_id, workspace_id, target_ref, source_ref)
|
||||
shadow_repo = target_vcs._get_shadow_instance(shadow_repository_path)
|
||||
|
||||
# This will populate the cache of the mercurial repository object
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ from rhodecode.lib.vcs.backends.base import (
|
|||
from rhodecode.lib.vcs.exceptions import VCSError, RepositoryError
|
||||
from rhodecode.lib.vcs.nodes import FileNode
|
||||
from rhodecode.tests.vcs.conftest import BackendTestMixin
|
||||
from rhodecode.tests import repo_id_generator
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("vcs_repository_support")
|
||||
|
|
@ -268,7 +269,7 @@ class TestRepositoryGetCommonAncestor:
|
|||
|
||||
|
||||
@pytest.mark.backends("git", "hg")
|
||||
class TestRepositoryMerge:
|
||||
class TestRepositoryMerge(object):
|
||||
def prepare_for_success(self, vcsbackend):
|
||||
self.target_repo = vcsbackend.create_repo(number_of_commits=1)
|
||||
self.source_repo = vcsbackend.clone_repo(self.target_repo)
|
||||
|
|
@ -287,7 +288,8 @@ class TestRepositoryMerge:
|
|||
'branch', default_branch, self.target_commit.raw_id)
|
||||
self.source_ref = Reference(
|
||||
'branch', default_branch, self.source_commit.raw_id)
|
||||
self.workspace = 'test-merge'
|
||||
self.workspace_id = 'test-merge'
|
||||
self.repo_id = repo_id_generator(self.target_repo.path)
|
||||
|
||||
def prepare_for_conflict(self, vcsbackend):
|
||||
self.target_repo = vcsbackend.create_repo(number_of_commits=1)
|
||||
|
|
@ -302,13 +304,15 @@ class TestRepositoryMerge:
|
|||
'branch', default_branch, self.target_commit.raw_id)
|
||||
self.source_ref = Reference(
|
||||
'branch', default_branch, self.source_commit.raw_id)
|
||||
self.workspace = 'test-merge'
|
||||
self.workspace_id = 'test-merge'
|
||||
self.repo_id = repo_id_generator(self.target_repo.path)
|
||||
|
||||
def test_merge_success(self, vcsbackend):
|
||||
self.prepare_for_success(vcsbackend)
|
||||
|
||||
merge_response = self.target_repo.merge(
|
||||
self.target_ref, self.source_repo, self.source_ref, self.workspace,
|
||||
self.repo_id, self.workspace_id, self.target_ref, self.source_repo,
|
||||
self.source_ref,
|
||||
'test user', 'test@rhodecode.com', 'merge message 1',
|
||||
dry_run=False)
|
||||
expected_merge_response = MergeResponse(
|
||||
|
|
@ -334,7 +338,7 @@ class TestRepositoryMerge:
|
|||
merge_response.merge_ref.commit_id)
|
||||
|
||||
merge_response = target_repo.merge(
|
||||
target_ref, self.source_repo, self.source_ref, self.workspace,
|
||||
self.repo_id, self.workspace_id, target_ref, self.source_repo, self.source_ref,
|
||||
'test user', 'test@rhodecode.com', 'merge message 2',
|
||||
dry_run=False)
|
||||
expected_merge_response = MergeResponse(
|
||||
|
|
@ -353,13 +357,13 @@ class TestRepositoryMerge:
|
|||
self.prepare_for_success(vcsbackend)
|
||||
|
||||
merge_response = self.target_repo.merge(
|
||||
self.target_ref, self.source_repo, self.source_ref, self.workspace,
|
||||
dry_run=True)
|
||||
self.repo_id, self.workspace_id, self.target_ref, self.source_repo,
|
||||
self.source_ref, dry_run=True)
|
||||
|
||||
# We call it twice so to make sure we can handle updates
|
||||
merge_response_update = self.target_repo.merge(
|
||||
self.target_ref, self.source_repo, self.source_ref, self.workspace,
|
||||
dry_run=True)
|
||||
self.repo_id, self.workspace_id, self.target_ref, self.source_repo,
|
||||
self.source_ref, dry_run=True)
|
||||
|
||||
# Multiple merges may differ in their commit id. Therefore we set the
|
||||
# commit id to `None` before comparing the merge responses.
|
||||
|
|
@ -381,13 +385,15 @@ class TestRepositoryMerge:
|
|||
False, False, None, MergeFailureReason.MERGE_FAILED)
|
||||
|
||||
merge_response = self.target_repo.merge(
|
||||
self.target_ref, self.source_repo, self.source_ref, self.workspace,
|
||||
self.repo_id, self.workspace_id, self.target_ref,
|
||||
self.source_repo, self.source_ref,
|
||||
'test_user', 'test@rhodecode.com', 'test message', dry_run=dry_run)
|
||||
assert merge_response == expected_merge_response
|
||||
|
||||
# We call it twice so to make sure we can handle updates
|
||||
merge_response = self.target_repo.merge(
|
||||
self.target_ref, self.source_repo, self.source_ref, self.workspace,
|
||||
self.repo_id, self.workspace_id, self.target_ref, self.source_repo,
|
||||
self.source_ref,
|
||||
'test_user', 'test@rhodecode.com', 'test message', dry_run=dry_run)
|
||||
assert merge_response == expected_merge_response
|
||||
|
||||
|
|
@ -400,8 +406,8 @@ class TestRepositoryMerge:
|
|||
self.target_ref.type, self.target_ref.name, '0' * 40)
|
||||
|
||||
merge_response = self.target_repo.merge(
|
||||
target_ref, self.source_repo, self.source_ref, self.workspace,
|
||||
dry_run=True)
|
||||
self.repo_id, self.workspace_id, target_ref, self.source_repo,
|
||||
self.source_ref, dry_run=True)
|
||||
|
||||
assert merge_response == expected_merge_response
|
||||
|
||||
|
|
@ -414,7 +420,8 @@ class TestRepositoryMerge:
|
|||
self.source_ref.type, 'not_existing', self.source_ref.commit_id)
|
||||
|
||||
merge_response = self.target_repo.merge(
|
||||
self.target_ref, self.source_repo, source_ref, self.workspace,
|
||||
self.repo_id, self.workspace_id, self.target_ref,
|
||||
self.source_repo, source_ref,
|
||||
dry_run=True)
|
||||
|
||||
assert merge_response == expected_merge_response
|
||||
|
|
@ -427,29 +434,38 @@ class TestRepositoryMerge:
|
|||
with mock.patch.object(self.target_repo, '_merge_repo',
|
||||
side_effect=RepositoryError()):
|
||||
merge_response = self.target_repo.merge(
|
||||
self.target_ref, self.source_repo, self.source_ref,
|
||||
self.workspace, dry_run=True)
|
||||
self.repo_id, self.workspace_id, self.target_ref,
|
||||
self.source_repo, self.source_ref,
|
||||
dry_run=True)
|
||||
|
||||
assert merge_response == expected_merge_response
|
||||
|
||||
def test_merge_invalid_user_name(self, vcsbackend):
|
||||
repo = vcsbackend.create_repo(number_of_commits=1)
|
||||
ref = Reference('branch', 'master', 'not_used')
|
||||
workspace_id = 'test-errors-in-merge'
|
||||
repo_id = repo_id_generator(workspace_id)
|
||||
with pytest.raises(ValueError):
|
||||
repo.merge(ref, self, ref, 'workspace_id')
|
||||
repo.merge(repo_id, workspace_id, ref, self, ref)
|
||||
|
||||
def test_merge_invalid_user_email(self, vcsbackend):
|
||||
repo = vcsbackend.create_repo(number_of_commits=1)
|
||||
ref = Reference('branch', 'master', 'not_used')
|
||||
workspace_id = 'test-errors-in-merge'
|
||||
repo_id = repo_id_generator(workspace_id)
|
||||
with pytest.raises(ValueError):
|
||||
repo.merge(ref, self, ref, 'workspace_id', 'user name')
|
||||
repo.merge(
|
||||
repo_id, workspace_id, ref, self, ref, 'user name')
|
||||
|
||||
def test_merge_invalid_message(self, vcsbackend):
|
||||
repo = vcsbackend.create_repo(number_of_commits=1)
|
||||
ref = Reference('branch', 'master', 'not_used')
|
||||
workspace_id = 'test-errors-in-merge'
|
||||
repo_id = repo_id_generator(workspace_id)
|
||||
with pytest.raises(ValueError):
|
||||
repo.merge(
|
||||
ref, self, ref, 'workspace_id', 'user name', 'user@email.com')
|
||||
repo_id, workspace_id, ref, self, ref,
|
||||
'user name', 'user@email.com')
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("vcs_repository_support")
|
||||
|
|
@ -505,7 +521,7 @@ class TestRepositoryStrip(BackendTestMixin):
|
|||
|
||||
|
||||
@pytest.mark.backends('hg', 'git')
|
||||
class TestRepositoryPull:
|
||||
class TestRepositoryPull(object):
|
||||
|
||||
def test_pull(self, vcsbackend):
|
||||
source_repo = vcsbackend.repo
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue