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

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

// Copyright 2011 The MOE Authors All Rights Reserved.

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

import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.devtools.moe.client.AppContext;
import com.google.devtools.moe.client.CommandRunner.CommandException;
import com.google.devtools.moe.client.FileSystem.Lifetime;
import com.google.devtools.moe.client.Lifetimes;
import com.google.devtools.moe.client.MoeProblem;
import com.google.devtools.moe.client.codebase.LocalClone;
import com.google.devtools.moe.client.project.RepositoryConfig;

import java.io.File;
import java.io.IOException;

/**
* Git implementation of {@link LocalClone}, i.e. a 'git clone' to local disk.
*/
public class GitClonedRepository implements LocalClone {

  private final String repositoryName;
  private final RepositoryConfig repositoryConfig;
  /**
   * The location to clone from. If snapshotting a locally modified Writer, this will _not_ be
   * the same as repositoryConfig.getUrl(). Otherwise, it will.
   */
  private final String repositoryUrl;
  private File localCloneTempDir;
  private boolean clonedLocally;
  /** The revision of this clone, a Git hash ID */
  private String revId;
 
  GitClonedRepository(String repositoryName, RepositoryConfig repositoryConfig) {
    this(repositoryName, repositoryConfig, repositoryConfig.getUrl());
  }

  GitClonedRepository(
      String repositoryName, RepositoryConfig repositoryConfig, String repositoryUrl) {
    this.repositoryName = repositoryName;
    this.repositoryConfig = repositoryConfig;
    this.repositoryUrl = repositoryUrl;
    this.clonedLocally = false;
  }

  @Override
  public String getRepositoryName() {
    return repositoryName;
  }

  @Override
  public RepositoryConfig getConfig() {
    return repositoryConfig;
  }

  @Override
  public File getLocalTempDir() {
    Preconditions.checkState(clonedLocally);
    Preconditions.checkNotNull(localCloneTempDir);
    return localCloneTempDir;
  }

  @Override
  public void cloneLocallyAtHead(Lifetime cloneLifetime) {
    Preconditions.checkState(!clonedLocally);

    String tempDirName = String.format("git_clone_%s_", repositoryName);
    localCloneTempDir = AppContext.RUN.fileSystem.getTemporaryDirectory(tempDirName, cloneLifetime);

    try {
      GitRepository.runGitCommand(
          ImmutableList.<String>of(
              "clone",
              repositoryUrl,
              localCloneTempDir.getAbsolutePath()),
          "" /*workingDirectory*/);
      clonedLocally = true;
      this.revId = "HEAD";
    } catch (CommandException e) {
      throw new MoeProblem(
          "Could not clone from git repo at " + repositoryUrl + ": " + e.stderr);
    }
  }

  @Override
  public void updateToRevision(String revId) {
    Preconditions.checkState(clonedLocally);
    Preconditions.checkState("HEAD".equals(this.revId));
    try {
      String headCommitId =
          runGitCommand("show-ref", "--heads", "--hash", GitWriter.DEFAULT_BRANCH_NAME).trim();
      // If we are updating to a revision other than the branch's head, branch from that revision.
      // Otherwise, no update/checkout is necessary since we are already at the desired revId,
      // branch head.
      if (!headCommitId.equals(revId)) {
        runGitCommand("checkout", revId, "-b", "moe_writing_branch_from_" + revId);
      }
      this.revId = revId;
    } catch (CommandException e) {
      throw new MoeProblem(
          "Could not update git repo at " + localCloneTempDir + ": " + e.stderr);
    }
  }

  @Override
  public File archiveAtRevision(String revId) {
    Preconditions.checkState(clonedLocally);
    if (Strings.isNullOrEmpty(revId)) {
      revId = "HEAD";
    }
    File archiveLocation = AppContext.RUN.fileSystem.getTemporaryDirectory(
        String.format("git_archive_%s_%s_", repositoryName, revId),
        Lifetimes.currentTask());
    // Using this just to get a filename.
    String tarballPath = AppContext.RUN.fileSystem.getTemporaryDirectory(
        String.format("git_tarball_%s_%s.tar.", repositoryName, revId),
        Lifetimes.currentTask()).getAbsolutePath();
    try {

      // Git doesn't support archiving to a directory: it only supports
      // archiving to a tar.  The fastest way to do this would be to pipe the
      // output directly into tar, however, there's no option for that using
      // the classes we have. (michaelpb)
      runGitCommand(
          "archive",
          "--format=tar",
          "--output=" + tarballPath,
          revId);

      // Make the directory to untar into
      AppContext.RUN.fileSystem.makeDirs(archiveLocation);

      // Untar the tarball we just made
      AppContext.RUN.cmd.runCommand(
          "tar",
          ImmutableList.<String>of(
              "xf",
              tarballPath,
              "-C",
              archiveLocation.getAbsolutePath()),
          "");
   
    } catch (CommandException e) {
      throw new MoeProblem(
          "Could not archive git clone at " +
            localCloneTempDir.getAbsolutePath() + ": " + e.stderr);
    } catch (IOException e) {
      throw new MoeProblem(
          "IOException archiving clone at " +
              localCloneTempDir.getAbsolutePath() +
              " to revision " + revId + ": " + e);
    }
    return archiveLocation;
  }

  /**
   * Runs a git command with the given arguments, in this cloned repository's directory.
   *
   * @param args a list of arguments for git
   * @return a string containing the STDOUT result
   */
  String runGitCommand(String... args) throws CommandException {
    return AppContext.RUN.cmd.runCommand("git", ImmutableList.copyOf(args),
        getLocalTempDir().getAbsolutePath() /*workingDirectory*/);
  }
}
TOP

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

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.