From 66c6068a5e5f7a0fb419f41f26e88700f08bf43a Mon Sep 17 00:00:00 2001 From: "James E. Blair" Date: Wed, 31 May 2017 12:48:01 -0400 Subject: Update the merger recent dict when saving the repo state This will have the effect of only saving or restoring the repo state once in the merger. The "recent" dictionary is consulted by the merger before it merges each change to find upon which change the merge should be based. If it contains an entry for a project-branch, that entry is used. Otherwise, it resets the repo and finds the branch tip. By populating it when we save the repo state, we can ensure that a repo is reset only once during a merge, and since the repo_state dict is only updated when there is no recent entry for a project-branch, the repo state is only updated once per project as well. The same applies to restoring the repo state -- the restore is performed right before the save, so by fully populating recent after the restore, we will only restore a repo state once. Change-Id: I6fbdf4ec9be303bb6b90caa724ee2c813673a431 --- zuul/merger/merger.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'zuul/merger') diff --git a/zuul/merger/merger.py b/zuul/merger/merger.py index 79531d95b..2ca5d5977 100644 --- a/zuul/merger/merger.py +++ b/zuul/merger/merger.py @@ -350,17 +350,19 @@ class Merger(object): repo.checkoutLocalBranch(branch) def _saveRepoState(self, connection_name, project_name, repo, - repo_state): + repo_state, recent): projects = repo_state.setdefault(connection_name, {}) project = projects.setdefault(project_name, {}) - if project: - # We already have a state for this project. - return for ref in repo.getRefs(): - if ref.path.startswith('refs/zuul'): + if ref.path.startswith('refs/zuul/'): continue - if ref.path.startswith('refs/remotes'): + if ref.path.startswith('refs/remotes/'): continue + if ref.path.startswith('refs/heads/'): + branch = ref.path[len('refs/heads/'):] + key = (connection_name, project_name, branch) + if key not in recent: + recent[key] = ref.object project[ref.path] = ref.object.hexsha def _restoreRepoState(self, connection_name, project_name, repo, @@ -429,7 +431,7 @@ class Merger(object): # Save the repo state so that later mergers can repeat # this process. self._saveRepoState(item['connection'], item['project'], repo, - repo_state) + repo_state, recent) else: self.log.debug("Found base commit %s for %s" % (base, key,)) # Merge the change -- cgit v1.2.1