Program: 113279
Project: 113279
Buggy source:
/** 
 * Executes the diff-tree command with the specified options.
 */
@Override protected void runInternal(GeogigCLI cli) throws IOException {
  if (refSpec.size() > 2) {
    throw new InvalidParameterException("String_Node_Str" + refSpec);
  }
  if (treeStats && describe) {
    throw new InvalidParameterException("String_Node_Str");
  }
  GeoGIG geogig=cli.getGeogig();
  org.locationtech.geogig.api.plumbing.DiffTree diff=geogig.command(org.locationtech.geogig.api.plumbing.DiffTree.class);
  String oldVersion=resolveOldVersion();
  String newVersion=resolveNewVersion();
  diff.setOldVersion(oldVersion).setNewVersion(newVersion);
  Iterator<DiffEntry> diffEntries;
  if (paths.isEmpty()) {
    diffEntries=diff.setProgressListener(cli.getProgressListener()).call();
  }
 else {
    diffEntries=Collections.emptyIterator();
    for (    String path : paths) {
      Iterator<DiffEntry> moreEntries=diff.setPathFilter(path).setProgressListener(cli.getProgressListener()).call();
      diffEntries=Iterators.concat(diffEntries,moreEntries);
    }
  }
  DiffEntry diffEntry;
  HashMap<String,Long[]> stats=Maps.newHashMap();
  while (diffEntries.hasNext()) {
    diffEntry=diffEntries.next();
    StringBuilder sb=new StringBuilder();
    String path=diffEntry.newPath() != null ? diffEntry.newPath() : diffEntry.oldPath();
    if (describe) {
      sb.append(diffEntry.changeType().toString().charAt(0)).append(' ').append(path).append(LINE_BREAK);
      if (diffEntry.changeType() == ChangeType.MODIFIED) {
        FeatureDiff featureDiff=geogig.command(DiffFeature.class).setNewVersion(Suppliers.ofInstance(diffEntry.getNewObject())).setOldVersion(Suppliers.ofInstance(diffEntry.getOldObject())).call();
        Map<PropertyDescriptor,AttributeDiff> diffs=featureDiff.getDiffs();
        HashSet<PropertyDescriptor> diffDescriptors=Sets.newHashSet(diffs.keySet());
        NodeRef noderef=diffEntry.changeType() != ChangeType.REMOVED ? diffEntry.getNewObject() : diffEntry.getOldObject();
        RevFeatureType featureType=geogig.command(RevObjectParse.class).setObjectId(noderef.getMetadataId()).call(RevFeatureType.class).get();
        Optional<RevObject> obj=geogig.command(RevObjectParse.class).setObjectId(noderef.getObjectId()).call();
        RevFeature feature=(RevFeature)obj.get();
        ImmutableList<Optional<Object>> values=feature.getValues();
        ImmutableList<PropertyDescriptor> descriptors=featureType.sortedDescriptors();
        int idx=0;
        for (        PropertyDescriptor descriptor : descriptors) {
          if (diffs.containsKey(descriptor)) {
            AttributeDiff ad=diffs.get(descriptor);
            sb.append(ad.getType().toString().charAt(0) + "String_Node_Str" + descriptor.getName().toString()+ LINE_BREAK);
            if (!ad.getType().equals(TYPE.ADDED)) {
              Object value=ad.getOldValue().orNull();
              sb.append(TextValueSerializer.asString(Optional.fromNullable(value)));
              sb.append(LINE_BREAK);
            }
            if (!ad.getType().equals(TYPE.REMOVED)) {
              Object value=ad.getNewValue().orNull();
              sb.append(TextValueSerializer.asString(Optional.fromNullable(value)));
              sb.append(LINE_BREAK);
            }
            diffDescriptors.remove(descriptor);
          }
 else {
            sb.append("String_Node_Str").append(descriptor.getName().toString()).append(LINE_BREAK);
            sb.append(TextValueSerializer.asString(values.get(idx))).append(LINE_BREAK);
          }
          idx++;
        }
        for (        PropertyDescriptor descriptor : diffDescriptors) {
          AttributeDiff ad=diffs.get(descriptor);
          sb.append(ad.getType().toString().charAt(0) + "String_Node_Str" + descriptor.getName().toString()+ LINE_BREAK);
          if (!ad.getType().equals(TYPE.ADDED)) {
            Object value=ad.getOldValue().orNull();
            sb.append(TextValueSerializer.asString(Optional.fromNullable(value)));
            sb.append(LINE_BREAK);
          }
          if (!ad.getType().equals(TYPE.REMOVED)) {
            Object value=ad.getNewValue().orNull();
            sb.append(TextValueSerializer.asString(Optional.fromNullable(value)));
            sb.append(LINE_BREAK);
          }
        }
      }
 else {
        NodeRef noderef=diffEntry.changeType() == ChangeType.ADDED ? diffEntry.getNewObject() : diffEntry.getOldObject();
        RevFeatureType featureType=geogig.command(RevObjectParse.class).setObjectId(noderef.getMetadataId()).call(RevFeatureType.class).get();
        Optional<RevObject> obj=geogig.command(RevObjectParse.class).setObjectId(noderef.getObjectId()).call();
        RevFeature feature=(RevFeature)obj.get();
        ImmutableList<Optional<Object>> values=feature.getValues();
        int i=0;
        for (        Optional<Object> value : values) {
          sb.append(diffEntry.changeType().toString().charAt(0));
          sb.append(' ');
          sb.append(featureType.sortedDescriptors().get(i).getName().toString());
          sb.append(LINE_BREAK);
          sb.append(TextValueSerializer.asString(value));
          sb.append(LINE_BREAK);
          i++;
        }
        sb.append(LINE_BREAK);
      }
      sb.append(LINE_BREAK);
      cli.getConsole().println(sb.toString());
    }
 else     if (treeStats) {
      String parent=NodeRef.parentPath(path);
      if (!stats.containsKey(parent)) {
        stats.put(parent,new Long[]{0l,0l,0l});
      }
      Long[] counts=stats.get(parent);
      if (diffEntry.changeType() == ChangeType.ADDED) {
        counts[0]++;
      }
 else       if (diffEntry.changeType() == ChangeType.REMOVED) {
        counts[1]++;
      }
 else       if (diffEntry.changeType() == ChangeType.MODIFIED) {
        counts[2]++;
      }
    }
 else {
      sb.append(path).append(' ');
      sb.append(diffEntry.oldObjectId().toString());
      sb.append(' ');
      sb.append(diffEntry.newObjectId().toString());
      cli.getConsole().println(sb.toString());
    }
  }
  if (treeStats) {
    for (    String path : stats.keySet()) {
      StringBuffer sb=new StringBuffer();
      sb.append(path);
      Long[] counts=stats.get(path);
      for (int i=0; i < counts.length; i++) {
        sb.append("String_Node_Str" + counts[i].toString());
      }
      cli.getConsole().println(sb.toString());
    }
  }
}

Fixed version (ground truth):
/** 
 * Executes the diff-tree command with the specified options.
 */
@Override protected void runInternal(GeogigCLI cli) throws IOException {
  if (refSpec.size() > 2) {
    throw new InvalidParameterException("String_Node_Str" + refSpec);
  }
  if (treeStats && describe) {
    throw new InvalidParameterException("String_Node_Str");
  }
  GeoGIG geogig=cli.getGeogig();
  org.locationtech.geogig.api.plumbing.DiffTree diff=geogig.command(org.locationtech.geogig.api.plumbing.DiffTree.class);
  String oldVersion=resolveOldVersion();
  String newVersion=resolveNewVersion();
  diff.setOldVersion(oldVersion).setNewVersion(newVersion);
  Iterator<DiffEntry> diffEntries;
  if (paths.isEmpty()) {
    diffEntries=diff.setProgressListener(cli.getProgressListener()).call();
  }
 else {
    diffEntries=Collections.emptyIterator();
    for (    String path : paths) {
      Iterator<DiffEntry> moreEntries=diff.setPathFilter(path).setProgressListener(cli.getProgressListener()).call();
      diffEntries=Iterators.concat(diffEntries,moreEntries);
    }
  }
  DiffEntry diffEntry;
  HashMap<String,Long[]> stats=Maps.newHashMap();
  while (diffEntries.hasNext()) {
    diffEntry=diffEntries.next();
    StringBuilder sb=new StringBuilder();
    String path=diffEntry.newPath() != null ? diffEntry.newPath() : diffEntry.oldPath();
    if (describe) {
      sb.append(diffEntry.changeType().toString().charAt(0)).append(' ').append(path).append(LINE_BREAK);
      if (diffEntry.changeType() == ChangeType.MODIFIED) {
        FeatureDiff featureDiff=geogig.command(DiffFeature.class).setNewVersion(Suppliers.ofInstance(diffEntry.getNewObject())).setOldVersion(Suppliers.ofInstance(diffEntry.getOldObject())).call();
        Map<PropertyDescriptor,AttributeDiff> diffs=featureDiff.getDiffs();
        HashSet<PropertyDescriptor> diffDescriptors=Sets.newHashSet(diffs.keySet());
        NodeRef noderef=diffEntry.changeType() != ChangeType.REMOVED ? diffEntry.getNewObject() : diffEntry.getOldObject();
        RevFeatureType featureType=geogig.command(RevObjectParse.class).setObjectId(noderef.getMetadataId()).call(RevFeatureType.class).get();
        Optional<RevObject> obj=geogig.command(RevObjectParse.class).setObjectId(noderef.getObjectId()).call();
        RevFeature feature=(RevFeature)obj.get();
        ImmutableList<Optional<Object>> values=feature.getValues();
        ImmutableList<PropertyDescriptor> descriptors=featureType.sortedDescriptors();
        int idx=0;
        for (        PropertyDescriptor descriptor : descriptors) {
          if (diffs.containsKey(descriptor)) {
            AttributeDiff ad=diffs.get(descriptor);
            sb.append(ad.getType().toString().charAt(0) + "String_Node_Str" + descriptor.getName().toString()+ LINE_BREAK);
            if (!ad.getType().equals(TYPE.ADDED)) {
              Object value=ad.getOldValue();
              sb.append(TextValueSerializer.asString(value));
              sb.append(LINE_BREAK);
            }
            if (!ad.getType().equals(TYPE.REMOVED)) {
              Object value=ad.getNewValue();
              sb.append(TextValueSerializer.asString(value));
              sb.append(LINE_BREAK);
            }
            diffDescriptors.remove(descriptor);
          }
 else {
            sb.append("String_Node_Str").append(descriptor.getName().toString()).append(LINE_BREAK);
            sb.append(TextValueSerializer.asString(values.get(idx))).append(LINE_BREAK);
          }
          idx++;
        }
        for (        PropertyDescriptor descriptor : diffDescriptors) {
          AttributeDiff ad=diffs.get(descriptor);
          sb.append(ad.getType().toString().charAt(0) + "String_Node_Str" + descriptor.getName().toString()+ LINE_BREAK);
          if (!ad.getType().equals(TYPE.ADDED)) {
            Object value=ad.getOldValue();
            sb.append(TextValueSerializer.asString(value));
            sb.append(LINE_BREAK);
          }
          if (!ad.getType().equals(TYPE.REMOVED)) {
            Object value=ad.getNewValue();
            sb.append(TextValueSerializer.asString(value));
            sb.append(LINE_BREAK);
          }
        }
      }
 else {
        NodeRef noderef=diffEntry.changeType() == ChangeType.ADDED ? diffEntry.getNewObject() : diffEntry.getOldObject();
        RevFeatureType featureType=geogig.command(RevObjectParse.class).setObjectId(noderef.getMetadataId()).call(RevFeatureType.class).get();
        Optional<RevObject> obj=geogig.command(RevObjectParse.class).setObjectId(noderef.getObjectId()).call();
        RevFeature feature=(RevFeature)obj.get();
        ImmutableList<Optional<Object>> values=feature.getValues();
        int i=0;
        for (        Optional<Object> value : values) {
          sb.append(diffEntry.changeType().toString().charAt(0));
          sb.append(' ');
          sb.append(featureType.sortedDescriptors().get(i).getName().toString());
          sb.append(LINE_BREAK);
          sb.append(TextValueSerializer.asString(value));
          sb.append(LINE_BREAK);
          i++;
        }
        sb.append(LINE_BREAK);
      }
      sb.append(LINE_BREAK);
      cli.getConsole().println(sb.toString());
    }
 else     if (treeStats) {
      String parent=NodeRef.parentPath(path);
      if (!stats.containsKey(parent)) {
        stats.put(parent,new Long[]{0l,0l,0l});
      }
      Long[] counts=stats.get(parent);
      if (diffEntry.changeType() == ChangeType.ADDED) {
        counts[0]++;
      }
 else       if (diffEntry.changeType() == ChangeType.REMOVED) {
        counts[1]++;
      }
 else       if (diffEntry.changeType() == ChangeType.MODIFIED) {
        counts[2]++;
      }
    }
 else {
      sb.append(path).append(' ');
      sb.append(diffEntry.oldObjectId().toString());
      sb.append(' ');
      sb.append(diffEntry.newObjectId().toString());
      cli.getConsole().println(sb.toString());
    }
  }
  if (treeStats) {
    for (    String path : stats.keySet()) {
      StringBuffer sb=new StringBuffer();
      sb.append(path);
      Long[] counts=stats.get(path);
      for (int i=0; i < counts.length; i++) {
        sb.append("String_Node_Str" + counts[i].toString());
      }
      cli.getConsole().println(sb.toString());
    }
  }
}