Package org.eclipse.jgit.lib

Source Code of org.eclipse.jgit.lib.Commit

/*
* Copyright (C) 2007, Dave Watson <dwatson@mimvista.com>
* Copyright (C) 2006-2007, Robin Rosenberg <robin.rosenberg@dewire.com>
* Copyright (C) 2006-2007, Shawn O. Pearce <spearce@spearce.org>
* and other copyright owners as documented in the project's IP log.
*
* This program and the accompanying materials are made available
* under the terms of the Eclipse Distribution License v1.0 which
* accompanies this distribution, is reproduced below, and is
* available at http://www.eclipse.org/org/documents/edl-v10.php
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above copyright
*   notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above
*   copyright notice, this list of conditions and the following
*   disclaimer in the documentation and/or other materials provided
*   with the distribution.
*
* - Neither the name of the Eclipse Foundation, Inc. nor the
*   names of its contributors may be used to endorse or promote
*   products derived from this software without specific prior
*   written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package org.eclipse.jgit.lib;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.text.MessageFormat;

import org.eclipse.jgit.JGitText;
import org.eclipse.jgit.errors.CorruptObjectException;
import org.eclipse.jgit.errors.MissingObjectException;

/**
* Instances of this class represent a Commit object. It represents a snapshot
* in a Git repository, who created it and when.
*/
public class Commit implements Treeish {
  private static final ObjectId[] EMPTY_OBJECTID_LIST = new ObjectId[0];

  private final Repository objdb;

  private ObjectId commitId;

  private ObjectId treeId;

  private ObjectId[] parentIds;

  private PersonIdent author;

  private PersonIdent committer;

  private String message;

  private Tree treeObj;

  private byte[] raw;

  private Charset encoding;

  /**
   * Create an empty commit object. More information must be fed to this
   * object to make it useful.
   *
   * @param db
   *            The repository with which to associate it.
   */
  public Commit(final Repository db) {
    objdb = db;
    parentIds = EMPTY_OBJECTID_LIST;
  }

  /**
   * Create a commit associated with these parents and associate it with a
   * repository.
   *
   * @param db
   *            The repository to which this commit object belongs
   * @param parentIds
   *            Id's of the parent(s)
   */
  public Commit(final Repository db, final ObjectId[] parentIds) {
    objdb = db;
    this.parentIds = parentIds;
  }

  /**
   * Create a commit object with the specified id and data from and existing
   * commit object in a repository.
   *
   * @param db
   *            The repository to which this commit object belongs
   * @param id
   *            Commit id
   * @param raw
   *            Raw commit object data
   */
  public Commit(final Repository db, final ObjectId id, final byte[] raw) {
    objdb = db;
    commitId = id;
    treeId = ObjectId.fromString(raw, 5);
    parentIds = new ObjectId[1];
    int np=0;
    int rawPtr = 46;
    for (;;) {
      if (raw[rawPtr] != 'p')
        break;
      if (np == 0) {
        parentIds[np++] = ObjectId.fromString(raw, rawPtr + 7);
      } else if (np == 1) {
        parentIds = new ObjectId[] { parentIds[0], ObjectId.fromString(raw, rawPtr + 7) };
        np++;
      } else {
        if (parentIds.length <= np) {
          ObjectId[] old = parentIds;
          parentIds = new ObjectId[parentIds.length+32];
          for (int i=0; i<np; ++i)
            parentIds[i] = old[i];
        }
        parentIds[np++] = ObjectId.fromString(raw, rawPtr + 7);
      }
      rawPtr += 48;
    }
    if (np != parentIds.length) {
      ObjectId[] old = parentIds;
      parentIds = new ObjectId[np];
      for (int i=0; i<np; ++i)
        parentIds[i] = old[i];
    } else
      if (np == 0)
        parentIds = EMPTY_OBJECTID_LIST;
    this.raw = raw;
  }

  /**
   * @return get repository for the commit
   */
  public Repository getRepository() {
    return objdb;
  }

  /**
   * @return The commit object id
   */
  public ObjectId getCommitId() {
    return commitId;
  }

  /**
   * Set the id of this object.
   *
   * @param id
   *            the id that we calculated for this object.
   */
  public void setCommitId(final ObjectId id) {
    commitId = id;
  }

  public ObjectId getTreeId() {
    return treeId;
  }

  /**
   * Set the tree id for this commit object
   *
   * @param id
   */
  public void setTreeId(final ObjectId id) {
    if (treeId==null || !treeId.equals(id)) {
      treeObj = null;
    }
    treeId = id;
  }

  public Tree getTree() throws IOException {
    if (treeObj == null) {
      treeObj = objdb.mapTree(getTreeId());
      if (treeObj == null) {
        throw new MissingObjectException(getTreeId(),
            Constants.TYPE_TREE);
      }
    }
    return treeObj;
  }

  /**
   * Set the tree object for this commit
   * @see #setTreeId
   * @param t the Tree object
   */
  public void setTree(final Tree t) {
    treeId = t.getTreeId();
    treeObj = t;
  }

  /**
   * @return the author and authoring time for this commit
   */
  public PersonIdent getAuthor() {
    decode();
    return author;
  }

  /**
   * Set the author and authoring time for this commit
   * @param a
   */
  public void setAuthor(final PersonIdent a) {
    author = a;
  }

  /**
   * @return the committer and commit time for this object
   */
  public PersonIdent getCommitter() {
    decode();
    return committer;
  }

  /**
   * Set the committer and commit time for this object
   * @param c the committer information
   */
  public void setCommitter(final PersonIdent c) {
    committer = c;
  }

  /**
   * @return the object ids of this commit
   */
  public ObjectId[] getParentIds() {
    return parentIds;
  }

  /**
   * @return the commit message
   */
  public String getMessage() {
    decode();
    return message;
  }

  /**
   * Set the parents of this commit
   * @param parentIds
   */
  public void setParentIds(ObjectId[] parentIds) {
    this.parentIds = new ObjectId[parentIds.length];
    for (int i=0; i<parentIds.length; ++i)
      this.parentIds[i] = parentIds[i];
  }

  private void decode() {
    // FIXME: handle I/O errors
    if (raw != null) {
      try {
        DataInputStream br = new DataInputStream(new ByteArrayInputStream(raw));
        String n = br.readLine();
        if (n == null || !n.startsWith("tree ")) {
          throw new CorruptObjectException(commitId, JGitText.get().corruptObjectNotree);
        }
        while ((n = br.readLine()) != null && n.startsWith("parent ")) {
          // empty body
        }
        if (n == null || !n.startsWith("author ")) {
          throw new CorruptObjectException(commitId, JGitText.get().corruptObjectNoAuthor);
        }
        String rawAuthor = n.substring("author ".length());
        n = br.readLine();
        if (n == null || !n.startsWith("committer ")) {
          throw new CorruptObjectException(commitId, JGitText.get().corruptObjectNoCommitter);
        }
        String rawCommitter = n.substring("committer ".length());
        n = br.readLine();
        if (n != null && n.startsWith"encoding"))
          encoding = Charset.forName(n.substring("encoding ".length()));
        else
          if (n == null || !n.equals("")) {
            throw new CorruptObjectException(commitId, MessageFormat.format(
                JGitText.get().corruptObjectMalformedHeader, n));
        }
        byte[] readBuf = new byte[br.available()]; // in-memory stream so this is all bytes left
        br.read(readBuf);
        int msgstart = readBuf.length != 0 ? ( readBuf[0] == '\n' ? 1 : 0 ) : 0;

        // If encoding is not specified, the default for commit is UTF-8
        if (encoding == null) encoding = Constants.CHARSET;

        // TODO: this isn't reliable so we need to guess the encoding from the actual content
        author = new PersonIdent(new String(rawAuthor.getBytes(),encoding.name()));
        committer = new PersonIdent(new String(rawCommitter.getBytes(),encoding.name()));
        message = new String(readBuf,msgstart, readBuf.length-msgstart, encoding.name());
      } catch (IOException e) {
        e.printStackTrace();
      } finally {
        raw = null;
      }
    }
  }

  /**
   * Set the commit message
   *
   * @param m the commit message
   */
  public void setMessage(final String m) {
    message = m;
  }

  /**
   * Persist this commit object
   *
   * @throws IOException
   */
  public void commit() throws IOException {
    if (getCommitId() != null)
      throw new IllegalStateException(MessageFormat.format(JGitText.get().commitAlreadyExists, getCommitId()));
    ObjectInserter odi = objdb.newObjectInserter();
    try {
      ObjectId id = odi.insert(Constants.OBJ_COMMIT, odi.format(this));
      odi.flush();
      setCommitId(id);
    } finally {
      odi.release();
    }
  }

  public String toString() {
    return "Commit[" + ObjectId.toString(getCommitId()) + " " + getAuthor() + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
  }

  /**
   * State the encoding for the commit information
   *
   * @param e
   *            the encoding. See {@link Charset}
   */
  public void setEncoding(String e) {
    encoding = Charset.forName(e);
  }

  /**
   * State the encoding for the commit information
   *
   * @param e
   *            the encoding. See {@link Charset}
   */
  public void setEncoding(Charset e) {
    encoding = e;
  }

  /**
   * @return the encoding used. See {@link Charset}
   */
  public String getEncoding() {
    if (encoding != null)
      return encoding.name();
    else
      return null;
  }
}
TOP

Related Classes of org.eclipse.jgit.lib.Commit

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.