Merge branch 'sb/describe-blob'
authorJunio C Hamano <gitster@pobox.com>
Thu, 28 Dec 2017 22:08:50 +0000 (14:08 -0800)
committerJunio C Hamano <gitster@pobox.com>
Thu, 28 Dec 2017 22:08:50 +0000 (14:08 -0800)
"git describe" was taught to dig trees deeper to find a
<commit-ish>:<path> that refers to a given blob object.

* sb/describe-blob:
builtin/describe.c: describe a blob
builtin/describe.c: factor out describe_commit
builtin/describe.c: print debug statements earlier
builtin/describe.c: rename `oid` to avoid variable shadowing
revision.h: introduce blob/tree walking in order of the commits
list-objects.c: factor out traverse_trees_and_blobs
t6120: fix typo in test name

1  2 
Documentation/rev-list-options.txt
builtin/describe.c
list-objects.c
revision.c
revision.h
Simple merge
Simple merge
diff --cc list-objects.c
index d9e83d05e15d36a4cba49de95ad35d7cdf54c199,4caa6fcb77c5601426792969ff0a1c02b3d18711..0966cdc9fa8dd448aa9955a2fb5324ae8ebbf97d
@@@ -214,27 -183,15 +214,17 @@@ static void add_pending_tree(struct rev
        add_pending_object(revs, &tree->object, "");
  }
  
- static void do_traverse(struct rev_info *revs,
-                       show_commit_fn show_commit,
-                       show_object_fn show_object,
-                       void *show_data,
-                       filter_object_fn filter_fn,
-                       void *filter_data)
+ static void traverse_trees_and_blobs(struct rev_info *revs,
+                                    struct strbuf *base,
+                                    show_object_fn show_object,
 -                                   void *data)
++                                   void *show_data,
++                                   filter_object_fn filter_fn,
++                                   void *filter_data)
  {
        int i;
-       struct commit *commit;
-       struct strbuf base;
  
-       strbuf_init(&base, PATH_MAX);
-       while ((commit = get_revision(revs)) != NULL) {
-               /*
-                * an uninteresting boundary commit may not have its tree
-                * parsed yet, but we are not going to show them anyway
-                */
-               if (commit->tree)
-                       add_pending_tree(revs, commit->tree);
-               show_commit(commit, show_data);
-       }
+       assert(base->len == 0);
        for (i = 0; i < revs->pending.nr; i++) {
                struct object_array_entry *pending = revs->pending.objects + i;
                struct object *obj = pending->item;
                        path = "";
                if (obj->type == OBJ_TREE) {
                        process_tree(revs, (struct tree *)obj, show_object,
-                                    &base, path, show_data,
 -                                   base, path, data);
++                                   base, path, show_data,
 +                                   filter_fn, filter_data);
                        continue;
                }
                if (obj->type == OBJ_BLOB) {
                        process_blob(revs, (struct blob *)obj, show_object,
-                                    &base, path, show_data,
 -                                   base, path, data);
++                                   base, path, show_data,
 +                                   filter_fn, filter_data);
                        continue;
                }
                die("unknown pending object %s (%s)",
                    oid_to_hex(&obj->oid), name);
        }
        object_array_clear(&revs->pending);
-       strbuf_release(&base);
+ }
 -void traverse_commit_list(struct rev_info *revs,
 -                        show_commit_fn show_commit,
 -                        show_object_fn show_object,
 -                        void *data)
++static void do_traverse(struct rev_info *revs,
++                      show_commit_fn show_commit,
++                      show_object_fn show_object,
++                      void *show_data,
++                      filter_object_fn filter_fn,
++                      void *filter_data)
+ {
+       struct commit *commit;
+       struct strbuf csp; /* callee's scratch pad */
+       strbuf_init(&csp, PATH_MAX);
+       while ((commit = get_revision(revs)) != NULL) {
+               /*
+                * an uninteresting boundary commit may not have its tree
+                * parsed yet, but we are not going to show them anyway
+                */
+               if (commit->tree)
+                       add_pending_tree(revs, commit->tree);
 -              show_commit(commit, data);
++              show_commit(commit, show_data);
+               if (revs->tree_blobs_in_commit_order)
+                       /*
+                        * NEEDSWORK: Adding the tree and then flushing it here
+                        * needs a reallocation for each commit. Can we pass the
+                        * tree directory without allocation churn?
+                        */
 -                      traverse_trees_and_blobs(revs, &csp, show_object, data);
++                      traverse_trees_and_blobs(revs, &csp,
++                                               show_object, show_data,
++                                               filter_fn, filter_data);
+       }
 -      traverse_trees_and_blobs(revs, &csp, show_object, data);
 -
++      traverse_trees_and_blobs(revs, &csp,
++                               show_object, show_data,
++                               filter_fn, filter_data);
+       strbuf_release(&csp);
  }
 +
 +void traverse_commit_list(struct rev_info *revs,
 +                        show_commit_fn show_commit,
 +                        show_object_fn show_object,
 +                        void *show_data)
 +{
 +      do_traverse(revs, show_commit, show_object, show_data, NULL, NULL);
 +}
 +
 +void traverse_commit_list_filtered(
 +      struct list_objects_filter_options *filter_options,
 +      struct rev_info *revs,
 +      show_commit_fn show_commit,
 +      show_object_fn show_object,
 +      void *show_data,
 +      struct oidset *omitted)
 +{
 +      filter_object_fn filter_fn = NULL;
 +      filter_free_fn filter_free_fn = NULL;
 +      void *filter_data = NULL;
 +
 +      filter_data = list_objects_filter__init(omitted, filter_options,
 +                                              &filter_fn, &filter_free_fn);
 +      do_traverse(revs, show_commit, show_object, show_data,
 +                  filter_fn, filter_data);
 +      if (filter_data && filter_free_fn)
 +              filter_free_fn(filter_data);
 +}
diff --cc revision.c
Simple merge
diff --cc revision.h
Simple merge