You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2010/05/25 22:18:25 UTC

svn commit: r948197 - /subversion/trunk/subversion/svn/log-cmd.c

Author: stsp
Date: Tue May 25 20:18:25 2010
New Revision: 948197

URL: http://svn.apache.org/viewvc?rev=948197&view=rev
Log:
Make svn log --show-diff deal with newly created directories in the
log history.

* subversion/svn/log-cmd.c
  (log_entry_receiver): If the target URL cannot be found, try to show
   a diff from its parent directories, up to the root of the repository.
   While doing so try to take into account that parents may not exist,
   and that authz restrictions may apply, so handle any such errors
   gracefully. (I don't know all possible errors that can occur yet.
   Any errors that aren't handled will produce stderr output.
   I hope that if the --show-diff option produces unexpected stderr
   output users will report this so we can decide whether to catch
   additional errors if needed.)

Modified:
    subversion/trunk/subversion/svn/log-cmd.c

Modified: subversion/trunk/subversion/svn/log-cmd.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/log-cmd.c?rev=948197&r1=948196&r2=948197&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/log-cmd.c (original)
+++ subversion/trunk/subversion/svn/log-cmd.c Tue May 25 20:18:25 2010
@@ -35,6 +35,7 @@
 #include "svn_time.h"
 #include "svn_cmdline.h"
 #include "svn_props.h"
+#include "svn_pools.h"
 
 #include "cl.h"
 
@@ -273,6 +274,7 @@ log_entry_receiver(void *baton,
       apr_status_t status;
       svn_opt_revision_t start_revision;
       svn_opt_revision_t end_revision;
+      svn_error_t *err;
 
       if ((status = apr_file_open_stdout(&outfile, pool)))
         return svn_error_wrap_apr(status, _("Can't open stdout"));
@@ -291,22 +293,81 @@ log_entry_receiver(void *baton,
       end_revision.value.number = log_entry->revision;
 
       SVN_ERR(svn_cmdline_printf(pool, _("\n")));
-      SVN_ERR(svn_client_diff5(diff_options,
-                               lb->target_url,
-                               &start_revision,
-                               lb->target_url,
-                               &end_revision,
-                               NULL,
-                               svn_depth_infinity,
-                               FALSE, /* ignore ancestry */
-                               TRUE, /* no diff deleted */
-                               FALSE, /* show copies as adds */
-                               FALSE, /* ignore content type */
-                               svn_cmdline_output_encoding(pool),
-                               outfile,
-                               errfile,
-                               NULL,
-                               lb->ctx, pool));
+      err = svn_client_diff5(diff_options,
+                             lb->target_url,
+                             &start_revision,
+                             lb->target_url,
+                             &end_revision,
+                             NULL,
+                             svn_depth_infinity,
+                             FALSE, /* ignore ancestry */
+                             TRUE, /* no diff deleted */
+                             FALSE, /* show copies as adds */
+                             FALSE, /* ignore content type */
+                             svn_cmdline_output_encoding(pool),
+                             outfile,
+                             errfile,
+                             NULL,
+                             lb->ctx, pool);
+      if (err)
+        {
+          /* We get a "path not found" error in case the revision created
+           * lb->target_url. Try to show a diff from the parent instead. */
+          if (err->apr_err == SVN_ERR_FS_NOT_FOUND)
+            {
+              const char *parent;
+              apr_pool_t *iterpool;
+
+              svn_error_clear(err);
+
+              parent = svn_uri_dirname(lb->target_url, pool);
+              iterpool = svn_pool_create(pool);
+              while (strcmp(parent, lb->target_url) != 0)
+                {
+                  svn_pool_clear(iterpool);
+                  err = svn_client_diff5(diff_options,
+                                         parent,
+                                         &start_revision,
+                                         parent,
+                                         &end_revision,
+                                         NULL,
+                                         svn_depth_infinity,
+                                         FALSE, /* ignore ancestry */
+                                         TRUE, /* no diff deleted */
+                                         FALSE, /* show copies as adds */
+                                         FALSE, /* ignore content type */
+                                         svn_cmdline_output_encoding(iterpool),
+                                         outfile,
+                                         errfile,
+                                         NULL,
+                                         lb->ctx, iterpool);
+                  if (err == SVN_NO_ERROR)
+                    break;
+                  else
+                    {
+                      if (err->apr_err == SVN_ERR_FS_NOT_FOUND)
+                        {
+                          svn_error_clear(err);
+                          continue;
+                        }
+                      if (err->apr_err == SVN_ERR_RA_ILLEGAL_URL ||
+                          err->apr_err == SVN_ERR_AUTHZ_UNREADABLE ||
+                          err->apr_err == SVN_ERR_RA_LOCAL_REPOS_OPEN_FAILED)
+                        {
+                          svn_error_clear(err);
+                          break;
+                        }
+                      return svn_error_return(err);
+                    }
+
+                  parent = svn_uri_dirname(parent, pool);
+                }
+              svn_pool_destroy(iterpool);
+            }
+          else
+            return svn_error_return(err);
+        }
+
       SVN_ERR(svn_cmdline_printf(pool, _("\n")));
     }