NULL;
int omitted_count = 0;
oidset_init(&omitted, 0);
...
----
Replace the call to `traverse_commit_list()` with
`traverse_commit_list_filtered()` and pass a pointer to the `omitted` oidset
defined and initialized above:
----
...
traverse_commit_list_filtered(rev,
walken_show_commit, walken_show_object, NULL, &omitted);
...
----
Then, after your traversal, the `oidset` traversal is pretty straightforward.
Count all the objects within and modify the print statement:
----
/* Count the omitted objects. */
oidset_iter_init(&omitted, &oit);
while ((oid = oidset_iter_next(&oit)))
omitted_count++;
printf("commits %d\nblobs %d\ntags %d\ntrees %d\nomitted %d\n",
commit_count, blob_count, tag_count, tree_count, omitted_count);
----
By running your walk with and without the filter, you should find that the total
object count in each case is identical. You can also time each invocation of
the `walken` subcommand, with and without `omitted` being passed in, to confirm
to yourself the runtime impact of tracking all omitted objects.
=== Changing the Order
Finally, let's demonstrate that you can also reorder walks of all objects, not
just walks of commits. First, we'll make our handlers chattier - modify
`walken_show_commit()` and `walken_show_object()` to print the object as they
go:
----
#include "hex.h"
...
static void walken_show_commit(struct commit *cmt, void *buf)
{
trace_printf("commit: %s\n", oid_to_hex(&cmt->object.oid));
commit_count++;
}
static void walken_show_object(struct object *obj, const char *str, void *buf)
{
trace_printf("%s: %s\n", type_name(obj->type), oid_to_hex(&obj->oid));
...
}
----
NOTE: Since we will be examining this output directly as humans, we'll use
`trace_printf()` here. Additionally, since this change introduces a significant
number of printed lines, using `trace_printf()` will allow us to easily silence
those lines without having to recompile.
(Leave the counter increment logic in place.)
With only that change, run again (but save yourself some scrollback):
----
$ GIT_TRACE=1 ./bin-wrappers/git walken 2>&1 | head -n 10
----
Take a look at the top commit with `git show` and the object ID you printed; it
should be the same as the output of `git show HEAD`.
Next, let's change a setting on our `struct rev_info` within
`walken_object_walk()`. Find where you're changing the other settings on `rev`,
such as `rev->tree_objects` and `rev->tree_blobs_in_commit_order`, and add the
`reverse` setting at the bottom:
----
...
rev->tree_objects = 1;
rev->blob_objects = 1;
rev->tag_objects = 1;
rev->tree_blobs_in_commit_order = 1;
rev->reverse = 1;
...
----
Now, run again, but this time, let's grab the last handful of objects instead
of the first handful:
----
$ make
$ GIT_TRACE=1 ./bin-wrappers/git walken 2>&1 | tail -n 10
----
The last commit object given should have the same OID as the one we saw at the
top before, and running `git show <oid>` with that OID should give you again
the same results as `git show HEAD`. Furthermore, if you run and examine the
first ten lines again (with `head` instead of `tail` like we did before applying
the `reverse` setting), you should see that now the first commit printed is the
initial commit, `e83c5163`.
== Wrapping Up
Let's review. In this tutorial, we:
- Built a commit walk from the ground up
- Enabled a grep filter for that commit walk
- Changed the sort order of that filtered commit walk
- Built an object walk (tags, commits, trees, and blobs) from the ground up
- Learned how to add a filter-spec to an object walk
- Changed the display order of the filtered object walk