[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Walking Merge History

From: Hyrum K. Wright <hyrum_wright_at_mail.utexas.edu>
Date: 2007-09-10 17:09:26 CEST

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

A couple of weeks ago, after reading Karl's excellent description[1] of
our delta editor, the idea occurred to me that we could use a similar
construct to walk through an object's ancestry, finding merging and
merged revisions, and allowing a consumer (such as the get_file_revs()
interface) to construct appropriate delta's and the like. Done right,
this could open up a lot of possibilities, such as merge history graphs.
Done wrong, we could be in a much worse situation than we are now.

Having looked at the problem for a while, and realizing that I'm just
not smart enough to go it alone, I'd like to get some opinions on the
best way to design the interface. So far, I've got something like:

typedef struct svn_repos__ancestry_callbacks_t
{
  /* An ancestor was found in PATH at REV. */
  svn_error_t *(*found_ancestor)(void *walk_baton,
                                 const char *path,
                                 svn_revnum_t rev,
                                 svn_boolean_t *halt,
                                 apr_pool_t *pool);

} svn_repos__ancestry_callbacks_t;

/* Walk the ancestry of PATH, from END to START, calling CALLBACKS as
   needed. */
svn_error_t *
svn_repos__walk_ancestry(const char *end_path,
                         svn_fs_t *fs,
                         svn_revnum_t start,
                         svn_revnum_t end,
                         svn_boolean_t include_merges,
                         svn_boolean_t stop_on_copy,
                         const svn_repos__ancestry_callbacks_t
                                                         *callbacks,
                         void *callbacks_baton,
                         svn_repos_authz_func_t authz_read_func,
                         void *authz_read_baton,
                         apr_pool_t *pool);

This is great at traversing one line of history, but what about multiple
lines? Unlike the delta editor where a node is either a directory or a
file, in the case of ancestry, a revision can be both a merging
revision, as well as a revision that somebody made edits to. Should
there be multiple callbacks? Which order should they come in? Is there
a way to send multiple lines of history streamily?

Some other questions:
 * Should we have separate callbacks for flagging merging and "end of
   branch" revisions, or just add flags on the existing callback?

 * Should we implement this walker in as public API, so that the client
   libraries can use it directly? What would be the best way to do so?
   (If we did do that, we'd need to transmit deltas, similar to
   get_file_revs().)

In some ways, I feel that my current implementation of 'blame -g' is
pretty hacky, and doesn't have a very sound theoretical backing. I know
that there are some bugs in there, and actually implementing an ancestry
walker would go a long way toward improving correctness.

Thoughts?

- -Hyrum

[1] http://www.red-bean.com/kfogel/beautiful-code/bc-chapter-02.html
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFG5V4mCwOubk4kUXwRAvroAKCaJHCOVsks0Nz3E9AvkQ7K4gILVwCfTfGa
GjWce2emffeZQVl7fkcSrgY=
=FLb5
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Mon Sep 10 17:06:18 2007

This is an archived mail posted to the Subversion Dev mailing list.