# HG changeset patch # User Marcin Kuzminski # Date 2018-01-15 18:13:31 # Node ID 0d428e35b2d95f0d0c924505ea4264fb2668d927 # Parent 4400cfcf1c119c67aa48dacc0001f046541828ea git: merge test, fetch other branch if it's different from target. This prevents potentially missing commits when doing a test merge. diff --git a/rhodecode/lib/vcs/backends/base.py b/rhodecode/lib/vcs/backends/base.py --- a/rhodecode/lib/vcs/backends/base.py +++ b/rhodecode/lib/vcs/backends/base.py @@ -461,7 +461,7 @@ class BaseRepository(object): raise ValueError('message cannot be empty') shadow_repository_path = self._maybe_prepare_merge_workspace( - workspace_id, target_ref) + workspace_id, target_ref, source_ref) try: return self._merge_repo( @@ -482,7 +482,7 @@ class BaseRepository(object): """Internal implementation of merge.""" raise NotImplementedError - def _maybe_prepare_merge_workspace(self, workspace_id, target_ref): + def _maybe_prepare_merge_workspace(self, workspace_id, target_ref, source_ref): """ Create the merge workspace. diff --git a/rhodecode/lib/vcs/backends/git/repository.py b/rhodecode/lib/vcs/backends/git/repository.py --- a/rhodecode/lib/vcs/backends/git/repository.py +++ b/rhodecode/lib/vcs/backends/git/repository.py @@ -402,6 +402,12 @@ class GitRepository(BaseRepository): node = tree return tree + def get_remote_ref(self, ref_name): + try: + return self._ref_tree['refs']['remotes']['origin'][ref_name] + except Exception: + return + def get_commit(self, commit_id=None, commit_idx=None, pre_load=None): """ Returns `GitCommit` object representing commit from git repository @@ -722,16 +728,26 @@ class GitRepository(BaseRepository): stdout, _ = self.run_git_command(['rev-parse', 'HEAD']) return stdout.strip() - def _local_clone(self, clone_path, branch_name): + def _local_clone(self, clone_path, branch_name, source_branch=None): """ Create a local clone of the current repo. """ # N.B.(skreft): the --branch option is required as otherwise the shallow # clone will only fetch the active branch. - cmd = ['clone', '--branch', branch_name, '--single-branch', + cmd = ['clone', '--branch', branch_name, self.path, os.path.abspath(clone_path)] + self.run_git_command(cmd, fail_on_stderr=False) + # if we get the different source branch, make sure we also fetch it for + # merge conditions + if source_branch and source_branch != branch_name: + # check if the ref exists. + shadow_repo = GitRepository(os.path.abspath(clone_path)) + if shadow_repo.get_remote_ref(source_branch): + cmd = ['fetch', self.path, source_branch] + self.run_git_command(cmd, fail_on_stderr=False) + def _local_fetch(self, repository_path, branch_name): """ Fetch a branch from a local repository. @@ -873,8 +889,16 @@ class GitRepository(BaseRepository): False, False, None, MergeFailureReason.TARGET_IS_NOT_HEAD) shadow_repo = GitRepository(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: + if shadow_repo.get_remote_ref(source_ref.name): + shadow_repo._checkout(source_ref.name) + + # checkout target shadow_repo._checkout(target_ref.name) shadow_repo._local_pull(self.path, target_ref.name) + # Need to reload repo to invalidate the cache, or otherwise we cannot # retrieve the last target commit. shadow_repo = GitRepository(shadow_repository_path) @@ -939,10 +963,11 @@ class GitRepository(BaseRepository): 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): + 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) + self._local_clone( + shadow_repository_path, target_ref.name, source_ref.name) return shadow_repository_path diff --git a/rhodecode/lib/vcs/backends/hg/repository.py b/rhodecode/lib/vcs/backends/hg/repository.py --- a/rhodecode/lib/vcs/backends/hg/repository.py +++ b/rhodecode/lib/vcs/backends/hg/repository.py @@ -693,7 +693,7 @@ class MercurialRepository(BaseRepository 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): + def _maybe_prepare_merge_workspace(self, workspace_id, unused_target_ref, unused_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)