Show More
@@ -534,6 +534,8 b' get_repo_settings' | |||||
534 | "phases_publish": "True", |
|
534 | "phases_publish": "True", | |
535 | "rhodecode_hg_use_rebase_for_merging": true, |
|
535 | "rhodecode_hg_use_rebase_for_merging": true, | |
536 | "rhodecode_hg_close_branch_before_merging": false, |
|
536 | "rhodecode_hg_close_branch_before_merging": false, | |
|
537 | "rhodecode_git_use_rebase_for_merging": true, | |||
|
538 | "rhodecode_git_close_branch_before_merging": false, | |||
537 | "rhodecode_pr_merge_enabled": true, |
|
539 | "rhodecode_pr_merge_enabled": true, | |
538 | "rhodecode_use_outdated_comments": true |
|
540 | "rhodecode_use_outdated_comments": true | |
539 | } |
|
541 | } |
@@ -558,6 +558,7 b' class MercurialRepository(BaseRepository' | |||||
558 | """ |
|
558 | """ | |
559 | Update the working copty to the specified revision. |
|
559 | Update the working copty to the specified revision. | |
560 | """ |
|
560 | """ | |
|
561 | log.debug('Doing checkout to commit: `%s` for %s', revision, self) | |||
561 | self._remote.update(revision, clean=clean) |
|
562 | self._remote.update(revision, clean=clean) | |
562 |
|
563 | |||
563 | def _identify(self): |
|
564 | def _identify(self): | |
@@ -654,8 +655,8 b' class MercurialRepository(BaseRepository' | |||||
654 | Returns the commit id of the close and a boolean indicating if the |
|
655 | Returns the commit id of the close and a boolean indicating if the | |
655 | commit needs to be pushed. |
|
656 | commit needs to be pushed. | |
656 | """ |
|
657 | """ | |
657 |
self._update( |
|
658 | self._update(source_ref.commit_id) | |
658 | message = close_message or "Closing branch" |
|
659 | message = close_message or "Closing branch: `{}`".format(source_ref.name) | |
659 | try: |
|
660 | try: | |
660 | self._remote.commit( |
|
661 | self._remote.commit( | |
661 | message=safe_str(message), |
|
662 | message=safe_str(message), | |
@@ -732,16 +733,26 b' class MercurialRepository(BaseRepository' | |||||
732 | False, False, None, MergeFailureReason.MISSING_SOURCE_REF) |
|
733 | False, False, None, MergeFailureReason.MISSING_SOURCE_REF) | |
733 |
|
734 | |||
734 | merge_ref = None |
|
735 | merge_ref = None | |
|
736 | merge_commit_id = None | |||
|
737 | close_commit_id = None | |||
735 | merge_failure_reason = MergeFailureReason.NONE |
|
738 | merge_failure_reason = MergeFailureReason.NONE | |
736 |
|
739 | |||
737 | if close_branch and not use_rebase: |
|
740 | # enforce that close branch should be used only in case we source from | |
|
741 | # an actual Branch | |||
|
742 | close_branch = close_branch and source_ref.type == 'branch' | |||
|
743 | ||||
|
744 | # don't allow to close branch if source and target are the same | |||
|
745 | close_branch = close_branch and source_ref.name != target_ref.name | |||
|
746 | ||||
|
747 | needs_push_on_close = False | |||
|
748 | if close_branch and not use_rebase and not dry_run: | |||
738 | try: |
|
749 | try: | |
739 | close_commit_id, needs_push = shadow_repo._local_close( |
|
750 | close_commit_id, needs_push_on_close = shadow_repo._local_close( | |
740 | target_ref, merger_name, merger_email, source_ref) |
|
751 | target_ref, merger_name, merger_email, source_ref) | |
741 | target_ref.commit_id = close_commit_id |
|
|||
742 | merge_possible = True |
|
752 | merge_possible = True | |
743 | except RepositoryError: |
|
753 | except RepositoryError: | |
744 | log.exception('Failure when doing close branch on hg shadow repo') |
|
754 | log.exception( | |
|
755 | 'Failure when doing close branch on hg shadow repo') | |||
745 | merge_possible = False |
|
756 | merge_possible = False | |
746 | merge_failure_reason = MergeFailureReason.MERGE_FAILED |
|
757 | merge_failure_reason = MergeFailureReason.MERGE_FAILED | |
747 | else: |
|
758 | else: | |
@@ -754,9 +765,13 b' class MercurialRepository(BaseRepository' | |||||
754 | source_ref, use_rebase=use_rebase) |
|
765 | source_ref, use_rebase=use_rebase) | |
755 | merge_possible = True |
|
766 | merge_possible = True | |
756 |
|
767 | |||
757 | # Set a bookmark pointing to the merge commit. This bookmark may be |
|
768 | # read the state of the close action, if it | |
758 | # used to easily identify the last successful merge commit in the |
|
769 | # maybe required a push | |
759 | # shadow repository. |
|
770 | needs_push = needs_push or needs_push_on_close | |
|
771 | ||||
|
772 | # Set a bookmark pointing to the merge commit. This bookmark | |||
|
773 | # may be used to easily identify the last successful merge | |||
|
774 | # commit in the shadow repository. | |||
760 | shadow_repo.bookmark('pr-merge', revision=merge_commit_id) |
|
775 | shadow_repo.bookmark('pr-merge', revision=merge_commit_id) | |
761 | merge_ref = Reference('book', 'pr-merge', merge_commit_id) |
|
776 | merge_ref = Reference('book', 'pr-merge', merge_commit_id) | |
762 | except SubrepoMergeError: |
|
777 | except SubrepoMergeError: | |
@@ -776,7 +791,6 b' class MercurialRepository(BaseRepository' | |||||
776 | if target_ref.type == 'book': |
|
791 | if target_ref.type == 'book': | |
777 | shadow_repo.bookmark( |
|
792 | shadow_repo.bookmark( | |
778 | target_ref.name, revision=merge_commit_id) |
|
793 | target_ref.name, revision=merge_commit_id) | |
779 |
|
||||
780 | try: |
|
794 | try: | |
781 | shadow_repo_with_hooks = self._get_shadow_instance( |
|
795 | shadow_repo_with_hooks = self._get_shadow_instance( | |
782 | shadow_repository_path, |
|
796 | shadow_repository_path, | |
@@ -788,6 +802,12 b' class MercurialRepository(BaseRepository' | |||||
788 | shadow_repo_with_hooks._local_push( |
|
802 | shadow_repo_with_hooks._local_push( | |
789 | merge_commit_id, self.path, push_branches=True, |
|
803 | merge_commit_id, self.path, push_branches=True, | |
790 | enable_hooks=True) |
|
804 | enable_hooks=True) | |
|
805 | ||||
|
806 | # maybe we also need to push the close_commit_id | |||
|
807 | if close_commit_id: | |||
|
808 | shadow_repo_with_hooks._local_push( | |||
|
809 | close_commit_id, self.path, push_branches=True, | |||
|
810 | enable_hooks=True) | |||
791 | merge_succeeded = True |
|
811 | merge_succeeded = True | |
792 | except RepositoryError: |
|
812 | except RepositoryError: | |
793 | log.exception( |
|
813 | log.exception( |
@@ -394,6 +394,8 b' class _BaseVcsSettingsForm(formencode.Sc' | |||||
394 |
|
394 | |||
395 | # git |
|
395 | # git | |
396 | vcs_git_lfs_enabled = v.StringBoolean(if_missing=False) |
|
396 | vcs_git_lfs_enabled = v.StringBoolean(if_missing=False) | |
|
397 | rhodecode_git_use_rebase_for_merging = v.StringBoolean(if_missing=False) | |||
|
398 | rhodecode_git_close_branch_before_merging = v.StringBoolean(if_missing=False) | |||
397 |
|
399 | |||
398 | # svn |
|
400 | # svn | |
399 | vcs_svn_proxy_http_requests_enabled = v.StringBoolean(if_missing=False) |
|
401 | vcs_svn_proxy_http_requests_enabled = v.StringBoolean(if_missing=False) |
@@ -1424,12 +1424,26 b' class PullRequestModel(BaseModel):' | |||||
1424 | pull_request, 'rhodecode_pr_merge_enabled') |
|
1424 | pull_request, 'rhodecode_pr_merge_enabled') | |
1425 |
|
1425 | |||
1426 | def _use_rebase_for_merging(self, pull_request): |
|
1426 | def _use_rebase_for_merging(self, pull_request): | |
1427 | return self._get_general_setting( |
|
1427 | repo_type = pull_request.target_repo.repo_type | |
1428 | pull_request, 'rhodecode_hg_use_rebase_for_merging') |
|
1428 | if repo_type == 'hg': | |
|
1429 | return self._get_general_setting( | |||
|
1430 | pull_request, 'rhodecode_hg_use_rebase_for_merging') | |||
|
1431 | elif repo_type == 'git': | |||
|
1432 | return self._get_general_setting( | |||
|
1433 | pull_request, 'rhodecode_git_use_rebase_for_merging') | |||
|
1434 | ||||
|
1435 | return False | |||
1429 |
|
1436 | |||
1430 | def _close_branch_before_merging(self, pull_request): |
|
1437 | def _close_branch_before_merging(self, pull_request): | |
1431 | return self._get_general_setting( |
|
1438 | repo_type = pull_request.target_repo.repo_type | |
1432 | pull_request, 'rhodecode_hg_close_branch_before_merging') |
|
1439 | if repo_type == 'hg': | |
|
1440 | return self._get_general_setting( | |||
|
1441 | pull_request, 'rhodecode_hg_close_branch_before_merging') | |||
|
1442 | elif repo_type == 'git': | |||
|
1443 | return self._get_general_setting( | |||
|
1444 | pull_request, 'rhodecode_git_close_branch_before_merging') | |||
|
1445 | ||||
|
1446 | return False | |||
1433 |
|
1447 | |||
1434 | def _get_general_setting(self, pull_request, settings_key, default=False): |
|
1448 | def _get_general_setting(self, pull_request, settings_key, default=False): | |
1435 | settings_model = VcsSettingsModel(repo=pull_request.target_repo) |
|
1449 | settings_model = VcsSettingsModel(repo=pull_request.target_repo) |
@@ -409,7 +409,9 b' class VcsSettingsModel(object):' | |||||
409 | 'use_outdated_comments', |
|
409 | 'use_outdated_comments', | |
410 | 'pr_merge_enabled', |
|
410 | 'pr_merge_enabled', | |
411 | 'hg_use_rebase_for_merging', |
|
411 | 'hg_use_rebase_for_merging', | |
412 |
'hg_close_branch_before_merging' |
|
412 | 'hg_close_branch_before_merging', | |
|
413 | 'git_use_rebase_for_merging', | |||
|
414 | 'git_close_branch_before_merging') | |||
413 |
|
415 | |||
414 | HOOKS_SETTINGS = ( |
|
416 | HOOKS_SETTINGS = ( | |
415 | ('hooks', 'changegroup.repo_size'), |
|
417 | ('hooks', 'changegroup.repo_size'), |
@@ -145,34 +145,6 b'' | |||||
145 |
|
145 | |||
146 | </div> |
|
146 | </div> | |
147 | </div> |
|
147 | </div> | |
148 | ## LABS for HG |
|
|||
149 | % if c.labs_active: |
|
|||
150 | <div class="panel panel-danger"> |
|
|||
151 | <div class="panel-heading"> |
|
|||
152 | <h3 class="panel-title">${_('Mercurial Labs Settings')} (${_('These features are considered experimental and may not work as expected.')})</h3> |
|
|||
153 | </div> |
|
|||
154 | <div class="panel-body"> |
|
|||
155 |
|
||||
156 | <div class="checkbox"> |
|
|||
157 | ${h.checkbox('rhodecode_hg_use_rebase_for_merging' + suffix, 'True', **kwargs)} |
|
|||
158 | <label for="rhodecode_hg_use_rebase_for_merging${suffix}">${_('Use rebase as merge strategy')}</label> |
|
|||
159 | </div> |
|
|||
160 | <div class="label"> |
|
|||
161 | <span class="help-block">${_('Use rebase instead of creating a merge commit when merging via web interface.')}</span> |
|
|||
162 | </div> |
|
|||
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 |
|
||||
172 | </div> |
|
|||
173 | </div> |
|
|||
174 | % endif |
|
|||
175 |
|
||||
176 | % endif |
|
148 | % endif | |
177 |
|
149 | |||
178 | % if display_globals or repo_type in ['git']: |
|
150 | % if display_globals or repo_type in ['git']: | |
@@ -340,4 +312,59 b'' | |||||
340 | </div> |
|
312 | </div> | |
341 | % endif |
|
313 | % endif | |
342 |
|
314 | |||
|
315 | % if display_globals or repo_type in ['hg',]: | |||
|
316 | <div class="panel panel-default"> | |||
|
317 | <div class="panel-heading" id="vcs-pull-requests-options"> | |||
|
318 | <h3 class="panel-title">${_('Mercurial Pull Request Settings')}<a class="permalink" href="#vcs-hg-pull-requests-options"> ΒΆ</a></h3> | |||
|
319 | </div> | |||
|
320 | <div class="panel-body"> | |||
|
321 | ## Specific HG settings | |||
|
322 | <div class="checkbox"> | |||
|
323 | ${h.checkbox('rhodecode_hg_use_rebase_for_merging' + suffix, 'True', **kwargs)} | |||
|
324 | <label for="rhodecode_hg_use_rebase_for_merging${suffix}">${_('Use rebase as merge strategy')}</label> | |||
|
325 | </div> | |||
|
326 | <div class="label"> | |||
|
327 | <span class="help-block">${_('Use rebase instead of creating a merge commit when merging via web interface.')}</span> | |||
|
328 | </div> | |||
|
329 | ||||
|
330 | <div class="checkbox"> | |||
|
331 | ${h.checkbox('rhodecode_hg_close_branch_before_merging' + suffix, 'True', **kwargs)} | |||
|
332 | <label for="rhodecode_hg_close_branch_before_merging{suffix}">${_('Close branch before merging it')}</label> | |||
|
333 | </div> | |||
|
334 | <div class="label"> | |||
|
335 | <span class="help-block">${_('Close branch before merging it into destination branch. No effect when rebase strategy is use.')}</span> | |||
|
336 | </div> | |||
|
337 | ||||
|
338 | ||||
|
339 | </div> | |||
|
340 | </div> | |||
|
341 | % endif | |||
|
342 | ||||
|
343 | ## DISABLED FOR GIT FOR NOW as the rebase/close is not supported yet | |||
|
344 | ## % if display_globals or repo_type in ['git']: | |||
|
345 | ## <div class="panel panel-default"> | |||
|
346 | ## <div class="panel-heading" id="vcs-pull-requests-options"> | |||
|
347 | ## <h3 class="panel-title">${_('Git Pull Request Settings')}<a class="permalink" href="#vcs-git-pull-requests-options"> ΒΆ</a></h3> | |||
|
348 | ## </div> | |||
|
349 | ## <div class="panel-body"> | |||
|
350 | ## <div class="checkbox"> | |||
|
351 | ## ${h.checkbox('rhodecode_git_use_rebase_for_merging' + suffix, 'True', **kwargs)} | |||
|
352 | ## <label for="rhodecode_git_use_rebase_for_merging${suffix}">${_('Use rebase as merge strategy')}</label> | |||
|
353 | ## </div> | |||
|
354 | ## <div class="label"> | |||
|
355 | ## <span class="help-block">${_('Use rebase instead of creating a merge commit when merging via web interface.')}</span> | |||
|
356 | ## </div> | |||
|
357 | ## | |||
|
358 | ## <div class="checkbox"> | |||
|
359 | ## ${h.checkbox('rhodecode_git_close_branch_before_merging' + suffix, 'True', **kwargs)} | |||
|
360 | ## <label for="rhodecode_git_close_branch_before_merging{suffix}">${_('Delete branch after merging it')}</label> | |||
|
361 | ## </div> | |||
|
362 | ## <div class="label"> | |||
|
363 | ## <span class="help-block">${_('Delete branch after merging it into destination branch. No effect when rebase strategy is use.')}</span> | |||
|
364 | ## </div> | |||
|
365 | ## </div> | |||
|
366 | ## </div> | |||
|
367 | ## % endif | |||
|
368 | ||||
|
369 | ||||
343 | </%def> |
|
370 | </%def> |
@@ -324,18 +324,6 b' class TestAdminSettingsVcs(object):' | |||||
324 | setting = SettingsModel().get_setting_by_name(setting_key) |
|
324 | setting = SettingsModel().get_setting_by_name(setting_key) | |
325 | assert setting.app_settings_value is new_value |
|
325 | assert setting.app_settings_value is new_value | |
326 |
|
326 | |||
327 | def test_has_a_section_for_labs_settings_if_enabled(self, app): |
|
|||
328 | with mock.patch.dict( |
|
|||
329 | rhodecode.CONFIG, {'labs_settings_active': 'true'}): |
|
|||
330 | response = self.app.get(url('admin_settings_vcs')) |
|
|||
331 | response.mustcontain('Labs Settings') |
|
|||
332 |
|
||||
333 | def test_has_not_a_section_for_labs_settings_if_disables(self, app): |
|
|||
334 | with mock.patch.dict( |
|
|||
335 | rhodecode.CONFIG, {'labs_settings_active': 'false'}): |
|
|||
336 | response = self.app.get(url('admin_settings_vcs')) |
|
|||
337 | response.mustcontain(no='Labs Settings') |
|
|||
338 |
|
||||
339 | @pytest.mark.parametrize('new_value', [True, False]) |
|
327 | @pytest.mark.parametrize('new_value', [True, False]) | |
340 | def test_allows_to_change_hg_rebase_merge_strategy( |
|
328 | def test_allows_to_change_hg_rebase_merge_strategy( | |
341 | self, app, form_defaults, csrf_token, new_value): |
|
329 | self, app, form_defaults, csrf_token, new_value): |
@@ -41,6 +41,9 b' GENERAL_FORM_DATA = {' | |||||
41 | 'rhodecode_pr_merge_enabled': True, |
|
41 | 'rhodecode_pr_merge_enabled': True, | |
42 | 'rhodecode_use_outdated_comments': True, |
|
42 | 'rhodecode_use_outdated_comments': True, | |
43 | 'rhodecode_hg_use_rebase_for_merging': True, |
|
43 | 'rhodecode_hg_use_rebase_for_merging': True, | |
|
44 | 'rhodecode_hg_close_branch_before_merging': True, | |||
|
45 | 'rhodecode_git_use_rebase_for_merging': True, | |||
|
46 | 'rhodecode_git_close_branch_before_merging': True, | |||
44 | } |
|
47 | } | |
45 |
|
48 | |||
46 |
|
49 |
@@ -164,7 +164,7 b' class TestPullRequestModel(object):' | |||||
164 | pull_request.target_ref_parts, |
|
164 | pull_request.target_ref_parts, | |
165 | pull_request.source_repo.scm_instance(), |
|
165 | pull_request.source_repo.scm_instance(), | |
166 | pull_request.source_ref_parts, self.workspace_id, dry_run=True, |
|
166 | pull_request.source_ref_parts, self.workspace_id, dry_run=True, | |
167 | use_rebase=False) |
|
167 | use_rebase=False, close_branch=False) | |
168 |
|
168 | |||
169 | assert pull_request._last_merge_source_rev == self.source_commit |
|
169 | assert pull_request._last_merge_source_rev == self.source_commit | |
170 | assert pull_request._last_merge_target_rev == self.target_commit |
|
170 | assert pull_request._last_merge_target_rev == self.target_commit | |
@@ -193,7 +193,7 b' class TestPullRequestModel(object):' | |||||
193 | pull_request.target_ref_parts, |
|
193 | pull_request.target_ref_parts, | |
194 | pull_request.source_repo.scm_instance(), |
|
194 | pull_request.source_repo.scm_instance(), | |
195 | pull_request.source_ref_parts, self.workspace_id, dry_run=True, |
|
195 | pull_request.source_ref_parts, self.workspace_id, dry_run=True, | |
196 | use_rebase=False) |
|
196 | use_rebase=False, close_branch=False) | |
197 |
|
197 | |||
198 | assert pull_request._last_merge_source_rev == self.source_commit |
|
198 | assert pull_request._last_merge_source_rev == self.source_commit | |
199 | assert pull_request._last_merge_target_rev == self.target_commit |
|
199 | assert pull_request._last_merge_target_rev == self.target_commit | |
@@ -225,7 +225,7 b' class TestPullRequestModel(object):' | |||||
225 | pull_request.target_ref_parts, |
|
225 | pull_request.target_ref_parts, | |
226 | pull_request.source_repo.scm_instance(), |
|
226 | pull_request.source_repo.scm_instance(), | |
227 | pull_request.source_ref_parts, self.workspace_id, dry_run=True, |
|
227 | pull_request.source_ref_parts, self.workspace_id, dry_run=True, | |
228 | use_rebase=False) |
|
228 | use_rebase=False, close_branch=False) | |
229 |
|
229 | |||
230 | assert pull_request._last_merge_source_rev is None |
|
230 | assert pull_request._last_merge_source_rev is None | |
231 | assert pull_request._last_merge_target_rev is None |
|
231 | assert pull_request._last_merge_target_rev is None | |
@@ -299,7 +299,7 b' class TestPullRequestModel(object):' | |||||
299 | pull_request.source_repo.scm_instance(), |
|
299 | pull_request.source_repo.scm_instance(), | |
300 | pull_request.source_ref_parts, self.workspace_id, |
|
300 | pull_request.source_ref_parts, self.workspace_id, | |
301 | user_name=user.username, user_email=user.email, message=message, |
|
301 | user_name=user.username, user_email=user.email, message=message, | |
302 | use_rebase=False |
|
302 | use_rebase=False, close_branch=False | |
303 | ) |
|
303 | ) | |
304 | self.invalidation_mock.assert_called_once_with( |
|
304 | self.invalidation_mock.assert_called_once_with( | |
305 | pull_request.target_repo.repo_name) |
|
305 | pull_request.target_repo.repo_name) | |
@@ -338,7 +338,7 b' class TestPullRequestModel(object):' | |||||
338 | pull_request.source_repo.scm_instance(), |
|
338 | pull_request.source_repo.scm_instance(), | |
339 | pull_request.source_ref_parts, self.workspace_id, |
|
339 | pull_request.source_ref_parts, self.workspace_id, | |
340 | user_name=user.username, user_email=user.email, message=message, |
|
340 | user_name=user.username, user_email=user.email, message=message, | |
341 | use_rebase=False |
|
341 | use_rebase=False, close_branch=False | |
342 | ) |
|
342 | ) | |
343 |
|
343 | |||
344 | pull_request = PullRequest.get(pull_request.pull_request_id) |
|
344 | pull_request = PullRequest.get(pull_request.pull_request_id) |
General Comments 0
You need to be logged in to leave comments.
Login now