Exemplo n.º 1
0
  private void integrateIntoHistory(ChangeSet cs, IdentifiedUser caller)
      throws IntegrationException, NoSuchChangeException, ResourceConflictException {
    logDebug("Beginning merge attempt on {}", cs);
    Map<Branch.NameKey, BranchBatch> toSubmit = new HashMap<>();
    logDebug("Perform the merges");
    try {
      Multimap<Project.NameKey, Branch.NameKey> br = cs.branchesByProject();
      Multimap<Branch.NameKey, ChangeData> cbb = cs.changesByBranch();
      for (Branch.NameKey branch : cbb.keySet()) {
        OpenRepo or = openRepo(branch.getParentKey());
        toSubmit.put(branch, validateChangeList(or, cbb.get(branch)));
      }
      failFast(cs); // Done checks that don't involve running submit strategies.

      for (Branch.NameKey branch : cbb.keySet()) {
        OpenRepo or = openRepo(branch.getParentKey());
        OpenBranch ob = or.getBranch(branch);
        BranchBatch submitting = toSubmit.get(branch);
        SubmitStrategy strategy =
            createStrategy(or, branch, submitting.submitType(), ob.oldTip, caller);
        ob.mergeTip = preMerge(strategy, submitting.changes(), ob.oldTip);
      }
      checkMergeStrategyResults(cs, toSubmit.values());
      for (Project.NameKey project : br.keySet()) {
        openRepo(project).ins.flush();
      }

      Set<Branch.NameKey> done = Sets.newHashSetWithExpectedSize(cbb.keySet().size());
      logDebug("Write out the new branch tips");
      SubmoduleOp subOp = subOpProvider.get();
      for (Project.NameKey project : br.keySet()) {
        OpenRepo or = openRepo(project);
        for (Branch.NameKey branch : br.get(project)) {
          OpenBranch ob = or.getBranch(branch);
          boolean updated = updateBranch(or, branch, caller);

          BranchBatch submitting = toSubmit.get(branch);
          updateChangeStatus(ob, submitting.changes(), caller);
          updateSubmoduleSubscriptions(ob, subOp);
          if (updated) {
            fireRefUpdated(ob);
          }
          done.add(branch);
        }
      }

      updateSuperProjects(subOp, br.values());
      checkState(
          done.equals(cbb.keySet()),
          "programmer error: did not process"
              + " all branches in input set.\nExpected: %s\nActual: %s",
          done,
          cbb.keySet());
    } catch (NoSuchProjectException noProject) {
      logWarn("Project " + noProject.project() + " no longer exists, " + "abandoning open changes");
      abandonAllOpenChanges(noProject.project());
    } catch (OrmException e) {
      throw new IntegrationException("Cannot query the database", e);
    } catch (IOException e) {
      throw new IntegrationException("Cannot query the database", e);
    }
  }
Exemplo n.º 2
0
  private boolean updateBranch(OpenRepo or, Branch.NameKey destBranch, IdentifiedUser caller)
      throws IntegrationException {
    OpenBranch ob = or.getBranch(destBranch);
    CodeReviewCommit currentTip = ob.getCurrentTip();
    if (Objects.equals(ob.oldTip, currentTip)) {
      if (currentTip != null) {
        logDebug("Branch already at merge tip {}, no update to perform", currentTip.name());
      } else {
        logDebug("Both branch and merge tip are nonexistent, no update");
      }
      return false;
    } else if (currentTip == null) {
      logDebug("No merge tip, no update to perform");
      return false;
    }

    if (RefNames.REFS_CONFIG.equals(ob.update.getName())) {
      logDebug("Loading new configuration from {}", RefNames.REFS_CONFIG);
      try {
        ProjectConfig cfg = new ProjectConfig(or.getProjectName());
        cfg.load(or.repo, currentTip);
      } catch (Exception e) {
        throw new IntegrationException(
            "Submit would store invalid"
                + " project configuration "
                + currentTip.name()
                + " for "
                + or.getProjectName(),
            e);
      }
    }

    ob.update.setRefLogIdent(identifiedUserFactory.create(caller.getAccountId()).newRefLogIdent());
    ob.update.setForceUpdate(false);
    ob.update.setNewObjectId(currentTip);
    ob.update.setRefLogMessage("merged", true);
    try {
      RefUpdate.Result result = ob.update.update(or.rw);
      logDebug(
          "Update of {}: {}..{} returned status {}",
          ob.update.getName(),
          ob.update.getOldObjectId(),
          ob.update.getNewObjectId(),
          result);
      switch (result) {
        case NEW:
        case FAST_FORWARD:
          if (ob.update.getResult() == RefUpdate.Result.FAST_FORWARD) {
            tagCache.updateFastForward(
                destBranch.getParentKey(),
                ob.update.getName(),
                ob.update.getOldObjectId(),
                currentTip);
          }

          if (RefNames.REFS_CONFIG.equals(ob.update.getName())) {
            Project p = or.project.getProject();
            projectCache.evict(p);
            or.project = projectCache.get(p.getNameKey());
            repoManager.setProjectDescription(p.getNameKey(), p.getDescription());
          }

          return true;

        case LOCK_FAILURE:
          throw new IntegrationException("Failed to lock " + ob.update.getName());
        default:
          throw new IOException(ob.update.getResult().name() + '\n' + ob.update);
      }
    } catch (IOException e) {
      throw new IntegrationException("Cannot update " + ob.update.getName(), e);
    }
  }
Exemplo n.º 3
0
 @Override
 public void close() {
   for (OpenRepo repo : openRepos.values()) {
     repo.close();
   }
 }