#include "mailmap.h"
 #include "commit-slab.h"
 #include "dir.h"
+#include "cache-tree.h"
 
 volatile show_early_output_fn_t show_early_output;
 
        for_each_reflog(handle_one_reflog, &cb);
 }
 
+static void add_cache_tree(struct cache_tree *it, struct rev_info *revs,
+                          struct strbuf *path)
+{
+       size_t baselen = path->len;
+       int i;
+
+       if (it->entry_count >= 0) {
+               struct tree *tree = lookup_tree(it->sha1);
+               add_pending_object_with_path(revs, &tree->object, "",
+                                            040000, path->buf);
+       }
+
+       for (i = 0; i < it->subtree_nr; i++) {
+               struct cache_tree_sub *sub = it->down[i];
+               strbuf_addf(path, "%s%s", baselen ? "/" : "", sub->name);
+               add_cache_tree(sub->cache_tree, revs, path);
+               strbuf_setlen(path, baselen);
+       }
+
+}
+
+void add_index_objects_to_pending(struct rev_info *revs, unsigned flags)
+{
+       int i;
+
+       read_cache();
+       for (i = 0; i < active_nr; i++) {
+               struct cache_entry *ce = active_cache[i];
+               struct blob *blob;
+
+               if (S_ISGITLINK(ce->ce_mode))
+                       continue;
+
+               blob = lookup_blob(ce->sha1);
+               if (!blob)
+                       die("unable to add index blob to traversal");
+               add_pending_object_with_path(revs, &blob->object, "",
+                                            ce->ce_mode, ce->name);
+       }
+
+       if (active_cache_tree) {
+               struct strbuf path = STRBUF_INIT;
+               add_cache_tree(active_cache_tree, revs, &path);
+               strbuf_release(&path);
+       }
+}
+
 static int add_parents_only(struct rev_info *revs, const char *arg_, int flags)
 {
        unsigned char sha1[20];
            !strcmp(arg, "--reflog") || !strcmp(arg, "--not") ||
            !strcmp(arg, "--no-walk") || !strcmp(arg, "--do-walk") ||
            !strcmp(arg, "--bisect") || starts_with(arg, "--glob=") ||
+           !strcmp(arg, "--indexed-objects") ||
            starts_with(arg, "--exclude=") ||
            starts_with(arg, "--branches=") || starts_with(arg, "--tags=") ||
            starts_with(arg, "--remotes=") || starts_with(arg, "--no-walk="))
                clear_ref_exclusion(&revs->ref_excludes);
        } else if (!strcmp(arg, "--reflog")) {
                add_reflogs_to_pending(revs, *flags);
+       } else if (!strcmp(arg, "--indexed-objects")) {
+               add_index_objects_to_pending(revs, *flags);
        } else if (!strcmp(arg, "--not")) {
                *flags ^= UNINTERESTING | BOTTOM;
        } else if (!strcmp(arg, "--no-walk")) {
 
        test_cmp expect actual
 '
 
+test_expect_success 'rev-list can show index objects' '
+       # Of the blobs and trees in the index, note:
+       #
+       #   - we do not show two/three, because it is the
+       #     same blob as "one", and we show objects only once
+       #
+       #   - we do show the tree "two", because it has a valid cache tree
+       #     from the last commit
+       #
+       #   - we do not show the root tree; since we updated the index, it
+       #     does not have a valid cache tree
+       #
+       cat >expect <<-\EOF
+       8e4020bb5a8d8c873b25de15933e75cc0fc275df one
+       d9d3a7417b9605cfd88ee6306b28dadc29e6ab08 only-in-index
+       9200b628cf9dc883a85a7abc8d6e6730baee589c two
+       EOF
+       echo only-in-index >only-in-index &&
+       git add only-in-index &&
+       git rev-list --objects --indexed-objects >actual &&
+       test_cmp expect actual
+'
+
 test_done