/**
   * Creates an in-memory index of the ticket change.
   *
   * @param changeId
   * @param change
   * @return an in-memory index
   * @throws IOException
   */
  private DirCache createIndex(Repository db, long ticketId, Change change)
      throws IOException, ClassNotFoundException, NoSuchFieldException {

    String ticketPath = toTicketPath(ticketId);
    DirCache newIndex = DirCache.newInCore();
    DirCacheBuilder builder = newIndex.builder();

    Set<String> ignorePaths = new TreeSet<String>();
    try (ObjectInserter inserter = db.newObjectInserter()) {
      // create/update the journal
      // exclude the attachment content
      List<Change> changes = getJournal(db, ticketId);
      changes.add(change);
      String journal = TicketSerializer.serializeJournal(changes).trim();

      byte[] journalBytes = journal.getBytes(Constants.ENCODING);
      String journalPath = ticketPath + "/" + JOURNAL;
      final DirCacheEntry journalEntry = new DirCacheEntry(journalPath);
      journalEntry.setLength(journalBytes.length);
      journalEntry.setLastModified(change.date.getTime());
      journalEntry.setFileMode(FileMode.REGULAR_FILE);
      journalEntry.setObjectId(
          inserter.insert(org.eclipse.jgit.lib.Constants.OBJ_BLOB, journalBytes));

      // add journal to index
      builder.add(journalEntry);
      ignorePaths.add(journalEntry.getPathString());

      // Add any attachments to the index
      if (change.hasAttachments()) {
        for (Attachment attachment : change.attachments) {
          // build a path name for the attachment and mark as ignored
          String path = toAttachmentPath(ticketId, attachment.name);
          ignorePaths.add(path);

          // create an index entry for this attachment
          final DirCacheEntry entry = new DirCacheEntry(path);
          entry.setLength(attachment.content.length);
          entry.setLastModified(change.date.getTime());
          entry.setFileMode(FileMode.REGULAR_FILE);

          // insert object
          entry.setObjectId(
              inserter.insert(org.eclipse.jgit.lib.Constants.OBJ_BLOB, attachment.content));

          // add to temporary in-core index
          builder.add(entry);
        }
      }

      for (DirCacheEntry entry : getTreeEntries(db, ignorePaths)) {
        builder.add(entry);
      }

      // finish the index
      builder.finish();
    }
    return newIndex;
  }
Beispiel #2
0
 protected DirCache readTree(RevTree tree)
     throws IOException, MissingObjectException, IncorrectObjectTypeException {
   DirCache dc = DirCache.newInCore();
   if (tree != null) {
     DirCacheBuilder b = dc.builder();
     b.addTree(new byte[0], DirCacheEntry.STAGE_0, reader, tree);
     b.finish();
   }
   return dc;
 }
Beispiel #3
0
 private static DirCache readTree(final Repository pdb, final Ref branch)
     throws MissingObjectException, IncorrectObjectTypeException, IOException {
   try (RevWalk rw = new RevWalk(pdb)) {
     final DirCache dc = DirCache.newInCore();
     final DirCacheBuilder b = dc.builder();
     b.addTree(
         new byte[0], // no prefix path
         DirCacheEntry.STAGE_0, // standard stage
         pdb.newObjectReader(),
         rw.parseTree(branch.getObjectId()));
     b.finish();
     return dc;
   }
 }
Beispiel #4
0
 /**
  * Construct a tree from a specific listing of file entries.
  *
  * @param entries the files to include in the tree. The collection does not need to be sorted
  *     properly and may be empty.
  * @return reference to the tree specified by the entry list.
  * @throws Exception
  */
 public RevTree tree(final DirCacheEntry... entries) throws Exception {
   final DirCache dc = DirCache.newInCore();
   final DirCacheBuilder b = dc.builder();
   for (final DirCacheEntry e : entries) b.add(e);
   b.finish();
   ObjectId root;
   try {
     root = dc.writeTree(inserter);
     inserter.flush();
   } finally {
     inserter.release();
   }
   return pool.lookupTree(root);
 }
  /**
   * Writes a file to the tickets branch.
   *
   * @param db
   * @param file
   * @param content
   * @param createdBy
   * @param msg
   */
  private void writeTicketsFile(
      Repository db, String file, String content, String createdBy, String msg) {
    if (getTicketsBranch(db) == null) {
      createTicketsBranch(db);
    }

    DirCache newIndex = DirCache.newInCore();
    DirCacheBuilder builder = newIndex.builder();

    try (ObjectInserter inserter = db.newObjectInserter()) {
      // create an index entry for the revised index
      final DirCacheEntry idIndexEntry = new DirCacheEntry(file);
      idIndexEntry.setLength(content.length());
      idIndexEntry.setLastModified(System.currentTimeMillis());
      idIndexEntry.setFileMode(FileMode.REGULAR_FILE);

      // insert new ticket index
      idIndexEntry.setObjectId(
          inserter.insert(
              org.eclipse.jgit.lib.Constants.OBJ_BLOB, content.getBytes(Constants.ENCODING)));

      // add to temporary in-core index
      builder.add(idIndexEntry);

      Set<String> ignorePaths = new HashSet<String>();
      ignorePaths.add(file);

      for (DirCacheEntry entry : getTreeEntries(db, ignorePaths)) {
        builder.add(entry);
      }

      // finish temporary in-core index used for this commit
      builder.finish();

      // commit the change
      commitIndex(db, newIndex, createdBy, msg);

    } catch (ConcurrentRefUpdateException e) {
      log.error("", e);
    } catch (IOException e) {
      log.error("", e);
    }
  }
Beispiel #6
0
  /**
   * @param local
   * @param inCore
   */
  protected ResolveMerger(Repository local, boolean inCore) {
    super(local);
    SupportedAlgorithm diffAlg =
        local
            .getConfig()
            .getEnum(
                ConfigConstants.CONFIG_DIFF_SECTION,
                null,
                ConfigConstants.CONFIG_KEY_ALGORITHM,
                SupportedAlgorithm.HISTOGRAM);
    mergeAlgorithm = new MergeAlgorithm(DiffAlgorithm.getAlgorithm(diffAlg));
    commitNames =
        new String[] {"BASE", "OURS", "THEIRS"}; // $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
    this.inCore = inCore;

    if (inCore) {
      implicitDirCache = false;
      dircache = DirCache.newInCore();
    } else {
      implicitDirCache = true;
    }
  }
Beispiel #7
0
  private DirCache createTemporaryIndex(ObjectId headId, DirCache index, RevWalk rw)
      throws IOException {
    ObjectInserter inserter = null;

    // get DirCacheBuilder for existing index
    DirCacheBuilder existingBuilder = index.builder();

    // get DirCacheBuilder for newly created in-core index to build a
    // temporary index for this commit
    DirCache inCoreIndex = DirCache.newInCore();
    DirCacheBuilder tempBuilder = inCoreIndex.builder();

    onlyProcessed = new boolean[only.size()];
    boolean emptyCommit = true;

    try (TreeWalk treeWalk = new TreeWalk(repo)) {
      treeWalk.setOperationType(OperationType.CHECKIN_OP);
      int dcIdx = treeWalk.addTree(new DirCacheBuildIterator(existingBuilder));
      FileTreeIterator fti = new FileTreeIterator(repo);
      fti.setDirCacheIterator(treeWalk, 0);
      int fIdx = treeWalk.addTree(fti);
      int hIdx = -1;
      if (headId != null) hIdx = treeWalk.addTree(rw.parseTree(headId));
      treeWalk.setRecursive(true);

      String lastAddedFile = null;
      while (treeWalk.next()) {
        String path = treeWalk.getPathString();
        // check if current entry's path matches a specified path
        int pos = lookupOnly(path);

        CanonicalTreeParser hTree = null;
        if (hIdx != -1) hTree = treeWalk.getTree(hIdx, CanonicalTreeParser.class);

        DirCacheIterator dcTree = treeWalk.getTree(dcIdx, DirCacheIterator.class);

        if (pos >= 0) {
          // include entry in commit

          FileTreeIterator fTree = treeWalk.getTree(fIdx, FileTreeIterator.class);

          // check if entry refers to a tracked file
          boolean tracked = dcTree != null || hTree != null;
          if (!tracked) continue;

          // for an unmerged path, DirCacheBuildIterator will yield 3
          // entries, we only want to add one
          if (path.equals(lastAddedFile)) continue;

          lastAddedFile = path;

          if (fTree != null) {
            // create a new DirCacheEntry with data retrieved from
            // disk
            final DirCacheEntry dcEntry = new DirCacheEntry(path);
            long entryLength = fTree.getEntryLength();
            dcEntry.setLength(entryLength);
            dcEntry.setLastModified(fTree.getEntryLastModified());
            dcEntry.setFileMode(fTree.getIndexFileMode(dcTree));

            boolean objectExists =
                (dcTree != null && fTree.idEqual(dcTree))
                    || (hTree != null && fTree.idEqual(hTree));
            if (objectExists) {
              dcEntry.setObjectId(fTree.getEntryObjectId());
            } else {
              if (FileMode.GITLINK.equals(dcEntry.getFileMode()))
                dcEntry.setObjectId(fTree.getEntryObjectId());
              else {
                // insert object
                if (inserter == null) inserter = repo.newObjectInserter();
                long contentLength = fTree.getEntryContentLength();
                InputStream inputStream = fTree.openEntryStream();
                try {
                  dcEntry.setObjectId(
                      inserter.insert(Constants.OBJ_BLOB, contentLength, inputStream));
                } finally {
                  inputStream.close();
                }
              }
            }

            // add to existing index
            existingBuilder.add(dcEntry);
            // add to temporary in-core index
            tempBuilder.add(dcEntry);

            if (emptyCommit
                && (hTree == null
                    || !hTree.idEqual(fTree)
                    || hTree.getEntryRawMode() != fTree.getEntryRawMode()))
              // this is a change
              emptyCommit = false;
          } else {
            // if no file exists on disk, neither add it to
            // index nor to temporary in-core index

            if (emptyCommit && hTree != null)
              // this is a change
              emptyCommit = false;
          }

          // keep track of processed path
          onlyProcessed[pos] = true;
        } else {
          // add entries from HEAD for all other paths
          if (hTree != null) {
            // create a new DirCacheEntry with data retrieved from
            // HEAD
            final DirCacheEntry dcEntry = new DirCacheEntry(path);
            dcEntry.setObjectId(hTree.getEntryObjectId());
            dcEntry.setFileMode(hTree.getEntryFileMode());

            // add to temporary in-core index
            tempBuilder.add(dcEntry);
          }

          // preserve existing entry in index
          if (dcTree != null) existingBuilder.add(dcTree.getDirCacheEntry());
        }
      }
    }

    // there must be no unprocessed paths left at this point; otherwise an
    // untracked or unknown path has been specified
    for (int i = 0; i < onlyProcessed.length; i++)
      if (!onlyProcessed[i])
        throw new JGitInternalException(
            MessageFormat.format(JGitText.get().entryNotFoundByPath, only.get(i)));

    // there must be at least one change
    if (emptyCommit) throw new JGitInternalException(JGitText.get().emptyCommit);

    // update index
    existingBuilder.commit();
    // finish temporary in-core index used for this commit
    tempBuilder.finish();
    return inCoreIndex;
  }
 @Test
 public void testFindOnEmpty() throws Exception {
   final DirCache dc = DirCache.newInCore();
   final byte[] path = Constants.encode("a");
   assertEquals(-1, dc.findEntry(path, path.length));
 }
  /**
   * Deletes a ticket from the repository.
   *
   * @param ticket
   * @return true if successful
   */
  @Override
  protected synchronized boolean deleteTicketImpl(
      RepositoryModel repository, TicketModel ticket, String deletedBy) {
    if (ticket == null) {
      throw new RuntimeException("must specify a ticket!");
    }

    boolean success = false;
    Repository db = repositoryManager.getRepository(ticket.repository);
    try {
      RefModel ticketsBranch = getTicketsBranch(db);

      if (ticketsBranch == null) {
        throw new RuntimeException(BRANCH + " does not exist!");
      }
      String ticketPath = toTicketPath(ticket.number);

      try {
        ObjectId treeId = db.resolve(BRANCH + "^{tree}");

        // Create the in-memory index of the new/updated ticket
        DirCache index = DirCache.newInCore();
        DirCacheBuilder builder = index.builder();

        // Traverse HEAD to add all other paths
        try (TreeWalk treeWalk = new TreeWalk(db)) {
          int hIdx = -1;
          if (treeId != null) {
            hIdx = treeWalk.addTree(treeId);
          }
          treeWalk.setRecursive(true);
          while (treeWalk.next()) {
            String path = treeWalk.getPathString();
            CanonicalTreeParser hTree = null;
            if (hIdx != -1) {
              hTree = treeWalk.getTree(hIdx, CanonicalTreeParser.class);
            }
            if (!path.startsWith(ticketPath)) {
              // add entries from HEAD for all other paths
              if (hTree != null) {
                final DirCacheEntry entry = new DirCacheEntry(path);
                entry.setObjectId(hTree.getEntryObjectId());
                entry.setFileMode(hTree.getEntryFileMode());

                // add to temporary in-core index
                builder.add(entry);
              }
            }
          }
        }

        // finish temporary in-core index used for this commit
        builder.finish();

        success = commitIndex(db, index, deletedBy, "- " + ticket.number);

      } catch (Throwable t) {
        log.error(
            MessageFormat.format(
                "Failed to delete ticket {0,number,0} from {1}", ticket.number, db.getDirectory()),
            t);
      }
    } finally {
      db.close();
    }
    return success;
  }
Beispiel #10
0
  /** Helper to generate a commit. */
  public class CommitBuilder {
    private final BranchBuilder branch;

    private final DirCache tree = DirCache.newInCore();

    private final List<RevCommit> parents = new ArrayList<RevCommit>(2);

    private int tick = 1;

    private String message = "";

    private RevCommit self;

    CommitBuilder() {
      branch = null;
    }

    CommitBuilder(BranchBuilder b) throws Exception {
      branch = b;

      Ref ref = db.getRef(branch.ref);
      if (ref != null) {
        parent(pool.parseCommit(ref.getObjectId()));
      }
    }

    CommitBuilder(CommitBuilder prior) throws Exception {
      branch = prior.branch;

      DirCacheBuilder b = tree.builder();
      for (int i = 0; i < prior.tree.getEntryCount(); i++) b.add(prior.tree.getEntry(i));
      b.finish();

      parents.add(prior.create());
    }

    public CommitBuilder parent(RevCommit p) throws Exception {
      if (parents.isEmpty()) {
        DirCacheBuilder b = tree.builder();
        parseBody(p);
        b.addTree(new byte[0], DirCacheEntry.STAGE_0, pool.getObjectReader(), p.getTree());
        b.finish();
      }
      parents.add(p);
      return this;
    }

    public CommitBuilder noParents() {
      parents.clear();
      return this;
    }

    public CommitBuilder noFiles() {
      tree.clear();
      return this;
    }

    public CommitBuilder add(String path, String content) throws Exception {
      return add(path, blob(content));
    }

    public CommitBuilder add(String path, final RevBlob id) throws Exception {
      return edit(
          new PathEdit(path) {
            @Override
            public void apply(DirCacheEntry ent) {
              ent.setFileMode(FileMode.REGULAR_FILE);
              ent.setObjectId(id);
            }
          });
    }

    public CommitBuilder edit(PathEdit edit) {
      DirCacheEditor e = tree.editor();
      e.add(edit);
      e.finish();
      return this;
    }

    public CommitBuilder rm(String path) {
      DirCacheEditor e = tree.editor();
      e.add(new DeletePath(path));
      e.add(new DeleteTree(path));
      e.finish();
      return this;
    }

    public CommitBuilder message(String m) {
      message = m;
      return this;
    }

    public CommitBuilder tick(int secs) {
      tick = secs;
      return this;
    }

    public RevCommit create() throws Exception {
      if (self == null) {
        TestRepository.this.tick(tick);

        final org.eclipse.jgit.lib.CommitBuilder c;

        c = new org.eclipse.jgit.lib.CommitBuilder();
        c.setParentIds(parents);
        setAuthorAndCommitter(c);
        c.setMessage(message);

        ObjectId commitId;
        try {
          c.setTreeId(tree.writeTree(inserter));
          commitId = inserter.insert(c);
          inserter.flush();
        } finally {
          inserter.release();
        }
        self = pool.lookupCommit(commitId);

        if (branch != null) branch.update(self);
      }
      return self;
    }

    public CommitBuilder child() throws Exception {
      return new CommitBuilder(this);
    }
  }