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

[PATCH] Re: svnversion weirdness with svn:externals

From: C. Michael Pilato <cmpilato_at_collab.net>
Date: 2003-11-05 07:55:06 CET

"C. Michael Pilato" <cmpilato@collab.net> writes:

> "C. Michael Pilato" <cmpilato@collab.net> writes:
>
> > "Steven Brown" <swbrown@ucsd.edu> writes:
> >
> > > Hello, I recently moved to 0.32.1 from 0.27, and now 'svnversion .' in a
> > > working copy that has a svn:externals directory pulled in reports the
> > > version of the external and the version of the working copy like a mixed
> > > copy, e.g., '106:429'. It used to ignore the external and report '429'.
> > > This new behavior seems horribly wrong, and I assume is a bug.
> >
> > It's a bug. svnversion uses svn_client_status() under-the-hood, and
> > in the newer Subversion, the status operation has learned about
> > svn:externals. For svnversion to work correctly, svn_client_status()
> > should take a boolean flag for including/ignoring svn:externals (which
> > is set to "ignore" when called by svnversion).
>
> Steven, would you mind testing the following patch to see if it fixes
> this problem for you?

Ack. Scratch that. This one's cooler. It not only ignores statuses
after externals start getting handled -- it uses the cancellation
callback to trigger an immediate (or at least much-more-nearly
immediate) halting of the status operation after that point.

-----

Start ignoring statuses (and in fact, cancel the rest of the status
operation) at the first sign of those pesky svn:externals. They will
taint our version range calculation.

* subversion/svnversion/main.c
  (struct status_baton): add 'done' parameter.
  (analyze_status): Return immediately if we're done.
  (notify, cancel): New.
  (main): Initialize the baton's new 'done' parameter, and register
    the new notification and cancellation functions/batons. Also,
    check for the cancellation error return from svn_client_status(),
    which is non-fatal.

Index: subversion/svnversion/main.c
===================================================================
--- subversion/svnversion/main.c (revision 7634)
+++ subversion/svnversion/main.c (working copy)
@@ -30,6 +30,7 @@
   svn_boolean_t modified; /* is anything modified? */
   const char *wc_path; /* path whose URL we're looking for. */
   const char *wc_url; /* URL for the path whose URL we're looking for. */
+ svn_boolean_t done; /* note completion of our task. */
   apr_pool_t *pool; /* pool in which to store alloc-needy things. */
 };
 
@@ -42,6 +43,9 @@
                 svn_wc_status_t *status)
 {
   struct status_baton *sb = baton;
+
+ if (sb->done)
+ return;
 
   if (! status->entry)
     return;
@@ -70,7 +74,38 @@
     sb->wc_url = apr_pstrdup (sb->pool, status->entry->url);
 }
 
+
+/* This implements `svn_wc_notify_func_t'. */
 static void
+notify (void *baton,
+ const char *path,
+ svn_wc_notify_action_t action,
+ svn_node_kind_t kind,
+ const char *mime_type,
+ svn_wc_notify_state_t content_state,
+ svn_wc_notify_state_t prop_state,
+ svn_revnum_t revision)
+{
+ struct status_baton *sb = baton;
+ if ((action == svn_wc_notify_status_external)
+ || (action == svn_wc_notify_status_completed))
+ sb->done = TRUE;
+}
+
+
+/* This implements `svn_cancel_func_t'. */
+static svn_error_t *
+cancel (void *baton)
+{
+ struct status_baton *sb = baton;
+ if (sb->done)
+ return svn_error_create (SVN_ERR_CANCELLED, NULL, "Finished");
+ else
+ return SVN_NO_ERROR;
+}
+
+
+static void
 usage(void)
 {
   fprintf(stderr,
@@ -117,6 +152,7 @@
   svn_client_ctx_t ctx = { 0 };
   struct status_baton sb;
   svn_opt_revision_t rev;
+ svn_error_t *err;
   
   if (argc != 2 && argc != 3)
     {
@@ -168,11 +204,24 @@
   sb.max_rev = SVN_INVALID_REVNUM;
   sb.wc_path = wc_path;
   sb.wc_url = NULL;
+ sb.done = FALSE;
   sb.pool = pool;
   rev.kind = svn_opt_revision_unspecified;
- SVN_INT_ERR (svn_client_status (&youngest, wc_path, &rev, analyze_status,
- &sb, TRUE, TRUE, FALSE, FALSE, &ctx, pool));
 
+ /* Setup the notification and cancellation callbacks, and their
+ shared baton (which is also shared with the status function). */
+ ctx.notify_func = notify;
+ ctx.notify_baton = &sb;
+ ctx.cancel_func = cancel;
+ ctx.cancel_baton = &sb;
+
+ err = svn_client_status (&youngest, wc_path, &rev, analyze_status,
+ &sb, TRUE, TRUE, FALSE, FALSE, &ctx, pool);
+ if (err && (err->apr_err == SVN_ERR_CANCELLED))
+ svn_error_clear (err);
+ else
+ SVN_INT_ERR (err);
+
   if ((! sb.switched ) && (argc == 3))
     {
       /* If the trailing part of the URL of the working copy directory

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Wed Nov 5 07:56:21 2003

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

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.