Here's an attempt at fixing issue #692 the right way.
Log:
Fix issue #692 the right way. There are two special cases to be handled:
(a) The repository has 0 revisions and the user runs "svn log URL": it
is as if the user had requested -rHEAD:1. We don't want to error
out just because r1 doesn't exist.
(b) The working copy is at BASE revision 0 but the repository is not
empty, and the user runs "svn log" in the working copy: it is as if
the user requested -rBASE:1. We don't want to print the log message
for r1, since the working copy is at r0.
* subversion/include/svn_client.h
(svn_client_log): Add documentation for special case (b).
* subversion/libsvn_client/log.c
(svn_client_log): Detect both special case conditions before requesting
logs from the server. If either one occurs, invoke the log message
receiver manually with a message for revision 0.
Index: subversion/include/svn_client.h
===================================================================
--- subversion/include/svn_client.h (revision 10111)
+++ subversion/include/svn_client.h (working copy)
@@ -753,6 +753,19 @@
* revision 1. That works fine, except when there are no commits in
* the repository, hence this special case.
*
+ * Special case for working copies at revision 0:
+ *
+ * If @a start->kind is @c svn_opt_revision_base, and @a end->kind is
+ * @c svn_opt_revision_number && @a end->number is @c 1, then handle an
+ * a working copy at revision 0 specially: instead of invoking @a receiver
+ * on revisions 0 through 1, only invoke @a receiver on revision 0, passing
+ * @c NULL for changed paths and empty strings for the author and date. This
+ * is because that particular combination of @a start and @a end usually
+ * indicates the common case of log invocation from the working copy -- the
+ * user wants to see all log messages from the BASE revision back through
+ * revision 1. That works fine, except when the BASE revision is 0, hence
+ * this special case.
+ *
* If @a ctx->notify_func is non-null, then call @a ctx->notify_func/baton
* with a 'skip' signal on any unversioned targets.
*
Index: subversion/libsvn_client/log.c
===================================================================
--- subversion/libsvn_client/log.c (revision 10111)
+++ subversion/libsvn_client/log.c (working copy)
@@ -113,7 +113,7 @@
apr_array_header_t *target_urls;
apr_array_header_t *real_targets;
int i;
-
+
/* Get URLs for each target */
target_urls = apr_array_make (pool, 1, sizeof (const char *));
real_targets = apr_array_make (pool, 1, sizeof (const char *));
@@ -135,7 +135,7 @@
svn_wc_notify_state_unknown,
SVN_INVALID_REVNUM);
-
+
continue;
}
if (! entry->url)
@@ -175,6 +175,33 @@
(NULL != base_name), TRUE,
ctx, pool));
+ /* Special case: If there have been no commits, we'll get an error
+ * for requesting log of a revision higher than 0. But the
+ * default behavior of "svn log" when given a URL is to give revisions HEAD
+ * through 1, on the assumption that HEAD >= 1. So if we see a start
+ * revision of HEAD and an end revision of 1, then we just invoke the
+ * receiver manually on a hand-constructed log message for revision 0.
+ *
+ * See also http://subversion.tigris.org/issues/show_bug.cgi?id=692.
+ */
+ {
+ svn_revnum_t youngest_rev;
+ SVN_ERR (ra_lib->get_latest_revnum (session, &youngest_rev, pool));
+ if ((start->kind == svn_opt_revision_head)
+ && (youngest_rev == 0)
+ && (end->kind == svn_opt_revision_number)
+ && (end->value.number == 1))
+ {
+ /* Log receivers are free to handle revision 0 specially... But
+ just in case some don't, we make up a message here. */
+ SVN_ERR (receiver (receiver_baton,
+ NULL, 0, "", "", _("No commits in repository"),
+ pool));
+
+ return SVN_NO_ERROR;
+ }
+ }
+
/* It's a bit complex to correctly handle the special revision words
* such as "BASE", "COMMITTED", and "PREV". For example, if the
* user runs
@@ -243,20 +270,50 @@
if (start_is_local)
SVN_ERR (svn_client__get_revision_number
(&start_revnum, ra_lib, session, start, target, pool));
-
+
if (end_is_local)
SVN_ERR (svn_client__get_revision_number
(&end_revnum, ra_lib, session, end, target, pool));
- err = ra_lib->get_log (session,
- condensed_targets,
- start_revnum,
- end_revnum,
- discover_changed_paths,
- strict_node_history,
- receiver,
- receiver_baton,
- pool);
+ /* Special case: If the BASE revision is 0 but the HEAD revision
+ * of the repository is > 0, then we'll get the log message for
+ * revision 1 when running "svn log" with no arguments in the
+ * working copy. That's because the default behavior of "svn log"
+ * in a working copy is to give revisions BASE through 1, on the
+ * assumption that BASE >= 1. So if we see a start revision of
+ * BASE and an end revision of 1, then we just invoke the receiver
+ * manually on a hand-constructed log message for revision 0.
+ *
+ * See also
+ * http://subversion.tigris.org/issues/show_bug.cgi?id=692.
+ */
+ if ((start->kind == svn_opt_revision_base)
+ && (start_revnum == 0)
+ && (end->kind == svn_opt_revision_number)
+ && (end->value.number == 1))
+ {
+ err = SVN_NO_ERROR;
+
+ /* Log receivers are free to handle revision 0 specially... But
+ just in case some don't, we make up a message here. */
+ SVN_ERR (receiver (receiver_baton,
+ NULL, 0, "", "",
+ _("No commits in BASE revision"),
+ pool));
+ }
+ else
+ {
+ err = ra_lib->get_log (session,
+ condensed_targets,
+ start_revnum,
+ end_revnum,
+ discover_changed_paths,
+ strict_node_history,
+ receiver,
+ receiver_baton,
+ pool);
+ }
+
if (err)
break;
}
@@ -273,40 +330,7 @@
receiver_baton,
pool);
}
-
- /* Special case: If there have been no commits, we'll get an error
- * for requesting log of a revision higher than 0. But the
- * default behavior of "svn log" is to give revisions HEAD through
- * 1, on the assumption that HEAD >= 1.
- *
- * So if we got that error for that reason, and it looks like the
- * user was just depending on the defaults (rather than explicitly
- * requesting the log for revision 1), then we don't error. Instead
- * we just invoke the receiver manually on a hand-constructed log
- * message for revision 0.
- *
- * See also http://subversion.tigris.org/issues/show_bug.cgi?id=692.
- */
- if (err && (err->apr_err == SVN_ERR_FS_NO_SUCH_REVISION)
- && (start->kind == svn_opt_revision_head)
- && ((end->kind == svn_opt_revision_number)
- && (end->value.number == 1)))
- {
- svn_revnum_t youngest_rev;
-
- SVN_ERR (ra_lib->get_latest_revnum (session, &youngest_rev, pool));
- if (youngest_rev == 0)
- {
- err = SVN_NO_ERROR;
-
- /* Log receivers are free to handle revision 0 specially... But
- just in case some don't, we make up a message here. */
- SVN_ERR (receiver (receiver_baton,
- NULL, 0, "", "", _("No commits in repository."),
- pool));
- }
- }
}
-
+
return err;
}
-- Mike
--
Michael W. Thelen
It is a painful thing
To look at your own trouble and know
That you yourself and no one else has made it
-- Sophocles, "Ajax"
Received on Thu Jul 1 09:25:58 2004