Show More
@@ -747,6 +747,69 b' class TestPullrequestsView(object):' | |||||
747 | assert 'Pull request updated to' in response.body |
|
747 | assert 'Pull request updated to' in response.body | |
748 | assert 'with 1 added, 1 removed commits.' in response.body |
|
748 | assert 'with 1 added, 1 removed commits.' in response.body | |
749 |
|
749 | |||
|
750 | def test_update_target_revision_with_removal_of_1_commit_git(self, backend_git, csrf_token): | |||
|
751 | backend = backend_git | |||
|
752 | commits = [ | |||
|
753 | {'message': 'master-commit-1'}, | |||
|
754 | {'message': 'master-commit-2-change-1'}, | |||
|
755 | {'message': 'master-commit-3-change-2'}, | |||
|
756 | ||||
|
757 | {'message': 'feat-commit-1', 'parents': ['master-commit-1']}, | |||
|
758 | {'message': 'feat-commit-2'}, | |||
|
759 | ] | |||
|
760 | commit_ids = backend.create_master_repo(commits) | |||
|
761 | target = backend.create_repo(heads=['master-commit-3-change-2']) | |||
|
762 | source = backend.create_repo(heads=['feat-commit-2']) | |||
|
763 | ||||
|
764 | # create pr from a in source to A in target | |||
|
765 | pull_request = PullRequest() | |||
|
766 | pull_request.source_repo = source | |||
|
767 | # TODO: johbo: Make sure that we write the source ref this way! | |||
|
768 | pull_request.source_ref = 'branch:{branch}:{commit_id}'.format( | |||
|
769 | branch=backend.default_branch_name, | |||
|
770 | commit_id=commit_ids['master-commit-3-change-2']) | |||
|
771 | ||||
|
772 | pull_request.target_repo = target | |||
|
773 | # TODO: johbo: Target ref should be branch based, since tip can jump | |||
|
774 | # from branch to branch | |||
|
775 | pull_request.target_ref = 'branch:{branch}:{commit_id}'.format( | |||
|
776 | branch=backend.default_branch_name, | |||
|
777 | commit_id=commit_ids['feat-commit-2']) | |||
|
778 | ||||
|
779 | pull_request.revisions = [ | |||
|
780 | commit_ids['feat-commit-1'], | |||
|
781 | commit_ids['feat-commit-2'] | |||
|
782 | ] | |||
|
783 | pull_request.title = u"Test" | |||
|
784 | pull_request.description = u"Description" | |||
|
785 | pull_request.author = UserModel().get_by_username( | |||
|
786 | TEST_USER_ADMIN_LOGIN) | |||
|
787 | Session().add(pull_request) | |||
|
788 | Session().commit() | |||
|
789 | pull_request_id = pull_request.pull_request_id | |||
|
790 | ||||
|
791 | # PR is created, now we simulate a force-push into target, | |||
|
792 | # that drops a 2 last commits | |||
|
793 | vcsrepo = target.scm_instance() | |||
|
794 | vcsrepo.config.clear_section('hooks') | |||
|
795 | vcsrepo.run_git_command(['reset', '--soft', 'HEAD~2']) | |||
|
796 | ||||
|
797 | # update PR | |||
|
798 | self.app.post( | |||
|
799 | route_path('pullrequest_update', | |||
|
800 | repo_name=target.repo_name, | |||
|
801 | pull_request_id=pull_request_id), | |||
|
802 | params={'update_commits': 'true', | |||
|
803 | 'csrf_token': csrf_token}, | |||
|
804 | status=200) | |||
|
805 | ||||
|
806 | response = self.app.get(route_path( | |||
|
807 | 'pullrequest_new', | |||
|
808 | repo_name=target.repo_name)) | |||
|
809 | assert response.status_int == 200 | |||
|
810 | response.mustcontain('Pull request updated to') | |||
|
811 | response.mustcontain('with 0 added, 0 removed commits.') | |||
|
812 | ||||
750 | def test_update_of_ancestor_reference(self, backend, csrf_token): |
|
813 | def test_update_of_ancestor_reference(self, backend, csrf_token): | |
751 | commits = [ |
|
814 | commits = [ | |
752 | {'message': 'ancestor'}, |
|
815 | {'message': 'ancestor'}, |
@@ -757,7 +757,7 b' class GitRepository(BaseRepository):' | |||||
757 | cmd = ['fetch', self.path, source_branch] |
|
757 | cmd = ['fetch', self.path, source_branch] | |
758 | self.run_git_command(cmd, fail_on_stderr=False) |
|
758 | self.run_git_command(cmd, fail_on_stderr=False) | |
759 |
|
759 | |||
760 | def _local_fetch(self, repository_path, branch_name): |
|
760 | def _local_fetch(self, repository_path, branch_name, use_origin=False): | |
761 | """ |
|
761 | """ | |
762 | Fetch a branch from a local repository. |
|
762 | Fetch a branch from a local repository. | |
763 | """ |
|
763 | """ | |
@@ -765,7 +765,17 b' class GitRepository(BaseRepository):' | |||||
765 | if repository_path == self.path: |
|
765 | if repository_path == self.path: | |
766 | raise ValueError('Cannot fetch from the same repository') |
|
766 | raise ValueError('Cannot fetch from the same repository') | |
767 |
|
767 | |||
768 | cmd = ['fetch', '--no-tags', repository_path, branch_name] |
|
768 | if use_origin: | |
|
769 | branch_name = '+{branch}:refs/heads/{branch}'.format( | |||
|
770 | branch=branch_name) | |||
|
771 | ||||
|
772 | cmd = ['fetch', '--no-tags', '--update-head-ok', | |||
|
773 | repository_path, branch_name] | |||
|
774 | self.run_git_command(cmd, fail_on_stderr=False) | |||
|
775 | ||||
|
776 | def _local_reset(self, branch_name): | |||
|
777 | branch_name = '{}'.format(branch_name) | |||
|
778 | cmd = ['reset', '--hard', branch_name] | |||
769 | self.run_git_command(cmd, fail_on_stderr=False) |
|
779 | self.run_git_command(cmd, fail_on_stderr=False) | |
770 |
|
780 | |||
771 | def _last_fetch_heads(self): |
|
781 | def _last_fetch_heads(self): | |
@@ -840,7 +850,7 b' class GitRepository(BaseRepository):' | |||||
840 | 'merge', '--no-ff', '-m', safe_str(merge_message)] |
|
850 | 'merge', '--no-ff', '-m', safe_str(merge_message)] | |
841 | cmd.extend(heads) |
|
851 | cmd.extend(heads) | |
842 | try: |
|
852 | try: | |
843 | self.run_git_command(cmd, fail_on_stderr=False) |
|
853 | output = self.run_git_command(cmd, fail_on_stderr=False) | |
844 | except RepositoryError: |
|
854 | except RepositoryError: | |
845 | # Cleanup any merge leftovers |
|
855 | # Cleanup any merge leftovers | |
846 | self.run_git_command(['merge', '--abort'], fail_on_stderr=False) |
|
856 | self.run_git_command(['merge', '--abort'], fail_on_stderr=False) | |
@@ -897,6 +907,8 b' class GitRepository(BaseRepository):' | |||||
897 | merger_name, merger_email, dry_run=False, |
|
907 | merger_name, merger_email, dry_run=False, | |
898 | use_rebase=False, close_branch=False): |
|
908 | use_rebase=False, close_branch=False): | |
899 | if target_ref.commit_id != self.branches[target_ref.name]: |
|
909 | if target_ref.commit_id != self.branches[target_ref.name]: | |
|
910 | log.warning('Target ref %s commit mismatch %s vs %s', target_ref, | |||
|
911 | target_ref.commit_id, self.branches[target_ref.name]) | |||
900 | return MergeResponse( |
|
912 | return MergeResponse( | |
901 | False, False, None, MergeFailureReason.TARGET_IS_NOT_HEAD) |
|
913 | False, False, None, MergeFailureReason.TARGET_IS_NOT_HEAD) | |
902 |
|
914 | |||
@@ -907,20 +919,29 b' class GitRepository(BaseRepository):' | |||||
907 | if shadow_repo.get_remote_ref(source_ref.name): |
|
919 | if shadow_repo.get_remote_ref(source_ref.name): | |
908 | shadow_repo._checkout(source_ref.name, force=True) |
|
920 | shadow_repo._checkout(source_ref.name, force=True) | |
909 |
|
921 | |||
910 | # checkout target |
|
922 | # checkout target, and fetch changes | |
911 | shadow_repo._checkout(target_ref.name, force=True) |
|
923 | shadow_repo._checkout(target_ref.name, force=True) | |
912 | shadow_repo._local_pull(self.path, target_ref.name) |
|
924 | ||
|
925 | # fetch/reset pull the target, in case it is changed | |||
|
926 | # this handles even force changes | |||
|
927 | shadow_repo._local_fetch(self.path, target_ref.name, use_origin=True) | |||
|
928 | shadow_repo._local_reset(target_ref.name) | |||
913 |
|
929 | |||
914 | # Need to reload repo to invalidate the cache, or otherwise we cannot |
|
930 | # Need to reload repo to invalidate the cache, or otherwise we cannot | |
915 | # retrieve the last target commit. |
|
931 | # retrieve the last target commit. | |
916 | shadow_repo = GitRepository(shadow_repository_path) |
|
932 | shadow_repo = GitRepository(shadow_repository_path) | |
917 | if target_ref.commit_id != shadow_repo.branches[target_ref.name]: |
|
933 | if target_ref.commit_id != shadow_repo.branches[target_ref.name]: | |
|
934 | log.warning('Shadow Target ref %s commit mismatch %s vs %s', | |||
|
935 | target_ref, target_ref.commit_id, | |||
|
936 | shadow_repo.branches[target_ref.name]) | |||
918 | return MergeResponse( |
|
937 | return MergeResponse( | |
919 | False, False, None, MergeFailureReason.TARGET_IS_NOT_HEAD) |
|
938 | False, False, None, MergeFailureReason.TARGET_IS_NOT_HEAD) | |
920 |
|
939 | |||
|
940 | # calculate new branch | |||
921 | pr_branch = shadow_repo._get_new_pr_branch( |
|
941 | pr_branch = shadow_repo._get_new_pr_branch( | |
922 | source_ref.name, target_ref.name) |
|
942 | source_ref.name, target_ref.name) | |
923 | log.debug('using pull-request merge branch: `%s`', pr_branch) |
|
943 | log.debug('using pull-request merge branch: `%s`', pr_branch) | |
|
944 | # checkout to temp branch, and fetch changes | |||
924 | shadow_repo._checkout(pr_branch, create=True) |
|
945 | shadow_repo._checkout(pr_branch, create=True) | |
925 | try: |
|
946 | try: | |
926 | shadow_repo._local_fetch(source_repo.path, source_ref.name) |
|
947 | shadow_repo._local_fetch(source_repo.path, source_ref.name) |
@@ -417,6 +417,7 b'' | |||||
417 | <strong>${_('Missing commits')}:</strong> |
|
417 | <strong>${_('Missing commits')}:</strong> | |
418 | ${_('This pull request cannot be displayed, because one or more commits no longer exist in the source repository.')} |
|
418 | ${_('This pull request cannot be displayed, because one or more commits no longer exist in the source repository.')} | |
419 | ${_('Please update this pull request, push the commits back into the source repository, or consider closing this pull request.')} |
|
419 | ${_('Please update this pull request, push the commits back into the source repository, or consider closing this pull request.')} | |
|
420 | ${_('Consider doing a {force_refresh_url} in case you think this is an error.').format(force_refresh_url=h.link_to('force refresh', h.current_route_path(request, force_refresh='1')))|n} | |||
420 | </div> |
|
421 | </div> | |
421 | </div> |
|
422 | </div> | |
422 | </div> |
|
423 | </div> |
General Comments 0
You need to be logged in to leave comments.
Login now