Package com.google.devtools.moe.client.dvcs.git

Source Code of com.google.devtools.moe.client.dvcs.git.GitRevisionHistory

// Copyright 2011 The MOE Authors All Rights Reserved.

package com.google.devtools.moe.client.dvcs.git;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
import com.google.devtools.moe.client.CommandRunner.CommandException;
import com.google.devtools.moe.client.MoeProblem;
import com.google.devtools.moe.client.repositories.AbstractRevisionHistory;
import com.google.devtools.moe.client.repositories.Revision;
import com.google.devtools.moe.client.repositories.RevisionMetadata;

import java.util.List;

/**
* A Git implementation of {@link AbstractRevisionHistory}.
*/
public class GitRevisionHistory extends AbstractRevisionHistory {

  @VisibleForTesting static final String LOG_DELIMITER = "---@MOE@---";

  /**
   * The default Git branch in which to look for revisions.
   */
  @VisibleForTesting static final String DEFAULT_BRANCH = "master";

  private final Supplier<GitClonedRepository> headCloneSupplier;

  GitRevisionHistory(Supplier<GitClonedRepository> headCloneSupplier) {
    this.headCloneSupplier = headCloneSupplier;
  }

  /**
   * Confirm the existence of the given hash ID via 'git log', or pull the most recent
   * hash ID if none is given.
   *
   * @param revId a revision ID (or the name of a branch)
   * @return a Revision corresponding to the given revId hash
   */
  @Override
  public Revision findHighestRevision(String revId) {
    if (revId == null || revId.isEmpty()) {
      revId = DEFAULT_BRANCH;
    }

    String hashID;
    GitClonedRepository headClone = headCloneSupplier.get();
    try {
      hashID = headClone.runGitCommand("log", "--max-count=1", "--format=%H", revId);
    } catch (CommandException e) {
      throw new MoeProblem(
          String.format(
              "Failed git log run: %d %s %s",
              e.returnStatus,
              e.stdout,
              e.stderr));
    }
    // Clean up output.
    hashID = hashID.replaceAll("\\W", "");

    return new Revision(hashID, headClone.getRepositoryName());
  }

  /**
   * Read the metadata for a given revision in the same repository.
   *
   * @param revision  the revision to parse metadata for
   */
  @Override
  public RevisionMetadata getMetadata(Revision revision) {
    GitClonedRepository headClone = headCloneSupplier.get();
    if (!headClone.getRepositoryName().equals(revision.repositoryName)) {
      throw new MoeProblem(
          String.format("Could not get metadata: Revision %s is in repository %s instead of %s",
                        revision.revId, revision.repositoryName, headClone.getRepositoryName()));
    }

    // Format: hash, author, date, parents, full commit message (subject and body)
    String format = Joiner.on(LOG_DELIMITER).join("%H", "%an", "%ad", "%P", "%B");

    String log;
    try {
      log = headClone.runGitCommand(
          "log",
          // Ensure one revision only, to be safe.
          "--max-count=1",
          "--format=" + format,
          revision.revId);
    } catch (CommandException e) {
      throw new MoeProblem(
          String.format("Failed git run: %d %s %s", e.returnStatus, e.stdout, e.stderr));
    }

    return parseMetadata(log);
  }

  /**
   * Parse the output of Git into RevisionMetadata.
   *
   * @param log  the output of getMetadata to parse
   */
  @VisibleForTesting RevisionMetadata parseMetadata(String log) {
    // Split on the log delimiter. Limit to 5 so that it will act correctly
    // even if the log delimiter happens to be in the commit message.
    List<String> split = ImmutableList.copyOf(Splitter.on(LOG_DELIMITER).limit(5).split(log));

    // The fourth item contains all of the parents, each separated by a space.
    ImmutableList.Builder<Revision> parentBuilder = ImmutableList.<Revision>builder();
    for (String parent : Splitter.on(" ").omitEmptyStrings().split(split.get(3))) {
      parentBuilder.add(new Revision(parent, headCloneSupplier.get().getRepositoryName()));
    }

    return new RevisionMetadata(
        split.get(0)// id
        split.get(1)// author
        split.get(2)// date
        split.get(4)// description
        parentBuilder.build())// parents
  }
 
  @Override
  protected List<Revision> findHeadRevisions() {
    List<String> importBranches = headCloneSupplier.get().getConfig().getImportBranches();
    if (importBranches == null) {
      importBranches = ImmutableList.of("master");
    }
   
    ImmutableList.Builder<Revision> result = ImmutableList.<Revision>builder();
    for (String branchName : importBranches) {
      result.add(findHighestRevision(branchName));
    }
    return result.build();
  }
}
TOP

Related Classes of com.google.devtools.moe.client.dvcs.git.GitRevisionHistory

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.