Home Explore Blog CI



git

5th chunk of `Documentation/MyFirstObjectWalk.adoc`
cd35ebe26a9ef0de1f4189bd5bf53bda3f70753ca5fd5c2c0000000100000fa5
 *var, const char *value,
			     const struct config_context *ctx, void *cb)
{
	grep_config(var, value, ctx, cb);
	return git_default_config(var, value, ctx, cb);
}
----

Next, we can modify the `grep_filter`. This is done with convenience functions
found in `grep.h`. For fun, we're filtering to only commits from folks using a
`gmail.com` email address - a not-very-precise guess at who may be working on
Git as a hobby. Since we're checking the author, which is a specific line in the
header, we'll use the `append_header_grep_pattern()` helper. We can use
the `enum grep_header_field` to indicate which part of the commit header we want
to search.

In `final_rev_info_setup()`, add your filter line:

----
static void final_rev_info_setup(int argc, const char **argv,
		const char *prefix, struct rev_info *rev)
{
	...

	append_header_grep_pattern(&rev->grep_filter, GREP_HEADER_AUTHOR,
		"gmail");
	compile_grep_patterns(&rev->grep_filter);

	...
}
----

`append_header_grep_pattern()` adds your new "gmail" pattern to `rev_info`, but
it won't work unless we compile it with `compile_grep_patterns()`.

NOTE: If you are using `setup_revisions()` (for example, if you are passing a
`setup_revision_opt` instead of using `add_head_to_pending()`), you don't need
to call `compile_grep_patterns()` because `setup_revisions()` calls it for you.

NOTE: We could add the same filter via the `append_grep_pattern()` helper if we
wanted to, but `append_header_grep_pattern()` adds the `enum grep_context` and
`enum grep_pat_token` for us.

=== Changing the Order

There are a few ways that we can change the order of the commits during a
revision walk. Firstly, we can use the `enum rev_sort_order` to choose from some
typical orderings.

`topo_order` is the same as `git log --topo-order`: we avoid showing a parent
before all of its children have been shown, and we avoid mixing commits which
are in different lines of history. (`git help log`'s section on `--topo-order`
has a very nice diagram to illustrate this.)

Let's see what happens when we run with `REV_SORT_BY_COMMIT_DATE` as opposed to
`REV_SORT_BY_AUTHOR_DATE`. Add the following:

----
static void final_rev_info_setup(int argc, const char **argv,
		const char *prefix, struct rev_info *rev)
{
	...

	rev->topo_order = 1;
	rev->sort_order = REV_SORT_BY_COMMIT_DATE;

	...
}
----

Let's output this into a file so we can easily diff it with the walk sorted by
author date.

----
$ make
$ ./bin-wrappers/git walken > commit-date.txt
----

Then, let's sort by author date and run it again.

----
static void final_rev_info_setup(int argc, const char **argv,
		const char *prefix, struct rev_info *rev)
{
	...

	rev->topo_order = 1;
	rev->sort_order = REV_SORT_BY_AUTHOR_DATE;

	...
}
----

----
$ make
$ ./bin-wrappers/git walken > author-date.txt
----

Finally, compare the two. This is a little less helpful without object names or
dates, but hopefully we get the idea.

----
$ diff -u commit-date.txt author-date.txt
----

This display indicates that commits can be reordered after they're written, for
example with `git rebase`.

Let's try one more reordering of commits. `rev_info` exposes a `reverse` flag.
Set that flag somewhere inside of `final_rev_info_setup()`:

----
static void final_rev_info_setup(int argc, const char **argv, const char *prefix,
		struct rev_info *rev)
{
	...

	rev->reverse = 1;

	...
}
----

Run your walk again and note the difference in order. (If you remove the grep
pattern, you should see the last commit this call gives you as your current
HEAD.)

== Basic Object Walk

So far we've been walking only commits. But Git has more types of objects than
that! Let's see if we can walk _all_ objects, and find out some information
about each one.

We can base our work on an example. `git pack-objects` prepares all kinds of
objects for packing into a bitmap or packfile. The work we are interested in
resides in `builtin/pack-objects.c:get_object_list()`; examination of that
function shows that the all-object

Title: Customizing the Revision Walk in Git
Summary
This section discusses customizing the revision walk in Git, including adding filters based on author email, changing the order of commits using `enum rev_sort_order`, and using flags like `rev->reverse` to reverse the order of commits, as well as introducing the concept of walking all objects in a Git repository.