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

[PATCH] Fix issue #1950

From: Michael W Thelen <thelenm_at_cs.utah.edu>
Date: 2004-07-28 19:24:06 CEST

Here is a repost of a patch that fixes issue #1950 and adds a test case for it
(minus whitespace fixes, to make it easier to read). It's straightforward and
should be easy to review. If you think it's worth including in 1.1, would
anyone be willing to nominate it?

-- Mike

Log:
Fix issue #1950. Fix and document the special case when the user runs "svn
log" with no arguments in a working copy at BASE revision 0. This case is
handled as if the user requested -rBASE:1. But if the repository is not
empty, we don't want to print the log message for r1, since the working copy
is at r0. Also add a test case.

* subversion/include/svn_client.h
  (svn_client_log): Add documentation for this special case.

* subversion/libsvn_client/log.c
  (svn_client_log): Detect the special case condition and if it occurs, invoke
    the log message receiver manually with a message for revision 0.

* subversion/tests/clients/cmdline/log_tests.py
  (log_with_wc_at_revision_zero): New test case for the above functionality.
  (parse_log_output): Add support for recognizing a revision 0 log message,
    since it is radically different from normal log messages.
  (check_log_chain): Only test log message text for revisions greater than 0.
    Also, fail if there are extra log messages in the list after checking all
    expected messages.

Index: subversion/include/svn_client.h
===================================================================
--- subversion/include/svn_client.h (revision 10435)
+++ subversion/include/svn_client.h (working copy)
@@ -754,6 +754,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 10435)
+++ subversion/libsvn_client/log.c (working copy)
@@ -243,20 +243,46 @@
             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. */
+ 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;
           }
Index: subversion/tests/clients/cmdline/log_tests.py
===================================================================
--- subversion/tests/clients/cmdline/log_tests.py (revision 10435)
+++ subversion/tests/clients/cmdline/log_tests.py (working copy)
@@ -255,6 +255,22 @@
       if this_item:
         this_item['msg'] = msg
         chain.append (this_item)
+ this_item = None
+ elif this_line == "No commit for revision 0.\n":
+ # Add previous log message
+ if this_item:
+ this_item['msg'] = msg
+ chain.append (this_item)
+ this_item = {}
+ this_item['revision'] = '0'
+ this_item['author'] = '(no author)'
+ this_item['date'] = '1970-01-01 00:00:00 -0000 (Thu, 01 Jan 1970)'
+ this_item['msg'] = this_line
+ chain.append (this_item)
+ this_item = None
+ # Remove the message separator line - it comes after the r0 log message,
+ # not before it.
+ log_lines.pop (0)
     else: # if didn't see separator now, then something's wrong
       raise SVNLogParseError, "trailing garbage after log message"
 
@@ -297,14 +313,17 @@
              or author == '(no author)')): raise svntest.Failure
     # Check that the log message looks right:
     msg_re = re.compile ('Log message for revision ' + `saw_rev`)
- if (not msg_re.search (msg)): raise svntest.Failure
+ if (saw_rev > 0 and not msg_re.search (msg)): raise svntest.Failure
 
   ### todo: need some multi-line log messages mixed in with the
   ### one-liners. Easy enough, just make the prime revisions use REV
   ### lines, and the rest use 1 line, or something, so it's
   ### predictable based on REV.
 
+ # If any log messages are still on the chain, that's a failure
+ if chain: raise svntest.Failure
 
+
 ######################################################################
 # Tests
 #
@@ -515,7 +534,21 @@
                                       'log', '-r', '2', mu2_path)
   svntest.actions.run_and_verify_svn (None, [], SVNAnyOutput,
                                       'log', '-r', '2', mu2_URL)
-
+
+#----------------------------------------------------------------------
+def log_with_wc_at_revision_zero(sbox):
+ "'svn log', no args, top of wc at BASE revision 0"
+
+ guarantee_repos_and_wc(sbox)
+
+ svntest.main.run_svn (None, 'up', '-r', '0', sbox.wc_dir)
+ output, err = svntest.actions.run_and_verify_svn(
+ None, None, [], 'log', sbox.wc_dir)
+
+ log_chain = parse_log_output (output)
+ if check_log_chain (log_chain, [0]):
+ raise svntest.Failure
+
 ########################################################################
 # Run the tests
 
@@ -530,6 +563,7 @@
               log_with_path_args,
               url_missing_in_head,
               log_through_copyfrom_history,
+ log_with_wc_at_revision_zero,
              ]
 
 if __name__ == '__main__':

-- 
Michael W. Thelen
The great thing about democracy is that is gives every voter a chance to do
something stupid.
                -- Art Spander

Received on Wed Jul 28 19:24:59 2004

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