Beispiel #1
0
 private boolean isAdd(List<DiffEntry> files) {
   String oldPath = ((FollowFilter) pathFilter).getPath();
   for (DiffEntry ent : files) {
     if (ent.getChangeType() == ADD && ent.getNewPath().equals(oldPath)) return true;
   }
   return false;
 }
Beispiel #2
0
  private void formatOldNewPaths(ByteArrayOutputStream o, DiffEntry ent) throws IOException {
    if (ent.oldId.equals(ent.newId)) return;

    final String oldp;
    final String newp;

    switch (ent.getChangeType()) {
      case ADD:
        oldp = DiffEntry.DEV_NULL;
        newp = quotePath(newPrefix + ent.getNewPath());
        break;

      case DELETE:
        oldp = quotePath(oldPrefix + ent.getOldPath());
        newp = DiffEntry.DEV_NULL;
        break;

      default:
        oldp = quotePath(oldPrefix + ent.getOldPath());
        newp = quotePath(newPrefix + ent.getNewPath());
        break;
    }

    o.write(encode("--- " + oldp + "\n")); // $NON-NLS-1$ //$NON-NLS-2$
    o.write(encode("+++ " + newp + "\n")); // $NON-NLS-1$ //$NON-NLS-2$
  }
Beispiel #3
0
 private List<DiffEntry> updateFollowFilter(List<DiffEntry> files) {
   String oldPath = ((FollowFilter) pathFilter).getPath();
   for (DiffEntry ent : files) {
     if (isRename(ent) && ent.getNewPath().equals(oldPath)) {
       pathFilter = FollowFilter.create(ent.getOldPath());
       return Collections.singletonList(ent);
     }
   }
   return Collections.emptyList();
 }
Beispiel #4
0
  private FormatResult createFormatResult(DiffEntry ent)
      throws IOException, CorruptObjectException, MissingObjectException {
    final FormatResult res = new FormatResult();
    ByteArrayOutputStream buf = new ByteArrayOutputStream();
    final EditList editList;
    final FileHeader.PatchType type;

    formatHeader(buf, ent);

    if (ent.getOldMode() == GITLINK || ent.getNewMode() == GITLINK) {
      formatOldNewPaths(buf, ent);
      writeGitLinkDiffText(buf, ent);
      editList = new EditList();
      type = PatchType.UNIFIED;

    } else {
      assertHaveRepository();

      byte[] aRaw = open(OLD, ent);
      byte[] bRaw = open(NEW, ent);

      if (aRaw == BINARY
          || bRaw == BINARY //
          || RawText.isBinary(aRaw)
          || RawText.isBinary(bRaw)) {
        formatOldNewPaths(buf, ent);
        buf.write(encodeASCII("Binary files differ\n")); // $NON-NLS-1$
        editList = new EditList();
        type = PatchType.BINARY;

      } else {
        res.a = new RawText(aRaw);
        res.b = new RawText(bRaw);
        editList = diff(res.a, res.b);
        type = PatchType.UNIFIED;

        switch (ent.getChangeType()) {
          case RENAME:
          case COPY:
            if (!editList.isEmpty()) formatOldNewPaths(buf, ent);
            break;

          default:
            formatOldNewPaths(buf, ent);
            break;
        }
      }
    }

    res.header = new FileHeader(buf.toByteArray(), editList, type);
    return res;
  }
Beispiel #5
0
 /**
  * @param o the stream the formatter will write line data to
  * @param ent the DiffEntry to create the FileHeader for
  * @throws IOException writing to the supplied stream failed.
  */
 protected void formatIndexLine(OutputStream o, DiffEntry ent) throws IOException {
   o.write(
       encodeASCII(
           "index " // //$NON-NLS-1$
               + format(ent.getOldId()) //
               + ".." // //$NON-NLS-1$
               + format(ent.getNewId())));
   if (ent.getOldMode().equals(ent.getNewMode())) {
     o.write(' ');
     ent.getNewMode().copyTo(o);
   }
   o.write('\n');
 }
Beispiel #6
0
 public String toString() {
   try {
     updateDiffInfo();
     Iterator iter = getDifferences().iterator();
     StringBuffer sb = new StringBuffer();
     while (iter.hasNext()) {
       DiffEntry de = (DiffEntry) iter.next();
       sb.append(de.toString());
     }
     return sb.toString();
   } catch (IntrospectionException e) {
     return e.getMessage();
   }
 }
Beispiel #7
0
 private void writeGitLinkDiffText(OutputStream o, DiffEntry ent) throws IOException {
   if (ent.getOldMode() == GITLINK) {
     o.write(
         encodeASCII(
             "-Subproject commit "
                 + ent.getOldId().name() // $NON-NLS-1$
                 + "\n")); //$NON-NLS-1$
   }
   if (ent.getNewMode() == GITLINK) {
     o.write(
         encodeASCII(
             "+Subproject commit "
                 + ent.getNewId().name() // $NON-NLS-1$
                 + "\n")); //$NON-NLS-1$
   }
 }
Beispiel #8
0
  private byte[] open(DiffEntry.Side side, DiffEntry entry) throws IOException {
    if (entry.getMode(side) == FileMode.MISSING) return EMPTY;

    if (entry.getMode(side).getObjectType() != Constants.OBJ_BLOB) return EMPTY;

    if (isBinary()) return BINARY;

    AbbreviatedObjectId id = entry.getId(side);
    if (!id.isComplete()) {
      Collection<ObjectId> ids = reader.resolve(id);
      if (ids.size() == 1) {
        id = AbbreviatedObjectId.fromObjectId(ids.iterator().next());
        switch (side) {
          case OLD:
            entry.oldId = id;
            break;
          case NEW:
            entry.newId = id;
            break;
        }
      } else if (ids.size() == 0) throw new MissingObjectException(id, Constants.OBJ_BLOB);
      else throw new AmbiguousObjectException(id, ids);
    }

    try {
      ObjectLoader ldr = source.open(side, entry);
      return ldr.getBytes(binaryFileThreshold);

    } catch (LargeObjectException.ExceedsLimit overLimit) {
      return BINARY;

    } catch (LargeObjectException.ExceedsByteArrayLimit overLimit) {
      return BINARY;

    } catch (LargeObjectException.OutOfMemory tooBig) {
      return BINARY;

    } catch (LargeObjectException tooBig) {
      tooBig.setObjectId(id.toObjectId());
      throw tooBig;
    }
  }
Beispiel #9
0
  /**
   * Determine the differences between two trees.
   *
   * <p>No output is created, instead only the file paths that are different are returned. Callers
   * may choose to format these paths themselves, or convert them into {@link FileHeader} instances
   * with a complete edit list by calling {@link #toFileHeader(DiffEntry)}.
   *
   * @param a the old (or previous) side.
   * @param b the new (or updated) side.
   * @return the paths that are different.
   * @throws IOException trees cannot be read or file contents cannot be read.
   */
  public List<DiffEntry> scan(AbstractTreeIterator a, AbstractTreeIterator b) throws IOException {
    assertHaveRepository();

    TreeWalk walk = new TreeWalk(reader);
    walk.addTree(a);
    walk.addTree(b);
    walk.setRecursive(true);

    TreeFilter filter = getDiffTreeFilterFor(a, b);
    if (pathFilter instanceof FollowFilter) {
      walk.setFilter(
          AndTreeFilter.create(PathFilter.create(((FollowFilter) pathFilter).getPath()), filter));
    } else {
      walk.setFilter(AndTreeFilter.create(pathFilter, filter));
    }

    source = new ContentSource.Pair(source(a), source(b));

    List<DiffEntry> files = DiffEntry.scan(walk);
    if (pathFilter instanceof FollowFilter && isAdd(files)) {
      // The file we are following was added here, find where it
      // came from so we can properly show the rename or copy,
      // then continue digging backwards.
      //
      a.reset();
      b.reset();
      walk.reset();
      walk.addTree(a);
      walk.addTree(b);
      walk.setFilter(filter);

      if (renameDetector == null) setDetectRenames(true);
      files = updateFollowFilter(detectRenames(DiffEntry.scan(walk)));

    } else if (renameDetector != null) files = detectRenames(files);

    return files;
  }
Beispiel #10
0
  private void formatHeader(ByteArrayOutputStream o, DiffEntry ent) throws IOException {
    final ChangeType type = ent.getChangeType();
    final String oldp = ent.getOldPath();
    final String newp = ent.getNewPath();
    final FileMode oldMode = ent.getOldMode();
    final FileMode newMode = ent.getNewMode();

    formatGitDiffFirstHeaderLine(o, type, oldp, newp);

    switch (type) {
      case ADD:
        o.write(encodeASCII("new file mode ")); // $NON-NLS-1$
        newMode.copyTo(o);
        o.write('\n');
        break;

      case DELETE:
        o.write(encodeASCII("deleted file mode ")); // $NON-NLS-1$
        oldMode.copyTo(o);
        o.write('\n');
        break;

      case RENAME:
        o.write(
            encodeASCII("similarity index " + ent.getScore() + "%")); // $NON-NLS-1$ //$NON-NLS-2$
        o.write('\n');

        o.write(encode("rename from " + quotePath(oldp))); // $NON-NLS-1$
        o.write('\n');

        o.write(encode("rename to " + quotePath(newp))); // $NON-NLS-1$
        o.write('\n');
        break;

      case COPY:
        o.write(
            encodeASCII("similarity index " + ent.getScore() + "%")); // $NON-NLS-1$ //$NON-NLS-2$
        o.write('\n');

        o.write(encode("copy from " + quotePath(oldp))); // $NON-NLS-1$
        o.write('\n');

        o.write(encode("copy to " + quotePath(newp))); // $NON-NLS-1$
        o.write('\n');

        if (!oldMode.equals(newMode)) {
          o.write(encodeASCII("new file mode ")); // $NON-NLS-1$
          newMode.copyTo(o);
          o.write('\n');
        }
        break;

      case MODIFY:
        if (0 < ent.getScore()) {
          o.write(
              encodeASCII(
                  "dissimilarity index " //$NON-NLS-1$
                      + (100 - ent.getScore())
                      + "%")); //$NON-NLS-1$
          o.write('\n');
        }
        break;
    }

    if ((type == MODIFY || type == RENAME) && !oldMode.equals(newMode)) {
      o.write(encodeASCII("old mode ")); // $NON-NLS-1$
      oldMode.copyTo(o);
      o.write('\n');

      o.write(encodeASCII("new mode ")); // $NON-NLS-1$
      newMode.copyTo(o);
      o.write('\n');
    }

    if (!ent.getOldId().equals(ent.getNewId())) {
      formatIndexLine(o, ent);
    }
  }
Beispiel #11
0
 private static boolean isRename(DiffEntry ent) {
   return ent.getChangeType() == RENAME || ent.getChangeType() == COPY;
 }