rev-list: add --indexed-objects option
authorJeff King <peff@peff.net>
Fri, 17 Oct 2014 00:44:23 +0000 (20:44 -0400)
committerJunio C Hamano <gitster@pobox.com>
Sun, 19 Oct 2014 22:07:07 +0000 (15:07 -0700)
There is currently no easy way to ask the revision traversal
machinery to include objects reachable from the index (e.g.,
blobs and trees that have not yet been committed). This
patch adds an option to do so.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/rev-list-options.txt
revision.c
revision.h
t/t6000-rev-list-misc.sh
index 4cf94c680399de7345fa4c634e9387168ebd6c8a..3301fdebf0206e7722acd5dd6863168d56aba55d 100644 (file)
@@ -172,6 +172,11 @@ explicitly.
        Pretend as if all objects mentioned by reflogs are listed on the
        command line as `<commit>`.
 
+--indexed-objects::
+       Pretend as if all trees and blobs used by the index are listed
+       on the command line.  Note that you probably want to use
+       `--objects`, too.
+
 --ignore-missing::
        Upon seeing an invalid object name in the input, pretend as if
        the bad input was not given.
index ebe3e93d1298c542ae655e3af3b5b2761f0061de..a2337f8ff98342e56293a81513bf91d41e71ec36 100644 (file)
@@ -17,6 +17,7 @@
 #include "mailmap.h"
 #include "commit-slab.h"
 #include "dir.h"
+#include "cache-tree.h"
 
 volatile show_early_output_fn_t show_early_output;
 
@@ -1303,6 +1304,53 @@ void add_reflogs_to_pending(struct rev_info *revs, unsigned flags)
        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];
@@ -1653,6 +1701,7 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
            !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="))
@@ -2082,6 +2131,8 @@ static int handle_revision_pseudo_opt(const char *submodule,
                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")) {
index e644044174ef17054e0edd515864ee15d8ba6fe4..e6dcd5dabd1170ac98142b566690df26924d6571 100644 (file)
@@ -277,6 +277,7 @@ extern void add_pending_sha1(struct rev_info *revs,
 
 extern void add_head_to_pending(struct rev_info *);
 extern void add_reflogs_to_pending(struct rev_info *, unsigned int flags);
+extern void add_index_objects_to_pending(struct rev_info *, unsigned int flags);
 
 enum commit_action {
        commit_ignore,
index 3794e4ceafc291be5621411f3cad7bf5ef764942..2602086303edeae192606d82d7fd1e71ac76534f 100755 (executable)
@@ -73,4 +73,27 @@ test_expect_success 'symleft flag bit is propagated down from tag' '
        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