Home Explore Blog CI



git

3rd chunk of `Documentation/MyFirstObjectWalk.adoc`
35a887f2f0149403f9e051addd74680b71f598a488f9c43f0000000100000fa4
 examining configuration files which may modify command behavior, set up
default state for switches or options your command may have. If your command
utilizes other Git components, ask them to set up their default states as well.
For instance, `git log` takes advantage of `grep` and `diff` functionality, so
its `init_log_defaults()` sets its own state (`decoration_style`) and asks
`grep` and `diff` to initialize themselves by calling each of their
initialization functions.

==== Configuring From `.gitconfig`

Next, we should have a look at any relevant configuration settings (i.e.,
settings readable and settable from `git config`). This is done by providing a
callback to `git_config()`; within that callback, you can also invoke methods
from other components you may need that need to intercept these options. Your
callback will be invoked once per each configuration value which Git knows about
(global, local, worktree, etc.).

Similarly to the default values, we don't have anything to do here yet
ourselves; however, we should call `git_default_config()` if we aren't calling
any other existing config callbacks.

Add a new function to `builtin/walken.c`.
We'll also need to include the `config.h` header:

----
#include "config.h"

...

static int git_walken_config(const char *var, const char *value,
			     const struct config_context *ctx, void *cb)
{
	/*
	 * For now, we don't have any custom configuration, so fall back to
	 * the default config.
	 */
	return git_default_config(var, value, ctx, cb);
}
----

Make sure to invoke `git_config()` with it in your `cmd_walken()`:

----
int cmd_walken(int argc, const char **argv, const char *prefix)
{
	...

	git_config(git_walken_config, NULL);

	...
}
----

==== Setting Up `rev_info`

Now that we've gathered external configuration and options, it's time to
initialize the `rev_info` object which we will use to perform the walk. This is
typically done by calling `repo_init_revisions()` with the repository you intend
to target, as well as the `prefix` argument of `cmd_walken` and your `rev_info`
struct.

Add the `struct rev_info` and the `repo_init_revisions()` call.
We'll also need to include the `revision.h` header:

----
#include "revision.h"

...

int cmd_walken(int argc, const char **argv, const char *prefix)
{
	/* This can go wherever you like in your declarations.*/
	struct rev_info rev;
	...

	/* This should go after the git_config() call. */
	repo_init_revisions(the_repository, &rev, prefix);

	...
}
----

==== Tweaking `rev_info` For the Walk

We're getting close, but we're still not quite ready to go. Now that `rev` is
initialized, we can modify it to fit our needs. This is usually done within a
helper for clarity, so let's add one:

----
static void final_rev_info_setup(struct rev_info *rev)
{
	/*
	 * We want to mimic the appearance of `git log --oneline`, so let's
	 * force oneline format.
	 */
	get_commit_format("oneline", rev);

	/* Start our object walk at HEAD. */
	add_head_to_pending(rev);
}
----

[NOTE]
====
Instead of using the shorthand `add_head_to_pending()`, you could do
something like this:

----
	struct setup_revision_opt opt;

	memset(&opt, 0, sizeof(opt));
	opt.def = "HEAD";
	opt.revarg_opt = REVARG_COMMITTISH;
	setup_revisions(argc, argv, rev, &opt);
----

Using a `setup_revision_opt` gives you finer control over your walk's starting
point.
====

Then let's invoke `final_rev_info_setup()` after the call to
`repo_init_revisions()`:

----
int cmd_walken(int argc, const char **argv, const char *prefix)
{
	...

	final_rev_info_setup(&rev);

	...
}
----

Later, we may wish to add more arguments to `final_rev_info_setup()`. But for
now, this is all we need.

==== Preparing `rev_info` For the Walk

Now that `rev` is all initialized and configured, we've got one more setup step
before we get rolling. We can do this in a helper, which will both prepare the
`rev_info` for the walk, and perform the walk itself. Let's start the helper
with the call to `prepare_revision_walk()`,

Title: Configuring and Initializing Revision Walk in Git
Summary
This section discusses the configuration and initialization of a revision walk in Git, including setting up default state, configuring from `.gitconfig`, initializing the `rev_info` object, tweaking it for the walk, and preparing it for the walk, with code examples and explanations of the steps involved.