Home Explore Blog CI



git

10th chunk of `Documentation/MyFirstObjectWalk.adoc`
81209592e4daa9f94618318415dc02b690232434acc679d40000000100000e3c
 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

Title: Modifying the Object Walk
Summary
This section explains how to modify the object walk to count omitted objects, change the order of the walk, and make the handlers more verbose, allowing for a better understanding of the walk's behavior and the effects of different settings, such as the `reverse` setting, on the walk's output.