+ if (!idx) {
+ diff_index_show_file(revs, "-", tree, tree->sha1, tree->ce_mode);
+ return;
+ }
+
+ /* Show difference between old and new */
+ show_modified(revs, tree, idx, 1, cached, match_missing);
+}
+
+/*
+ * Count how many index entries go with the first one
+ */
+static inline int count_skip(const struct cache_entry *src, int pos)
+{
+ int skip = 1;
+
+ /* We can only have multiple entries if the first one is not stage-0 */
+ if (ce_stage(src)) {
+ struct cache_entry **p = active_cache + pos;
+ int namelen = ce_namelen(src);
+
+ for (;;) {
+ const struct cache_entry *ce;
+ pos++;
+ if (pos >= active_nr)
+ break;
+ ce = *++p;
+ if (ce_namelen(ce) != namelen)
+ break;
+ if (memcmp(ce->name, src->name, namelen))
+ break;
+ skip++;
+ }
+ }
+ return skip;
+}
+
+/*
+ * The unpack_trees() interface is designed for merging, so
+ * the different source entries are designed primarily for
+ * the source trees, with the old index being really mainly
+ * used for being replaced by the result.
+ *
+ * For diffing, the index is more important, and we only have a
+ * single tree.
+ *
+ * We're supposed to return how many index entries we want to skip.
+ *
+ * This wrapper makes it all more readable, and takes care of all
+ * the fairly complex unpack_trees() semantic requirements, including
+ * the skipping, the path matching, the type conflict cases etc.
+ */
+static int oneway_diff(struct cache_entry **src,
+ struct unpack_trees_options *o,
+ int index_pos)
+{
+ int skip = 0;
+ struct cache_entry *idx = src[0];
+ struct cache_entry *tree = src[1];
+ struct rev_info *revs = o->unpack_data;
+
+ if (index_pos >= 0)
+ skip = count_skip(idx, index_pos);
+
+ /*
+ * Unpack-trees generates a DF/conflict entry if
+ * there was a directory in the index and a tree
+ * in the tree. From a diff standpoint, that's a
+ * delete of the tree and a create of the file.
+ */
+ if (tree == o->df_conflict_entry)
+ tree = NULL;
+
+ if (ce_path_match(idx ? idx : tree, revs->prune_data))
+ do_oneway_diff(o, idx, tree, index_pos, skip);
+
+ return skip;
+}
+
+int run_diff_index(struct rev_info *revs, int cached)
+{
+ struct object *ent;
+ struct tree *tree;
+ const char *tree_name;
+ struct unpack_trees_options opts;
+ struct tree_desc t;