##// END OF EJS Templates
mercurial: Add option to close a branch before merging
Mathieu Cantin -
r2055:5bbc6873 default
parent child Browse files
Show More
@@ -533,6 +533,7 b' get_repo_settings'
533 533 "hooks_outgoing_pull_logger": true,
534 534 "phases_publish": "True",
535 535 "rhodecode_hg_use_rebase_for_merging": true,
536 "rhodecode_hg_close_branch_before_merging": false,
536 537 "rhodecode_pr_merge_enabled": true,
537 538 "rhodecode_use_outdated_comments": true
538 539 }
@@ -420,7 +420,7 b' class BaseRepository(object):'
420 420
421 421 def merge(self, target_ref, source_repo, source_ref, workspace_id,
422 422 user_name='', user_email='', message='', dry_run=False,
423 use_rebase=False):
423 use_rebase=False, close_branch=False):
424 424 """
425 425 Merge the revisions specified in `source_ref` from `source_repo`
426 426 onto the `target_ref` of this repository.
@@ -445,6 +445,7 b' class BaseRepository(object):'
445 445 :param dry_run: If `True` the merge will not take place.
446 446 :param use_rebase: If `True` commits from the source will be rebased
447 447 on top of the target instead of being merged.
448 :param close_branch: If `True` branch will be close before merging it
448 449 """
449 450 if dry_run:
450 451 message = message or 'dry_run_merge_message'
@@ -465,7 +466,7 b' class BaseRepository(object):'
465 466 return self._merge_repo(
466 467 shadow_repository_path, target_ref, source_repo,
467 468 source_ref, message, user_name, user_email, dry_run=dry_run,
468 use_rebase=use_rebase)
469 use_rebase=use_rebase, close_branch=close_branch)
469 470 except RepositoryError:
470 471 log.exception(
471 472 'Unexpected failure when running merge, dry-run=%s',
@@ -475,7 +476,8 b' class BaseRepository(object):'
475 476
476 477 def _merge_repo(self, shadow_repository_path, target_ref,
477 478 source_repo, source_ref, merge_message,
478 merger_name, merger_email, dry_run=False, use_rebase=False):
479 merger_name, merger_email, dry_run=False,
480 use_rebase=False, close_branch=False):
479 481 """Internal implementation of merge."""
480 482 raise NotImplementedError
481 483
@@ -849,7 +849,7 b' class GitRepository(BaseRepository):'
849 849 def _merge_repo(self, shadow_repository_path, target_ref,
850 850 source_repo, source_ref, merge_message,
851 851 merger_name, merger_email, dry_run=False,
852 use_rebase=False):
852 use_rebase=False, close_branch=False):
853 853 if target_ref.commit_id != self.branches[target_ref.name]:
854 854 return MergeResponse(
855 855 False, False, None, MergeFailureReason.TARGET_IS_NOT_HEAD)
@@ -646,6 +646,28 b' class MercurialRepository(BaseRepository'
646 646 self._remote.update(clean=True)
647 647 raise
648 648
649 def _local_close(self, target_ref, user_name, user_email,
650 source_ref, close_message=''):
651 """
652 Close the branch of the given source_revision
653
654 Returns the commit id of the close and a boolean indicating if the
655 commit needs to be pushed.
656 """
657 self._update(target_ref.commit_id)
658 message = close_message or "Closing branch"
659 try:
660 self._remote.commit(
661 message=safe_str(message),
662 username=safe_str('%s <%s>' % (user_name, user_email)),
663 close_branch=True)
664 self._remote.invalidate_vcs_cache()
665 return self._identify(), True
666 except RepositoryError:
667 # Cleanup any commit leftovers
668 self._remote.update(clean=True)
669 raise
670
649 671 def _is_the_same_branch(self, target_ref, source_ref):
650 672 return (
651 673 self._get_branch_name(target_ref) ==
@@ -679,7 +701,7 b' class MercurialRepository(BaseRepository'
679 701 def _merge_repo(self, shadow_repository_path, target_ref,
680 702 source_repo, source_ref, merge_message,
681 703 merger_name, merger_email, dry_run=False,
682 use_rebase=False):
704 use_rebase=False, close_branch=False):
683 705 if target_ref.commit_id not in self._heads():
684 706 return MergeResponse(
685 707 False, False, None, MergeFailureReason.TARGET_IS_NOT_HEAD)
@@ -712,6 +734,20 b' class MercurialRepository(BaseRepository'
712 734 merge_ref = None
713 735 merge_failure_reason = MergeFailureReason.NONE
714 736
737 if close_branch and not use_rebase:
738 try:
739 close_commit_id, needs_push = shadow_repo._local_close(
740 target_ref, merger_name, merger_email, source_ref)
741 target_ref.commit_id = close_commit_id
742 merge_possible = True
743 except RepositoryError:
744 log.exception('Failure when doing close branch on hg shadow repo')
745 merge_possible = False
746 merge_failure_reason = MergeFailureReason.MERGE_FAILED
747 else:
748 merge_possible = True
749
750 if merge_possible:
715 751 try:
716 752 merge_commit_id, needs_push = shadow_repo._local_merge(
717 753 target_ref, merge_message, merger_name, merger_email,
@@ -388,7 +388,9 b' class _BaseVcsSettingsForm(formencode.Sc'
388 388 extensions_largefiles = v.StringBoolean(if_missing=False)
389 389 extensions_evolve = v.StringBoolean(if_missing=False)
390 390 phases_publish = v.StringBoolean(if_missing=False)
391
391 392 rhodecode_hg_use_rebase_for_merging = v.StringBoolean(if_missing=False)
393 rhodecode_hg_close_branch_before_merging = v.StringBoolean(if_missing=False)
392 394
393 395 # git
394 396 vcs_git_lfs_enabled = v.StringBoolean(if_missing=False)
@@ -552,6 +552,7 b' class PullRequestModel(BaseModel):'
552 552
553 553 workspace_id = self._workspace_id(pull_request)
554 554 use_rebase = self._use_rebase_for_merging(pull_request)
555 close_branch = self._close_branch_before_merging(pull_request)
555 556
556 557 callback_daemon, extras = prepare_callback_daemon(
557 558 extras, protocol=vcs_settings.HOOKS_PROTOCOL,
@@ -565,7 +566,8 b' class PullRequestModel(BaseModel):'
565 566 merge_state = target_vcs.merge(
566 567 target_ref, source_vcs, pull_request.source_ref_parts,
567 568 workspace_id, user_name=user.username,
568 user_email=user.email, message=message, use_rebase=use_rebase)
569 user_email=user.email, message=message, use_rebase=use_rebase,
570 close_branch=close_branch)
569 571 return merge_state
570 572
571 573 def _comment_and_close_pr(self, pull_request, user, merge_state):
@@ -1249,9 +1251,11 b' class PullRequestModel(BaseModel):'
1249 1251 workspace_id = self._workspace_id(pull_request)
1250 1252 source_vcs = pull_request.source_repo.scm_instance()
1251 1253 use_rebase = self._use_rebase_for_merging(pull_request)
1254 close_branch = self._close_branch_before_merging(pull_request)
1252 1255 merge_state = target_vcs.merge(
1253 1256 target_reference, source_vcs, pull_request.source_ref_parts,
1254 workspace_id, dry_run=True, use_rebase=use_rebase)
1257 workspace_id, dry_run=True, use_rebase=use_rebase,
1258 close_branch=close_branch)
1255 1259
1256 1260 # Do not store the response if there was an unknown error.
1257 1261 if merge_state.failure_reason != MergeFailureReason.UNKNOWN:
@@ -1416,14 +1420,21 b' class PullRequestModel(BaseModel):'
1416 1420 return vcs_diff
1417 1421
1418 1422 def _is_merge_enabled(self, pull_request):
1423 return self._get_general_setting(
1424 pull_request, 'rhodecode_pr_merge_enabled')
1425
1426 def _use_rebase_for_merging(self, pull_request):
1427 return self._get_general_setting(
1428 pull_request, 'rhodecode_hg_use_rebase_for_merging')
1429
1430 def _close_branch_before_merging(self, pull_request):
1431 return self._get_general_setting(
1432 pull_request, 'rhodecode_hg_close_branch_before_merging')
1433
1434 def _get_general_setting(self, pull_request, settings_key, default=False):
1419 1435 settings_model = VcsSettingsModel(repo=pull_request.target_repo)
1420 1436 settings = settings_model.get_general_settings()
1421 return settings.get('rhodecode_pr_merge_enabled', False)
1422
1423 def _use_rebase_for_merging(self, pull_request):
1424 settings_model = VcsSettingsModel(repo=pull_request.target_repo)
1425 settings = settings_model.get_general_settings()
1426 return settings.get('rhodecode_hg_use_rebase_for_merging', False)
1437 return settings.get(settings_key, default)
1427 1438
1428 1439 def _log_audit_action(self, action, action_data, user, pull_request):
1429 1440 audit_logger.store(
@@ -408,7 +408,8 b' class VcsSettingsModel(object):'
408 408 GENERAL_SETTINGS = (
409 409 'use_outdated_comments',
410 410 'pr_merge_enabled',
411 'hg_use_rebase_for_merging')
411 'hg_use_rebase_for_merging',
412 'hg_close_branch_before_merging')
412 413
413 414 HOOKS_SETTINGS = (
414 415 ('hooks', 'changegroup.repo_size'),
@@ -161,6 +161,14 b''
161 161 <span class="help-block">${_('Use rebase instead of creating a merge commit when merging via web interface.')}</span>
162 162 </div>
163 163
164 <div class="checkbox">
165 ${h.checkbox('rhodecode_hg_close_branch_before_merging' + suffix, 'True', **kwargs)}
166 <label for="rhodecode_hg_close_branch_before_merging{suffix}">${_('Close branch before merging it')}</label>
167 </div>
168 <div class="label">
169 <span class="help-block">${_('Close branch before merging it into destination branch. No effect when rebase strategy is use.')}</span>
170 </div>
171
164 172 </div>
165 173 </div>
166 174 % endif
General Comments 0
You need to be logged in to leave comments. Login now