You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ph...@apache.org on 2013/02/12 14:29:26 UTC

svn commit: r1445164 - in /subversion/trunk/subversion: libsvn_client/blame.c svn/blame-cmd.c tests/cmdline/blame_tests.py

Author: philip
Date: Tue Feb 12 13:29:26 2013
New Revision: 1445164

URL: http://svn.apache.org/r1445164
Log:
Make blame only check for binary mime-type on the final revision instead
of every revision.  If the final file is not binary, but was binary in the
past, blame will now run without requiring --force.

* subversion/libsvn_client/blame.c
  (struct file_rev_baton): Remove unused member.
  (check_mimetype): Remove unused function.
  (file_rev_handler): Don't check mime-type.
  (svn_client_blame5): Check final mime-type.

* subversion/svn/blame-cmd.c
  (svn_cl__blame): Add another non-existant file error.

* subversion/tests/cmdline/blame_tests.py
  (blame_binary): Adapt to test new behaviour.
  (blame_file_not_in_head, blame_multiple_targets): Tweak expected errors.

Modified:
    subversion/trunk/subversion/libsvn_client/blame.c
    subversion/trunk/subversion/svn/blame-cmd.c
    subversion/trunk/subversion/tests/cmdline/blame_tests.py

Modified: subversion/trunk/subversion/libsvn_client/blame.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/blame.c?rev=1445164&r1=1445163&r2=1445164&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/blame.c (original)
+++ subversion/trunk/subversion/libsvn_client/blame.c Tue Feb 12 13:29:26 2013
@@ -79,7 +79,6 @@ struct file_rev_baton {
   const char *target;
   svn_client_ctx_t *ctx;
   const svn_diff_file_options_t *diff_options;
-  svn_boolean_t ignore_mime_type;
   /* name of file containing the previous revision of the file */
   const char *last_filename;
   struct rev *rev;     /* the rev for which blame is being assigned
@@ -383,27 +382,6 @@ window_handler(svn_txdelta_window_t *win
   return SVN_NO_ERROR;
 }
 
-/* Throw an SVN_ERR_CLIENT_IS_BINARY_FILE error if PROP_DIFFS indicates a
-   binary MIME type.  Else, return SVN_NO_ERROR. */
-static svn_error_t *
-check_mimetype(const apr_array_header_t *prop_diffs, const char *target,
-               apr_pool_t *pool)
-{
-  int i;
-
-  for (i = 0; i < prop_diffs->nelts; ++i)
-    {
-      const svn_prop_t *prop = &APR_ARRAY_IDX(prop_diffs, i, svn_prop_t);
-      if (strcmp(prop->name, SVN_PROP_MIME_TYPE) == 0
-          && prop->value
-          && svn_mime_type_is_binary(prop->value->data))
-        return svn_error_createf
-          (SVN_ERR_CLIENT_IS_BINARY_FILE, 0,
-           _("Cannot calculate blame information for binary file '%s'"),
-           svn_dirent_local_style(target, pool));
-    }
-  return SVN_NO_ERROR;
-}
 
 /* Calculate and record blame information for one revision of the file,
  * by comparing the file content against the previously seen revision.
@@ -432,10 +410,6 @@ file_rev_handler(void *baton, const char
   /* Clear the current pool. */
   svn_pool_clear(frb->currpool);
 
-  /* If this file has a non-textual mime-type, bail out. */
-  if (! frb->ignore_mime_type)
-    SVN_ERR(check_mimetype(prop_diffs, frb->target, frb->currpool));
-
   if (frb->ctx->notify_func2)
     {
       svn_wc_notify_t *notify
@@ -640,12 +614,43 @@ svn_client_blame5(const char *target,
       (SVN_ERR_CLIENT_BAD_REVISION, NULL,
        _("Start revision must precede end revision"));
 
+  /* We check the mime-type of the yougest revision before getting all
+     the older revisions. */
+  if (!ignore_mime_type)
+    {
+      apr_hash_t *props;
+      apr_hash_index_t *hi;
+
+      SVN_ERR(svn_client_propget5(&props, NULL, SVN_PROP_MIME_TYPE,
+                                  target_abspath_or_url,  peg_revision,
+                                  end, NULL, svn_depth_empty, NULL, ctx,
+                                  pool, pool));
+
+      /* props could be keyed on URLs or paths depending on the
+         peg_revision and end values so avoid using the key. */
+      hi = apr_hash_first(pool, props);
+      if (hi)
+        {
+          svn_string_t *value;
+
+          /* Should only be one value */
+          SVN_ERR_ASSERT(apr_hash_count(props) == 1);
+
+          value = svn__apr_hash_index_val(hi);
+          if (value && svn_mime_type_is_binary(value->data))
+            return svn_error_createf
+              (SVN_ERR_CLIENT_IS_BINARY_FILE, 0,
+               _("Cannot calculate blame information for binary file '%s'"),
+               (svn_path_is_url(target)
+                ? target : svn_dirent_local_style(target, pool)));
+        }
+    }
+
   frb.start_rev = start_revnum;
   frb.end_rev = end_revnum;
   frb.target = target;
   frb.ctx = ctx;
   frb.diff_options = diff_options;
-  frb.ignore_mime_type = ignore_mime_type;
   frb.include_merged_revisions = include_merged_revisions;
   frb.last_filename = NULL;
   frb.last_original_filename = NULL;

Modified: subversion/trunk/subversion/svn/blame-cmd.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/blame-cmd.c?rev=1445164&r1=1445163&r2=1445164&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/blame-cmd.c (original)
+++ subversion/trunk/subversion/svn/blame-cmd.c Tue Feb 12 13:29:26 2013
@@ -381,6 +381,7 @@ svn_cl__blame(apr_getopt_t *os,
                                           target));
             }
           else if (err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND ||
+                   err->apr_err == SVN_ERR_ENTRY_NOT_FOUND ||
                    err->apr_err == SVN_ERR_FS_NOT_FILE ||
                    err->apr_err == SVN_ERR_FS_NOT_FOUND)
             {

Modified: subversion/trunk/subversion/tests/cmdline/blame_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/blame_tests.py?rev=1445164&r1=1445163&r2=1445164&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/blame_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/blame_tests.py Tue Feb 12 13:29:26 2013
@@ -130,23 +130,36 @@ def blame_binary(sbox):
   svntest.main.file_append(iota, "More new contents for iota\n")
   svntest.main.run_svn(binary_mime_type_on_text_file_warning,
                        'propset', 'svn:mime-type', 'image/jpeg', iota)
+
+  # Blame fails when mime-type is locally modified to binary
+  exit_code, output, errput = svntest.main.run_svn(2, 'blame', iota)
+  if (len(errput) != 1) or (errput[0].find('Skipping') == -1):
+    raise svntest.Failure
+
   svntest.main.run_svn(None, 'ci',
                        '-m', '', iota)
 
+  # Blame fails when mime-type is binary
+  exit_code, output, errput = svntest.main.run_svn(2, 'blame', iota)
+  if (len(errput) != 1) or (errput[0].find('Skipping') == -1):
+    raise svntest.Failure
+
   # Once more, but now let's remove that mimetype.
   iota = os.path.join(wc_dir, 'iota')
   svntest.main.file_append(iota, "Still more new contents for iota\n")
   svntest.main.run_svn(None, 'propdel', 'svn:mime-type', iota)
   svntest.main.run_svn(None, 'ci',
                        '-m', '', iota)
-
-  exit_code, output, errput = svntest.main.run_svn(2, 'blame', iota)
+  
+  # Blame fails when asking about an old revision where the mime-type is binary
+  exit_code, output, errput = svntest.main.run_svn(2, 'blame', iota + '@3')
   if (len(errput) != 1) or (errput[0].find('Skipping') == -1):
     raise svntest.Failure
 
   # But with --force, it should work.
-  exit_code, output, errput = svntest.main.run_svn(2, 'blame', '--force', iota)
-  if (len(errput) != 0 or len(output) != 4):
+  exit_code, output, errput = svntest.main.run_svn(2, 'blame', '--force',
+                                                   iota + '@3')
+  if (len(errput) != 0 or len(output) != 3):
     raise svntest.Failure
 
 
@@ -602,7 +615,7 @@ def blame_file_not_in_head(sbox):
 
   # Check that a correct error message is printed when blaming a target that
   # doesn't exist (in HEAD).
-  expected_err = ".*notexisting' (is not a file.*|path not found)"
+  expected_err = ".*notexisting' (is not a file.*|path not found|does not exist)"
   svntest.actions.run_and_verify_svn(None, [], expected_err,
                                      'blame', notexisting_url)
 
@@ -847,7 +860,7 @@ def blame_multiple_targets(sbox):
       "     2    jrandom New contents for iota\n",
       ]
 
-    expected_err = ".*(W160017|W160013).*\n.*E200009.*"
+    expected_err = ".*(W160017|W160013|W150000).*\n.*E200009.*"
     expected_err_re = re.compile(expected_err, re.DOTALL)
 
     exit_code, output, error = svntest.main.run_svn(1, 'blame',