Let's talk about behavior first. Here are some log commands:
$ svn log
$ svn log -r 20
$ svn log -r 20:30
$ svn log foo.c
$ svn log -r 20 foo.c
$ svn log -r 20:30 foo.c
The output of these would be similar to what you see now at
... that is, a straight commit-by-commit report of repository
activity, going backwards in time, i.e., most recent commits first.
(Notice how some of those commands were invoked on a specific file or
set of files. I'm assuming that does the obvious thing: show just the
commits in which that particular file(s) was involved.)
Each commit's log message contains the revision number, author, date,
and the actual log comment. Should each message also contain all the
changed paths for that commit? (That is, all files on which text or
props have been changed, and all dirs on which props have been changed
or entries added or deleted.)
This can get expensive to compute, since it requires delta_dirs-style
walk through each revision for which the log is being generated.
Should the format for commit messages be the same whether or not "svn
log" was invoked on a specific set of files? That is, if "svn log"
typically shows the paths involved in each commit, then would "svn log
foo.c" as well? (Note that in any given commit involving foo.c, other
files might be involved too -- the question is should they be shown in
the report for that commit, even though you ran "svn log foo.c" not
Since I never do very well pretending to objectivity, let me say that
I think the format of log output should always be the same, and should
always include the changed files of each commit (and if that's
expensive to compute, it's worth some effort to make it cheaper,
whether through caching, or suppressing deltification of directories,
or other means). Would like to hear thoughts from others on this,
Let's talk about implementation:
Add a new function to svn_ra_plugin_t, `get_log':
/* Return the log messages for revisions START to END, by invoking
* RECEIVER on each one.
* - If START and END are the same, then just return the message
* for that revision,
* - Else if START is less than END, return messages in that
* range (inclusive) from older to younger,
* - Else if START is greater than END, do the same from younger
* to older,
* - Else if START is a valid revision number but END is
* SVN_INVALID_REVNUM, then return all messages from START to
* - Else if START is SVN_INVALID_REVNUM but END is a valid
* revision number, then return all messages from oldest to
* - Else if both are SVN_INVALID_REVNUM, then return all
* messages, starting with youngest.
* If PATHS is non-null, then only show revisions in which at least
* one element of PATHS was changed (i.e., if file, text or props
* changed; if dir, props changed or an entry was added or
apr_array_header_t *paths, /* or maybe apr_hash_t... */
svn_client_log_entry_receiver_t *receiver /* see below */
void *receiver_baton); /* see below */
That callback looks something like this
typedef svn_error_t *(*svn_client_log_entry_receiver_t)
const char *author,
const char *message);
Actual details may vary, of course. Maybe the CHANGED_PATHS argument
won't be there, maybe the MESSAGE should be an `svn_string_t', etc.
And declaring it in svn_client makes ra dependent on client, which is
weird, so that has to be fixed... But anyway, you get the basic idea.
How does it work?
Ra_dav sends a special report request to the server (hello,
mod_dav_svn); the server responds with a custom report (hello, xml),
which ra_dav parses to drive the receiver callback an arbitrary number
Ra_local can just use the same libsvn_fs calls that mod_dav_svn uses
above, and drive the receiver directly.
So, that's the basic proposal (with thanks to Greg Stein). Thoughts?
Make it quick, I'd like to start right away. :-)
To unsubscribe, e-mail: email@example.com
For additional commands, e-mail: firstname.lastname@example.org
Received on Sat Oct 21 14:36:45 2006