subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From i...@apache.org
Subject svn commit: r1703974 [1/2] - in /subversion/branches/reuse-ra-session: ./ build/ subversion/include/ subversion/libsvn_client/ subversion/libsvn_diff/ subversion/svn/ subversion/svnadmin/ subversion/svnbench/ subversion/tests/cmdline/ subversion/tests/...
Date Sat, 19 Sep 2015 10:19:47 GMT
Author: ivan
Date: Sat Sep 19 10:19:47 2015
New Revision: 1703974

URL: http://svn.apache.org/viewvc?rev=1703974&view=rev
Log:
On the reuse-ra-session branch: Sync with trunk up to r1703970.

Modified:
    subversion/branches/reuse-ra-session/   (props changed)
    subversion/branches/reuse-ra-session/CHANGES
    subversion/branches/reuse-ra-session/Makefile.in
    subversion/branches/reuse-ra-session/build/run_tests.py
    subversion/branches/reuse-ra-session/subversion/include/svn_diff.h
    subversion/branches/reuse-ra-session/subversion/libsvn_client/diff.c
    subversion/branches/reuse-ra-session/subversion/libsvn_client/merge.c
    subversion/branches/reuse-ra-session/subversion/libsvn_diff/binary_diff.c
    subversion/branches/reuse-ra-session/subversion/libsvn_diff/parse-diff.c
    subversion/branches/reuse-ra-session/subversion/svn/cl.h
    subversion/branches/reuse-ra-session/subversion/svn/conflict-callbacks.c
    subversion/branches/reuse-ra-session/subversion/svn/resolve-cmd.c
    subversion/branches/reuse-ra-session/subversion/svn/svn.c
    subversion/branches/reuse-ra-session/subversion/svnadmin/svnadmin.c
    subversion/branches/reuse-ra-session/subversion/svnbench/null-export-cmd.c
    subversion/branches/reuse-ra-session/subversion/tests/cmdline/merge_automatic_tests.py
    subversion/branches/reuse-ra-session/subversion/tests/cmdline/patch_tests.py
    subversion/branches/reuse-ra-session/subversion/tests/cmdline/svntest/main.py
    subversion/branches/reuse-ra-session/tools/client-side/bash_completion
    subversion/branches/reuse-ra-session/tools/client-side/svn-mergeinfo-normalizer/analyze-cmd.c
    subversion/branches/reuse-ra-session/tools/client-side/svn-mergeinfo-normalizer/logic.c
    subversion/branches/reuse-ra-session/tools/client-side/svn-mergeinfo-normalizer/mergeinfo-normalizer.h
    subversion/branches/reuse-ra-session/tools/client-side/svn-mergeinfo-normalizer/normalize-cmd.c
    subversion/branches/reuse-ra-session/tools/client-side/svn-mergeinfo-normalizer/svn-mergeinfo-normalizer.c
    subversion/branches/reuse-ra-session/win-tests.py

Propchange: subversion/branches/reuse-ra-session/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Sat Sep 19 10:19:47 2015
@@ -94,4 +94,4 @@
 /subversion/branches/verify-at-commit:1462039-1462408
 /subversion/branches/verify-keep-going:1439280-1546110
 /subversion/branches/wc-collate-path:1402685-1480384
-/subversion/trunk:1501802-1703640
+/subversion/trunk:1501802-1703970

Modified: subversion/branches/reuse-ra-session/CHANGES
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/CHANGES?rev=1703974&r1=1703973&r2=1703974&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/CHANGES (original)
+++ subversion/branches/reuse-ra-session/CHANGES Sat Sep 19 10:19:47 2015
@@ -18,14 +18,19 @@ http://svn.apache.org/repos/asf/subversi
     * upgrade: fix crash for pre-1.3 wc with externals (r1702218 et al)
     * revert: fix crash when reverting the root of a move (r1702237 et al)
     * svn: do not crash upon specific database corruptions (r1702974, r1702991)
+    * svn: show utf8proc version in svn --version --verbose (r1702533, r1702891)
 
   - Server-side bugfixes:
     * fix reporting for empty representations in svnfsfs stats (r1698312 et al)
 
  Developer-visible changes:
+  - General:
+    * fix svnfsfs_tests.py in fsfs-v4 and fsfs-v6 modes (r1700215 et al)
+
   - API changes:
     * disable unsupported operations for standard streams (r1701633 et al)
 
+
 Version 1.9.1
 (02 Sep 2015, from /branches/1.9.x)
 http://svn.apache.org/repos/asf/subversion/tags/1.9.1

Modified: subversion/branches/reuse-ra-session/Makefile.in
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/Makefile.in?rev=1703974&r1=1703973&r2=1703974&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/Makefile.in (original)
+++ subversion/branches/reuse-ra-session/Makefile.in Sat Sep 19 10:19:47 2015
@@ -519,7 +519,6 @@ check-all-javahl: check-apache-javahl ch
 #  will perform only basic tests (likewise for other tests).
 check: bin @TRANSFORM_LIBTOOL_SCRIPTS@ $(TEST_DEPS) @BDB_TEST_DEPS@
 	@if test "$(PYTHON)" != "none"; then                                 \
-	  flags="--verbose";                                                 \
 	  if test "$(CLEANUP)" != ""; then                                   \
 	    flags="--cleanup $$flags";                                       \
 	  fi;                                                                \

Modified: subversion/branches/reuse-ra-session/build/run_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/build/run_tests.py?rev=1703974&r1=1703973&r2=1703974&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/build/run_tests.py (original)
+++ subversion/branches/reuse-ra-session/build/run_tests.py Sat Sep 19 10:19:47 2015
@@ -46,6 +46,7 @@ separated list of test numbers; the defa
 
 import os, sys
 import re
+import logging
 import optparse, subprocess, imp, threading, traceback, exceptions
 from datetime import datetime
 
@@ -181,7 +182,8 @@ class TestHarness:
     # ### Support --repos-template
     if self.opts.list_tests is not None:
       cmdline.append('--list')
-    if self.opts.verbose is not None:
+    if (self.opts.set_log_level is not None
+        and self.opts.set_log_level <= logging.DEBUG):
       cmdline.append('--verbose')
     if self.opts.cleanup is not None:
       cmdline.append('--cleanup')
@@ -204,8 +206,6 @@ class TestHarness:
     cmdline = ['--srcdir=%s' % self.srcdir]
     if self.opts.list_tests is not None:
       cmdline.append('--list')
-    if self.opts.verbose is not None:
-      cmdline.append('--verbose')
     if self.opts.cleanup is not None:
       cmdline.append('--cleanup')
     if self.opts.parallel is not None:
@@ -693,11 +693,17 @@ class TestHarness:
 
 
 def create_parser():
+  def set_log_level(option, opt, value, parser, level=None):
+    if level is None:
+      level = value
+    parser.values.set_log_level = getattr(logging, level, None) or int(level)
+
   parser = optparse.OptionParser(usage=__doc__);
 
   parser.add_option('-l', '--list', action='store_true', dest='list_tests',
                     help='Print test doc strings instead of running them')
-  parser.add_option('-v', '--verbose', action='store_true',
+  parser.add_option('-v', '--verbose', action='callback',
+                    callback=set_log_level, callback_args=(logging.DEBUG, ),
                     help='Print binary command-lines')
   parser.add_option('-c', '--cleanup', action='store_true',
                     help='Clean up after successful tests')
@@ -735,7 +741,8 @@ def create_parser():
   parser.add_option('--mode-filter', action='store', dest='mode_filter',
                     default='ALL',
                     help='Limit tests to those with type specified (e.g. XFAIL)')
-  parser.add_option('--set-log-level', action='store',
+  parser.add_option('--set-log-level', action='callback', type='str',
+                    callback=set_log_level,
                     help="Set log level (numerically or symbolically). " +
                          "Symbolic levels are: CRITICAL, ERROR, WARNING, " +
                          "INFO, DEBUG")
@@ -753,6 +760,8 @@ def create_parser():
                     help='Use sqlite exclusive locking for working copies')
   parser.add_option('--memcached-server', action='store',
                     help='Use memcached server at specified URL (FSFS only)')
+
+  parser.set_defaults(set_log_level=None)
   return parser
 
 def main():

Modified: subversion/branches/reuse-ra-session/subversion/include/svn_diff.h
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/include/svn_diff.h?rev=1703974&r1=1703973&r2=1703974&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/include/svn_diff.h (original)
+++ subversion/branches/reuse-ra-session/subversion/include/svn_diff.h Sat Sep 19 10:19:47 2015
@@ -1212,6 +1212,13 @@ typedef struct svn_prop_patch_t {
 } svn_prop_patch_t;
 
 /**
+ * A binary patch representation. This basically describes replacing one
+ * exact binary representation with another one.
+ *
+ * @since new in 1.10. */
+typedef struct svn_diff_binary_patch_t svn_diff_binary_patch_t;
+
+/**
  * Data type to manage parsing of patches.
  * API users should not allocate structures of this type directly.
  *
@@ -1249,6 +1256,12 @@ typedef struct svn_patch_t {
    * @since New in 1.9. */
   svn_mergeinfo_t mergeinfo;
   svn_mergeinfo_t reverse_mergeinfo;
+
+  /**
+   * Declares that there is a binary conflict and contains the information
+   * to apply it as parsed from the file.
+   * @since New in 1.10. */
+  svn_diff_binary_patch_t *binary_patch;
 } svn_patch_t;
 
 /** An opaque type representing an open patch file.

Modified: subversion/branches/reuse-ra-session/subversion/libsvn_client/diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_client/diff.c?rev=1703974&r1=1703973&r2=1703974&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_client/diff.c (original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_client/diff.c Sat Sep 19 10:19:47 2015
@@ -496,12 +496,12 @@ display_prop_diffs(const apr_array_heade
     }
 
   SVN_ERR(svn_stream_printf_from_utf8(outstream, encoding, scratch_pool,
-                                      _("%sProperty changes on: %s%s"),
+                                      APR_EOL_STR
+                                      "Property changes on: %s"
                                       APR_EOL_STR,
                                       use_git_diff_format
                                             ? repos_relpath1
-                                            : index_path,
-                                      APR_EOL_STR));
+                                            : index_path));
 
   SVN_ERR(svn_stream_printf_from_utf8(outstream, encoding, scratch_pool,
                                       SVN_DIFF__UNDER_STRING APR_EOL_STR));
@@ -708,6 +708,8 @@ diff_content_changed(svn_boolean_t *wrot
                SVN_DIFF__EQUAL_STRING APR_EOL_STR,
                index_path));
 
+      *wrote_header = TRUE;
+
       /* ### Print git diff headers. */
 
       if (dwi->use_git_diff_format)

Modified: subversion/branches/reuse-ra-session/subversion/libsvn_client/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_client/merge.c?rev=1703974&r1=1703973&r2=1703974&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_client/merge.c (original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_client/merge.c Sat Sep 19 10:19:47 2015
@@ -2349,17 +2349,47 @@ files_same_p(svn_boolean_t *same,
     {
       svn_stream_t *mine_stream;
       svn_stream_t *older_stream;
-      svn_opt_revision_t working_rev = { svn_opt_revision_working, { 0 } };
+      svn_string_t *special = svn_hash_gets(working_props, SVN_PROP_SPECIAL);
+      svn_string_t *eol_style = svn_hash_gets(working_props, SVN_PROP_EOL_STYLE);
+      svn_string_t *keywords = svn_hash_gets(working_props, SVN_PROP_KEYWORDS);
 
       /* Compare the file content, translating 'mine' to 'normal' form. */
-      if (svn_prop_get_value(working_props, SVN_PROP_SPECIAL) != NULL)
+      if (special != NULL)
         SVN_ERR(svn_subst_read_specialfile(&mine_stream, mine_abspath,
                                            scratch_pool, scratch_pool));
       else
-        SVN_ERR(svn_client__get_normalized_stream(&mine_stream, wc_ctx,
-                                                  mine_abspath, &working_rev,
-                                                  FALSE, TRUE, NULL, NULL,
-                                                  scratch_pool, scratch_pool));
+        SVN_ERR(svn_stream_open_readonly(&mine_stream, mine_abspath,
+                                         scratch_pool, scratch_pool));
+
+      if (!special && (eol_style || keywords))
+        {
+          apr_hash_t *kw = NULL;
+          const char *eol = NULL;
+          svn_subst_eol_style_t style;
+
+          /* We used to use svn_client__get_normalized_stream() here, but
+             that doesn't work in 100% of the cases because it doesn't
+             convert EOLs to the repository form; just to '\n'.
+           */
+
+          if (eol_style)
+            {
+              svn_subst_eol_style_from_value(&style, &eol, eol_style->data);
+
+              if (style == svn_subst_eol_style_native)
+                eol = SVN_SUBST_NATIVE_EOL_STR;
+              else if (style != svn_subst_eol_style_fixed
+                       && style != svn_subst_eol_style_none)
+                return svn_error_create(SVN_ERR_IO_UNKNOWN_EOL, NULL, NULL);
+            }
+
+          if (keywords)
+            SVN_ERR(svn_subst_build_keywords3(&kw, keywords->data, "", "",
+                                              "", 0, "", scratch_pool));
+
+          mine_stream = svn_subst_stream_translated(
+            mine_stream, eol, FALSE, kw, FALSE, scratch_pool);
+        }
 
       SVN_ERR(svn_stream_open_readonly(&older_stream, older_abspath,
                                        scratch_pool, scratch_pool));

Modified: subversion/branches/reuse-ra-session/subversion/libsvn_diff/binary_diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_diff/binary_diff.c?rev=1703974&r1=1703973&r2=1703974&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_diff/binary_diff.c (original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_diff/binary_diff.c Sat Sep 19 10:19:47 2015
@@ -213,7 +213,5 @@ svn_diff_output_binary(svn_stream_t *out
                         scratch_pool));
   svn_pool_destroy(subpool);
 
-  SVN_ERR(svn_stream_puts(output_stream, APR_EOL_STR));
-
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/reuse-ra-session/subversion/libsvn_diff/parse-diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_diff/parse-diff.c?rev=1703974&r1=1703973&r2=1703974&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_diff/parse-diff.c (original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_diff/parse-diff.c Sat Sep 19 10:19:47 2015
@@ -82,6 +82,24 @@ struct svn_diff_hunk_t {
   svn_linenum_t trailing_context;
 };
 
+struct svn_diff_binary_patch_t {
+  /* The patch this hunk belongs to. */
+  svn_patch_t *patch;
+
+  /* APR file handle to the patch file this hunk came from. */
+  apr_file_t *apr_file;
+
+  /* Offsets inside APR_FILE representing the location of the patch */
+  apr_off_t src_start;
+  apr_off_t src_end;
+  svn_filesize_t src_filesize; /* Expanded/final size */
+
+  /* Offsets inside APR_FILE representing the location of the patch */
+  apr_off_t dst_start;
+  apr_off_t dst_end;
+  svn_filesize_t dst_filesize; /* Expanded/final size */
+};
+
 void
 svn_diff_hunk_reset_diff_text(svn_diff_hunk_t *hunk)
 {
@@ -917,16 +935,17 @@ compare_hunks(const void *a, const void
 /* Possible states of the diff header parser. */
 enum parse_state
 {
-   state_start,           /* initial */
-   state_git_diff_seen,   /* diff --git */
-   state_git_tree_seen,   /* a tree operation, rather than content change */
-   state_git_minus_seen,  /* --- /dev/null; or --- a/ */
-   state_git_plus_seen,   /* +++ /dev/null; or +++ a/ */
-   state_move_from_seen,  /* rename from foo.c */
-   state_copy_from_seen,  /* copy from foo.c */
-   state_minus_seen,      /* --- foo.c */
-   state_unidiff_found,   /* valid start of a regular unidiff header */
-   state_git_header_found /* valid start of a --git diff header */
+   state_start,             /* initial */
+   state_git_diff_seen,     /* diff --git */
+   state_git_tree_seen,     /* a tree operation, rather than content change */
+   state_git_minus_seen,    /* --- /dev/null; or --- a/ */
+   state_git_plus_seen,     /* +++ /dev/null; or +++ a/ */
+   state_move_from_seen,    /* rename from foo.c */
+   state_copy_from_seen,    /* copy from foo.c */
+   state_minus_seen,        /* --- foo.c */
+   state_unidiff_found,     /* valid start of a regular unidiff header */
+   state_git_header_found,  /* valid start of a --git diff header */
+   state_binary_patch_found /* valid start of binary patch */
 };
 
 /* Data type describing a valid state transition of the parser. */
@@ -1234,6 +1253,18 @@ git_deleted_file(enum parse_state *new_s
   return SVN_NO_ERROR;
 }
 
+/* Parse the 'GIT binary patch' header */
+static svn_error_t *
+binary_patch_start(enum parse_state *new_state, char *line, svn_patch_t *patch,
+             apr_pool_t *result_pool, apr_pool_t *scratch_pool)
+{
+  patch->operation = svn_diff_op_modified;
+
+  *new_state = state_binary_patch_found;
+  return SVN_NO_ERROR;
+}
+
+
 /* Add a HUNK associated with the property PROP_NAME to PATCH. */
 static svn_error_t *
 add_property_hunk(svn_patch_t *patch, const char *prop_name,
@@ -1346,29 +1377,134 @@ parse_hunks(svn_patch_t *patch, apr_file
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+parse_binary_patch(svn_patch_t *patch, apr_file_t *apr_file,
+                   apr_pool_t *result_pool, apr_pool_t *scratch_pool)
+{
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+  apr_off_t pos, last_line;
+  svn_stringbuf_t *line;
+  svn_boolean_t eof = FALSE;
+  svn_diff_binary_patch_t *bpatch = apr_pcalloc(result_pool, sizeof(*bpatch));
+  svn_boolean_t in_blob = FALSE;
+  svn_boolean_t in_dst = FALSE;
+
+  patch->operation = svn_diff_op_modified;
+  patch->prop_patches = apr_hash_make(result_pool);
+
+  pos = 0;
+  SVN_ERR(svn_io_file_seek(apr_file, APR_CUR, &pos, scratch_pool));
+
+  while (!eof)
+    {
+      last_line = pos;
+      SVN_ERR(svn_io_file_readline(apr_file, &line, NULL, &eof, APR_SIZE_MAX,
+                               iterpool, iterpool));
+
+      /* Update line offset for next iteration. */
+      pos = 0;
+      SVN_ERR(svn_io_file_seek(apr_file, APR_CUR, &pos, iterpool));
+
+      if (in_blob)
+        {
+          char c = line->data[0];
+
+          /* 66 = len byte + (52/4*5) chars */
+          if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') 
+              && line->len <= 66
+              && !strchr(line->data, ':')
+              && !strchr(line->data, ' '))
+            {
+              /* One more blop line */
+              if (in_dst)
+                bpatch->dst_end = pos;
+              else
+                bpatch->src_end = pos;
+            }
+          else if (svn_stringbuf_first_non_whitespace(line) < line->len
+                   && !(in_dst && bpatch->dst_start < last_line))
+            {
+              break; /* Bad patch */
+            }
+          else if (in_dst)
+            {
+              patch->binary_patch = bpatch; /* SUCCESS! */
+              break; 
+            }
+          else
+            {
+              in_blob = FALSE;
+              in_dst = TRUE;
+            }
+        }
+      else if (starts_with(line->data, "literal "))
+        {
+          apr_uint64_t expanded_size;
+          svn_error_t *err = svn_cstring_strtoui64(&expanded_size,
+                                                   &line->data[8],
+                                                   0, APR_UINT64_MAX, 10);
+
+          if (err)
+            {
+              svn_error_clear(err);
+              break;
+            }
+
+          if (in_dst)
+            {
+              bpatch->dst_start = pos;
+              bpatch->dst_filesize = expanded_size;
+            }
+          else
+            {
+              bpatch->src_start = pos;
+              bpatch->src_filesize = expanded_size;
+            }
+          in_blob = TRUE;
+        }
+      else
+        break; /* We don't support GIT deltas (yet) */
+    }
+  svn_pool_destroy(iterpool);
+
+  if (!eof)
+    /* Rewind to the start of the line just read, so subsequent calls
+     * don't end up skipping the line. It may contain a patch or hunk header.*/
+    SVN_ERR(svn_io_file_seek(apr_file, APR_SET, &last_line, scratch_pool));
+  else if (in_dst
+           && ((bpatch->dst_end > bpatch->dst_start) || !bpatch->dst_filesize))
+    {
+      patch->binary_patch = bpatch; /* SUCCESS */
+    }
+
+  return SVN_NO_ERROR;
+}
+
 /* State machine for the diff header parser.
  * Expected Input   Required state          Function to call */
 static struct transition transitions[] =
 {
-  {"--- ",          state_start,            diff_minus},
-  {"+++ ",          state_minus_seen,       diff_plus},
+  {"--- ",              state_start,            diff_minus},
+  {"+++ ",              state_minus_seen,       diff_plus},
 
-  {"diff --git",    state_start,            git_start},
-  {"--- a/",        state_git_diff_seen,    git_minus},
-  {"--- a/",        state_git_tree_seen,    git_minus},
-  {"--- /dev/null", state_git_tree_seen,    git_minus},
-  {"+++ b/",        state_git_minus_seen,   git_plus},
-  {"+++ /dev/null", state_git_minus_seen,   git_plus},
+  {"diff --git",        state_start,            git_start},
+  {"--- a/",            state_git_diff_seen,    git_minus},
+  {"--- a/",            state_git_tree_seen,    git_minus},
+  {"--- /dev/null",     state_git_tree_seen,    git_minus},
+  {"+++ b/",            state_git_minus_seen,   git_plus},
+  {"+++ /dev/null",     state_git_minus_seen,   git_plus},
 
-  {"rename from ",  state_git_diff_seen,    git_move_from},
-  {"rename to ",    state_move_from_seen,   git_move_to},
+  {"rename from ",      state_git_diff_seen,    git_move_from},
+  {"rename to ",        state_move_from_seen,   git_move_to},
 
-  {"copy from ",    state_git_diff_seen,    git_copy_from},
-  {"copy to ",      state_copy_from_seen,   git_copy_to},
+  {"copy from ",        state_git_diff_seen,    git_copy_from},
+  {"copy to ",          state_copy_from_seen,   git_copy_to},
 
-  {"new file ",     state_git_diff_seen,    git_new_file},
+  {"new file ",         state_git_diff_seen,    git_new_file},
 
-  {"deleted file ", state_git_diff_seen,    git_deleted_file},
+  {"deleted file ",     state_git_diff_seen,    git_deleted_file},
+
+  {"GIT binary patch",  state_git_diff_seen,    binary_patch_start},
 };
 
 svn_error_t *
@@ -1433,7 +1569,9 @@ svn_diff_parse_next_patch(svn_patch_t **
             }
         }
 
-      if (state == state_unidiff_found || state == state_git_header_found)
+      if (state == state_unidiff_found
+          || state == state_git_header_found
+          || state == state_binary_patch_found)
         {
           /* We have a valid diff header, yay! */
           break;
@@ -1487,8 +1625,17 @@ svn_diff_parse_next_patch(svn_patch_t **
       patch = NULL;
     }
   else
-    SVN_ERR(parse_hunks(patch, patch_file->apr_file, ignore_whitespace,
-                        result_pool, iterpool));
+    {
+      if (state == state_binary_patch_found)
+        {
+          SVN_ERR(parse_binary_patch(patch, patch_file->apr_file,
+                                     result_pool, iterpool));
+          /* And fall through in property parsing */
+        }
+
+      SVN_ERR(parse_hunks(patch, patch_file->apr_file, ignore_whitespace,
+                          result_pool, iterpool));
+    }
 
   svn_pool_destroy(iterpool);
 
@@ -1496,7 +1643,7 @@ svn_diff_parse_next_patch(svn_patch_t **
   SVN_ERR(svn_io_file_seek(patch_file->apr_file, APR_CUR,
                            &patch_file->next_patch_offset, scratch_pool));
 
-  if (patch)
+  if (patch && patch->hunks)
     {
       /* Usually, hunks appear in the patch sorted by their original line
        * offset. But just in case they weren't parsed in this order for

Modified: subversion/branches/reuse-ra-session/subversion/svn/cl.h
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/svn/cl.h?rev=1703974&r1=1703973&r2=1703974&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/svn/cl.h (original)
+++ subversion/branches/reuse-ra-session/subversion/svn/cl.h Sat Sep 19 10:19:47 2015
@@ -251,10 +251,13 @@ typedef struct svn_cl__opt_state_t
   const char *show_item;           /* print only the given item */
 } svn_cl__opt_state_t;
 
+/* Conflict stats for operations such as update and merge. */
+typedef struct svn_cl__conflict_stats_t svn_cl__conflict_stats_t;
 
 typedef struct svn_cl__cmd_baton_t
 {
   svn_cl__opt_state_t *opt_state;
+  svn_cl__conflict_stats_t *conflict_stats;
   svn_client_ctx_t *ctx;
 } svn_cl__cmd_baton_t;
 
@@ -346,9 +349,6 @@ svn_cl__check_cancel(void *baton);
 typedef struct svn_cl__interactive_conflict_baton_t
   svn_cl__interactive_conflict_baton_t;
 
-/* Conflict stats for operations such as update and merge. */
-typedef struct svn_cl__conflict_stats_t svn_cl__conflict_stats_t;
-
 /* Return a new, initialized, conflict stats structure, allocated in
  * POOL. */
 svn_cl__conflict_stats_t *
@@ -405,9 +405,18 @@ svn_cl__conflict_func_interactive(svn_wc
 
 svn_error_t *
 svn_cl__resolve_conflict(svn_boolean_t *resolved,
+                         svn_cl__accept_t *accept_which,
+                         svn_boolean_t *quit,
+                         svn_boolean_t *external_failed,
+                         svn_boolean_t *printed_summary,
                          svn_client_conflict_t *conflict,
+                         const char *editor_cmd,
+                         apr_hash_t *config,
+                         const char *path_prefix,
+                         svn_cmdline_prompt_baton_t *pb,
+                         svn_cl__conflict_stats_t *conflict_stats,
+                         svn_client_conflict_option_id_t option_id,
                          svn_client_ctx_t *ctx,
-                         svn_wc_conflict_choice_t conflict_choice,
                          apr_pool_t *scratch_pool);
 
 

Modified: subversion/branches/reuse-ra-session/subversion/svn/conflict-callbacks.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/svn/conflict-callbacks.c?rev=1703974&r1=1703973&r2=1703974&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/svn/conflict-callbacks.c (original)
+++ subversion/branches/reuse-ra-session/subversion/svn/conflict-callbacks.c Sat Sep 19 10:19:47 2015
@@ -334,15 +334,16 @@ show_prop_conflict(const svn_string_t *b
 static svn_error_t *
 open_editor(svn_boolean_t *performed_edit,
             const char *merged_abspath,
-            svn_cl__interactive_conflict_baton_t *b,
+            const char *editor_cmd,
+            apr_hash_t *config,
             apr_pool_t *pool)
 {
   svn_error_t *err;
 
   if (merged_abspath)
     {
-      err = svn_cmdline__edit_file_externally(merged_abspath, b->editor_cmd,
-                                              b->config, pool);
+      err = svn_cmdline__edit_file_externally(merged_abspath, editor_cmd,
+                                              config, pool);
       if (err && (err->apr_err == SVN_ERR_CL_NO_EXTERNAL_EDITOR ||
                   err->apr_err == SVN_ERR_EXTERNAL_PROGRAM))
         {
@@ -376,7 +377,9 @@ edit_prop_conflict(const svn_string_t **
                    const svn_string_t *base_propval,
                    const svn_string_t *my_propval,
                    const svn_string_t *their_propval,
-                   svn_cl__interactive_conflict_baton_t *b,
+                   const char *editor_cmd,
+                   apr_hash_t *config,
+                   svn_cmdline_prompt_baton_t *pb,
                    apr_pool_t *result_pool,
                    apr_pool_t *scratch_pool)
 {
@@ -392,12 +395,13 @@ edit_prop_conflict(const svn_string_t **
                                          scratch_pool);
   SVN_ERR(merge_prop_conflict(merged_prop, base_propval, my_propval,
                               their_propval, NULL,
-                              b->pb->cancel_func,
-                              b->pb->cancel_baton,
+                              pb->cancel_func,
+                              pb->cancel_baton,
                               scratch_pool));
   SVN_ERR(svn_stream_close(merged_prop));
   SVN_ERR(svn_io_file_flush(file, scratch_pool));
-  SVN_ERR(open_editor(&performed_edit, file_path, b, scratch_pool));
+  SVN_ERR(open_editor(&performed_edit, file_path, editor_cmd,
+                      config, scratch_pool));
   if (performed_edit && merged_propval)
     {
       svn_stringbuf_t *buf;
@@ -708,8 +712,13 @@ prompt_user(const resolver_option_t **op
 static svn_error_t *
 handle_text_conflict(svn_client_conflict_option_id_t *option_id,
                      svn_boolean_t *save_merged,
+                     svn_cl__accept_t *accept_which,
+                     svn_boolean_t *quit,
                      const svn_client_conflict_t *conflict,
-                     svn_cl__interactive_conflict_baton_t *b,
+                     const char *path_prefix,
+                     svn_cmdline_prompt_baton_t *pb,
+                     const char *editor_cmd,
+                     apr_hash_t *config,
                      apr_pool_t *scratch_pool)
 {
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
@@ -736,7 +745,7 @@ handle_text_conflict(svn_client_conflict
                                                 conflict, scratch_pool,
                                                 scratch_pool));
 
-  local_relpath = svn_cl__local_style_skip_ancestor(b->path_prefix,
+  local_relpath = svn_cl__local_style_skip_ancestor(path_prefix,
                                                     local_abspath,
                                                     scratch_pool);
 
@@ -810,15 +819,15 @@ handle_text_conflict(svn_client_conflict
       *next_option++ = "s";
       *next_option++ = NULL;
 
-      SVN_ERR(prompt_user(&opt, conflict_options, options, b->pb, iterpool));
+      SVN_ERR(prompt_user(&opt, conflict_options, options, pb, iterpool));
       if (! opt)
         continue;
 
       if (strcmp(opt->code, "q") == 0)
         {
           *option_id = opt->choice;
-          b->accept_which = svn_cl__accept_postpone;
-          b->quit = TRUE;
+          *accept_which = svn_cl__accept_postpone;
+          *quit = TRUE;
           break;
         }
       else if (strcmp(opt->code, "s") == 0)
@@ -845,8 +854,8 @@ handle_text_conflict(svn_client_conflict
               continue;
             }
           SVN_ERR(show_conflicts(conflict,
-                                 b->pb->cancel_func,
-                                 b->pb->cancel_baton,
+                                 pb->cancel_func,
+                                 pb->cancel_baton,
                                  iterpool));
           knows_something = TRUE;
         }
@@ -861,14 +870,15 @@ handle_text_conflict(svn_client_conflict
               continue;
             }
 
-          SVN_ERR(show_diff(conflict, merged_abspath, b->path_prefix,
-                            b->pb->cancel_func, b->pb->cancel_baton,
+          SVN_ERR(show_diff(conflict, merged_abspath, path_prefix,
+                            pb->cancel_func, pb->cancel_baton,
                             iterpool));
           knows_something = TRUE;
         }
       else if (strcmp(opt->code, "e") == 0 || strcmp(opt->code, ":-E") == 0)
         {
-          SVN_ERR(open_editor(&performed_edit, merged_abspath, b, iterpool));
+          SVN_ERR(open_editor(&performed_edit, merged_abspath, editor_cmd,
+                              config, iterpool));
           if (performed_edit)
             knows_something = TRUE;
         }
@@ -890,7 +900,7 @@ handle_text_conflict(svn_client_conflict
                                               their_abspath,
                                               my_abspath,
                                               merged_abspath,
-                                              local_abspath, b->config,
+                                              local_abspath, config,
                                               NULL, iterpool);
           if (err)
             {
@@ -906,11 +916,11 @@ handle_text_conflict(svn_client_conflict
                                              my_abspath,
                                              merged_abspath,
                                              local_abspath,
-                                             b->path_prefix,
-                                             b->editor_cmd,
-                                             b->config,
-                                             b->pb->cancel_func,
-                                             b->pb->cancel_baton,
+                                             path_prefix,
+                                             editor_cmd,
+                                             config,
+                                             pb->cancel_func,
+                                             pb->cancel_baton,
                                              iterpool));
                   knows_something = !remains_in_conflict;
                 }
@@ -955,7 +965,7 @@ handle_text_conflict(svn_client_conflict
                                                   my_abspath,
                                                   merged_abspath,
                                                   local_abspath,
-                                                  b->config, NULL, iterpool);
+                                                  config, NULL, iterpool);
               if (err && (err->apr_err == SVN_ERR_CL_NO_EXTERNAL_MERGE_TOOL ||
                           err->apr_err == SVN_ERR_EXTERNAL_PROGRAM))
                 {
@@ -986,11 +996,11 @@ handle_text_conflict(svn_client_conflict
                                      my_abspath,
                                      merged_abspath,
                                      local_abspath,
-                                     b->path_prefix,
-                                     b->editor_cmd,
-                                     b->config,
-                                     b->pb->cancel_func,
-                                     b->pb->cancel_baton,
+                                     path_prefix,
+                                     editor_cmd,
+                                     config,
+                                     pb->cancel_func,
+                                     pb->cancel_baton,
                                      iterpool));
 
           if (!remains_in_conflict)
@@ -1040,8 +1050,13 @@ handle_text_conflict(svn_client_conflict
 static svn_error_t *
 handle_prop_conflict(svn_client_conflict_option_id_t *option_id,
                      const svn_string_t **merged_value,
+                     svn_cl__accept_t *accept_which,
+                     svn_boolean_t *quit,
+                     const char *path_prefix,
+                     svn_cmdline_prompt_baton_t *pb,
+                     const char *editor_cmd,
+                     apr_hash_t *config,
                      const svn_client_conflict_t *conflict,
-                     svn_cl__interactive_conflict_baton_t *b,
                      apr_pool_t *result_pool,
                      apr_pool_t *scratch_pool)
 {
@@ -1062,7 +1077,7 @@ handle_prop_conflict(svn_client_conflict
                                 " on '%s'.\n"),
                               svn_client_conflict_prop_get_propname(conflict),
                               svn_cl__local_style_skip_ancestor(
-                                b->path_prefix,
+                                path_prefix,
                                 svn_client_conflict_get_local_abspath(conflict),
                                 scratch_pool)));
 
@@ -1091,7 +1106,7 @@ handle_prop_conflict(svn_client_conflict
 
       svn_pool_clear(iterpool);
 
-      SVN_ERR(prompt_user(&opt, prop_conflict_options, options, b->pb,
+      SVN_ERR(prompt_user(&opt, prop_conflict_options, options, pb,
                           iterpool));
       if (! opt)
         continue;
@@ -1099,22 +1114,23 @@ handle_prop_conflict(svn_client_conflict
       if (strcmp(opt->code, "q") == 0)
         {
           *option_id = opt->choice;
-          b->accept_which = svn_cl__accept_postpone;
-          b->quit = TRUE;
+          *accept_which = svn_cl__accept_postpone;
+          *quit = TRUE;
           break;
         }
       else if (strcmp(opt->code, "dc") == 0)
         {
           SVN_ERR(show_prop_conflict(base_propval, my_propval, their_propval,
                                      merged_propval,
-                                     b->pb->cancel_func, b->pb->cancel_baton,
+                                     pb->cancel_func, pb->cancel_baton,
                                      scratch_pool));
         }
       else if (strcmp(opt->code, "e") == 0)
         {
           SVN_ERR(edit_prop_conflict(&merged_propval,
                                      base_propval, my_propval, their_propval,
-                                     b, result_pool, scratch_pool));
+                                     editor_cmd, config, pb,
+                                     result_pool, scratch_pool));
           resolved_allowed = (merged_propval != NULL);
         }
       else if (strcmp(opt->code, "r") == 0)
@@ -1148,8 +1164,11 @@ handle_prop_conflict(svn_client_conflict
  * SCRATCH_POOL is used for temporary allocations. */
 static svn_error_t *
 handle_tree_conflict(svn_client_conflict_option_id_t *option_id,
+                     svn_cl__accept_t *accept_which,
+                     svn_boolean_t *quit,
                      const svn_client_conflict_t *conflict,
-                     svn_cl__interactive_conflict_baton_t *b,
+                     const char *path_prefix,
+                     svn_cmdline_prompt_baton_t *pb,
                      apr_pool_t *scratch_pool)
 {
   const char *readable_desc;
@@ -1166,7 +1185,7 @@ handle_tree_conflict(svn_client_conflict
   SVN_ERR(svn_cmdline_fprintf(
                stderr, scratch_pool,
                _("Tree conflict on '%s'\n   > %s\n"),
-               svn_cl__local_style_skip_ancestor(b->path_prefix,
+               svn_cl__local_style_skip_ancestor(path_prefix,
                  svn_client_conflict_get_local_abspath(conflict), scratch_pool),
                readable_desc));
 
@@ -1231,15 +1250,15 @@ handle_tree_conflict(svn_client_conflict
             }
         }
 
-      SVN_ERR(prompt_user(&opt, tc_opts, NULL, b->pb, iterpool));
+      SVN_ERR(prompt_user(&opt, tc_opts, NULL, pb, iterpool));
       if (! opt)
         continue;
 
       if (strcmp(opt->code, "q") == 0)
         {
           *option_id = opt->choice;
-          b->accept_which = svn_cl__accept_postpone;
-          b->quit = TRUE;
+          *accept_which = svn_cl__accept_postpone;
+          *quit = TRUE;
           break;
         }
       else if (opt->choice != svn_client_conflict_option_undefined)
@@ -1258,12 +1277,19 @@ static svn_error_t *
 conflict_func_interactive(svn_client_conflict_option_id_t *option_id,
                           svn_boolean_t *save_merged,
                           const svn_string_t **merged_propval,
+                          svn_cl__accept_t *accept_which, 
+                          svn_boolean_t *quit,
+                          svn_boolean_t *external_failed,
+                          svn_boolean_t *printed_summary,
                           const svn_client_conflict_t *conflict,
-                          void *baton,
+                          const char *editor_cmd,
+                          apr_hash_t *config,
+                          const char *path_prefix,
+                          svn_cmdline_prompt_baton_t *pb,
+                          svn_cl__conflict_stats_t *conflict_stats,
                           apr_pool_t *result_pool,
                           apr_pool_t *scratch_pool)
 {
-  svn_cl__interactive_conflict_baton_t *b = baton;
   svn_error_t *err;
   const char *base_abspath = NULL;
   const char *my_abspath = NULL;
@@ -1280,7 +1306,7 @@ conflict_func_interactive(svn_client_con
   /* Start out assuming we're going to postpone the conflict. */
   *option_id = svn_client_conflict_option_postpone;
 
-  switch (b->accept_which)
+  switch (*accept_which)
     {
     case svn_cl__accept_invalid:
     case svn_cl__accept_unspecified:
@@ -1310,14 +1336,14 @@ conflict_func_interactive(svn_client_con
     case svn_cl__accept_edit:
       if (merged_abspath)
         {
-          if (b->external_failed)
+          if (*external_failed)
             {
               *option_id = svn_client_conflict_option_postpone;
               return SVN_NO_ERROR;
             }
 
           err = svn_cmdline__edit_file_externally(merged_abspath,
-                                                  b->editor_cmd, b->config,
+                                                  editor_cmd, config,
                                                   scratch_pool);
           if (err && (err->apr_err == SVN_ERR_CL_NO_EXTERNAL_EDITOR ||
                       err->apr_err == SVN_ERR_EXTERNAL_PROGRAM))
@@ -1329,7 +1355,7 @@ conflict_func_interactive(svn_client_con
               SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, "%s\n",
                                           message));
               svn_error_clear(err);
-              b->external_failed = TRUE;
+              *external_failed = TRUE;
             }
           else if (err)
             return svn_error_trace(err);
@@ -1344,7 +1370,7 @@ conflict_func_interactive(svn_client_con
           svn_boolean_t remains_in_conflict;
           const char *local_abspath;
 
-          if (b->external_failed)
+          if (*external_failed)
             {
               *option_id = svn_client_conflict_option_postpone;
               return SVN_NO_ERROR;
@@ -1356,7 +1382,7 @@ conflict_func_interactive(svn_client_con
                                               my_abspath,
                                               merged_abspath,
                                               local_abspath,
-                                              b->config,
+                                              config,
                                               &remains_in_conflict,
                                               scratch_pool);
           if (err && (err->apr_err == SVN_ERR_CL_NO_EXTERNAL_MERGE_TOOL ||
@@ -1368,7 +1394,7 @@ conflict_func_interactive(svn_client_con
               message = svn_err_best_message(err, buf, sizeof(buf));
               SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, "%s\n",
                                           message));
-              b->external_failed = TRUE;
+              *external_failed = TRUE;
               return svn_error_trace(err);
             }
           else if (err)
@@ -1385,10 +1411,10 @@ conflict_func_interactive(svn_client_con
     }
 
   /* Print a summary of conflicts before starting interactive resolution */
-  if (! b->printed_summary)
+  if (! *printed_summary)
     {
-      SVN_ERR(svn_cl__print_conflict_stats(b->conflict_stats, scratch_pool));
-      b->printed_summary = TRUE;
+      SVN_ERR(svn_cl__print_conflict_stats(conflict_stats, scratch_pool));
+      *printed_summary = TRUE;
     }
 
   /* We're in interactive mode and either the user gave no --accept
@@ -1404,14 +1430,19 @@ conflict_func_interactive(svn_client_con
            svn_wc_conflict_action_edit)
        && (svn_client_conflict_get_local_change(conflict) ==
            svn_wc_conflict_reason_edited)))
-    SVN_ERR(handle_text_conflict(option_id, save_merged, conflict, b,
-                                 scratch_pool));
+    SVN_ERR(handle_text_conflict(option_id, save_merged, accept_which,
+                                 quit, conflict, path_prefix, pb,
+                                 editor_cmd, config, scratch_pool));
   else if (svn_client_conflict_get_kind(conflict) ==
            svn_wc_conflict_kind_property)
-    SVN_ERR(handle_prop_conflict(option_id, merged_propval, conflict, b,
+    SVN_ERR(handle_prop_conflict(option_id, merged_propval, accept_which,
+                                 quit, path_prefix, pb,
+                                 editor_cmd, config, conflict,
                                  result_pool, scratch_pool));
   else if (svn_client_conflict_get_kind(conflict) == svn_wc_conflict_kind_tree)
-    SVN_ERR(handle_tree_conflict(option_id, conflict, b, scratch_pool));
+    SVN_ERR(handle_tree_conflict(option_id, accept_which, quit,
+                                 conflict, path_prefix, pb,
+                                 scratch_pool));
 
   else /* other types of conflicts -- do nothing about them. */
     {
@@ -1486,14 +1517,17 @@ svn_cl__conflict_func_interactive(svn_wc
   *result = svn_wc_create_conflict_result(svn_client_conflict_option_postpone,
                                           NULL, result_pool);
   SVN_ERR(conflict_func_interactive(&option_id, &save_merged, &merged_propval,
-                                    conflict, baton,
+                                    &b->accept_which, &b->quit,
+                                    &b->external_failed, &b->printed_summary,
+                                    conflict, b->editor_cmd, b->config,
+                                    b->path_prefix, b->pb, b->conflict_stats,
                                     result_pool, scratch_pool));
   (*result)->choice = conflict_option_id_to_wc_conflict_choice(option_id);
   (*result)->save_merged = save_merged;
   (*result)->merged_value = merged_propval;
 
   /* If we are resolving a conflict, adjust the summary of conflicts. */
-  if ((*result)->choice != svn_client_conflict_option_postpone)
+  if (option_id != svn_client_conflict_option_postpone)
     {
       const char *local_path
         = svn_cl__local_style_skip_ancestor(
@@ -1508,29 +1542,36 @@ svn_cl__conflict_func_interactive(svn_wc
 
 svn_error_t *
 svn_cl__resolve_conflict(svn_boolean_t *resolved,
-                          svn_client_conflict_t *conflict,
-                          svn_client_ctx_t *ctx,
-                          svn_wc_conflict_choice_t conflict_choice,
-                          apr_pool_t *scratch_pool)
+                         svn_cl__accept_t *accept_which,
+                         svn_boolean_t *quit,
+                         svn_boolean_t *external_failed,
+                         svn_boolean_t *printed_summary,
+                         svn_client_conflict_t *conflict,
+                         const char *editor_cmd,
+                         apr_hash_t *config,
+                         const char *path_prefix,
+                         svn_cmdline_prompt_baton_t *pb,
+                         svn_cl__conflict_stats_t *conflict_stats,
+                         svn_client_conflict_option_id_t option_id,
+                         svn_client_ctx_t *ctx,
+                         apr_pool_t *scratch_pool)
 {
-  svn_cl__interactive_conflict_baton_t *b = ctx->conflict_baton2;
+  if (option_id == svn_client_conflict_option_unspecified)
+    SVN_ERR(conflict_func_interactive(&option_id, NULL, NULL,
+                                      accept_which, quit,
+                                      external_failed, printed_summary,
+                                      conflict, editor_cmd, config,
+                                      path_prefix, pb, conflict_stats,
+                                      scratch_pool, scratch_pool));
 
-  if (conflict_choice == svn_wc_conflict_choose_unspecified)
-    {
-      svn_client_conflict_option_id_t option_id;
-
-      SVN_ERR(conflict_func_interactive(&option_id, NULL, NULL, conflict, b,
-                                        scratch_pool, scratch_pool));
-
-      conflict_choice = conflict_option_id_to_wc_conflict_choice(option_id);
-    }
+  SVN_ERR_ASSERT(option_id != svn_client_conflict_option_unspecified);
 
   /* If we are resolving a conflict, adjust the summary of conflicts. */
-  if (conflict_choice != svn_wc_conflict_choose_postpone)
+  if (option_id != svn_client_conflict_option_postpone)
     {
       const char *local_relpath
         = svn_cl__local_style_skip_ancestor(
-            b->path_prefix, svn_client_conflict_get_local_abspath(conflict),
+            path_prefix, svn_client_conflict_get_local_abspath(conflict),
             scratch_pool);
       svn_wc_conflict_kind_t conflict_kind;
       const char *local_abspath;
@@ -1552,7 +1593,7 @@ svn_cl__resolve_conflict(svn_boolean_t *
               conflict_kind == svn_wc_conflict_kind_text,
               conflict_kind == svn_wc_conflict_kind_property ? "" : NULL,
               conflict_kind == svn_wc_conflict_kind_tree,
-              conflict_choice,
+              conflict_option_id_to_wc_conflict_choice(option_id),
               ctx->cancel_func, ctx->cancel_baton,
               ctx->notify_func2, ctx->notify_baton2,
               scratch_pool);
@@ -1564,7 +1605,7 @@ svn_cl__resolve_conflict(svn_boolean_t *
 
       SVN_ERR(err);
     
-      svn_cl__conflict_stats_resolved(b->conflict_stats, local_relpath,
+      svn_cl__conflict_stats_resolved(conflict_stats, local_relpath,
                                       svn_client_conflict_get_kind(conflict));
       *resolved = TRUE;
     }

Modified: subversion/branches/reuse-ra-session/subversion/svn/resolve-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/svn/resolve-cmd.c?rev=1703974&r1=1703973&r2=1703974&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/svn/resolve-cmd.c (original)
+++ subversion/branches/reuse-ra-session/subversion/svn/resolve-cmd.c Sat Sep 19 10:19:47 2015
@@ -43,11 +43,20 @@
 struct conflict_status_walker_baton
 {
   svn_client_ctx_t *ctx;
-  svn_wc_conflict_choice_t conflict_choice;
+  svn_client_conflict_option_id_t option_id;
   svn_wc_notify_func2_t notify_func;
   void *notify_baton;
   svn_boolean_t resolved_one;
   apr_hash_t *resolve_later;
+  svn_cl__accept_t *accept_which;
+  svn_boolean_t *quit;
+  svn_boolean_t *external_failed;
+  svn_boolean_t *printed_summary;
+  const char *editor_cmd;
+  apr_hash_t *config;
+  const char *path_prefix;
+  svn_cmdline_prompt_baton_t *pb;
+  svn_cl__conflict_stats_t *conflict_stats;
 };
 
 /* Implements svn_wc_notify_func2_t to collect new conflicts caused by
@@ -99,8 +108,13 @@ conflict_status_walker(void *baton,
 
   SVN_ERR(svn_client_conflict_get(&conflict, local_abspath, cswb->ctx,
                                   iterpool, iterpool));
-  SVN_ERR(svn_cl__resolve_conflict(&resolved, conflict, cswb->ctx,
-                                   cswb->conflict_choice,
+  SVN_ERR(svn_cl__resolve_conflict(&resolved, cswb->accept_which,
+                                   cswb->quit, cswb->external_failed,
+                                   cswb->printed_summary,
+                                   conflict, cswb->editor_cmd,
+                                   cswb->config, cswb->path_prefix,
+                                   cswb->pb, cswb->conflict_stats,
+                                   cswb->option_id, cswb->ctx,
                                    scratch_pool));
   if (resolved)
     cswb->resolved_one = TRUE;
@@ -114,7 +128,16 @@ static svn_error_t *
 walk_conflicts(svn_client_ctx_t *ctx,
                const char *local_abspath,
                svn_depth_t depth,
-               svn_wc_conflict_choice_t conflict_choice,
+               svn_client_conflict_option_id_t option_id,
+               svn_cl__accept_t *accept_which,
+               svn_boolean_t *quit,
+               svn_boolean_t *external_failed,
+               svn_boolean_t *printed_summary,
+               const char *editor_cmd,
+               apr_hash_t *config,
+               const char *path_prefix,
+               svn_cmdline_prompt_baton_t *pb,
+               svn_cl__conflict_stats_t *conflict_stats,
                apr_pool_t *scratch_pool)
 {
   struct conflict_status_walker_baton cswb;
@@ -125,13 +148,24 @@ walk_conflicts(svn_client_ctx_t *ctx,
     depth = svn_depth_infinity;
 
   cswb.ctx = ctx;
-  cswb.conflict_choice = conflict_choice;
+  cswb.option_id = option_id;
 
   cswb.resolved_one = FALSE;
   cswb.resolve_later = (depth != svn_depth_empty)
                           ? apr_hash_make(scratch_pool)
                           : NULL;
 
+  cswb.accept_which = accept_which;
+  cswb.quit = quit;
+  cswb.external_failed = external_failed;
+  cswb.printed_summary = printed_summary;
+  cswb.editor_cmd = editor_cmd;
+  cswb.config = config;
+  cswb.path_prefix = path_prefix;
+  cswb.pb = pb;
+  cswb.conflict_stats = conflict_stats;
+
+
   /* ### call notify.c code */
   if (ctx->notify_func2)
     ctx->notify_func2(ctx->notify_baton2,
@@ -265,39 +299,53 @@ svn_cl__resolve(apr_getopt_t *os,
                 apr_pool_t *scratch_pool)
 {
   svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
+  svn_cl__conflict_stats_t *conflict_stats =
+    ((svn_cl__cmd_baton_t *) baton)->conflict_stats;
   svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
-  svn_wc_conflict_choice_t conflict_choice;
+  svn_client_conflict_option_id_t option_id;
   svn_error_t *err;
   apr_array_header_t *targets;
+  const char *path_prefix;
   int i;
   apr_pool_t *iterpool;
   svn_boolean_t had_error = FALSE;
+  svn_boolean_t quit = FALSE;
+  svn_boolean_t external_failed = FALSE;
+  svn_boolean_t printed_summary = FALSE;
+  svn_cmdline_prompt_baton_t *pb = apr_palloc(scratch_pool, sizeof(*pb));
+
+  pb->cancel_func = ctx->cancel_func;
+  pb->cancel_baton = ctx->cancel_baton;
+
+  option_id = svn_client_conflict_option_unspecified;
+
+  SVN_ERR(svn_dirent_get_absolute(&path_prefix, "", scratch_pool));
 
   switch (opt_state->accept_which)
     {
     case svn_cl__accept_working:
-      conflict_choice = svn_wc_conflict_choose_merged;
+      option_id = svn_wc_conflict_choose_merged;
       break;
     case svn_cl__accept_base:
-      conflict_choice = svn_wc_conflict_choose_base;
+      option_id = svn_wc_conflict_choose_base;
       break;
     case svn_cl__accept_theirs_conflict:
-      conflict_choice = svn_wc_conflict_choose_theirs_conflict;
+      option_id = svn_wc_conflict_choose_theirs_conflict;
       break;
     case svn_cl__accept_mine_conflict:
-      conflict_choice = svn_wc_conflict_choose_mine_conflict;
+      option_id = svn_wc_conflict_choose_mine_conflict;
       break;
     case svn_cl__accept_theirs_full:
-      conflict_choice = svn_wc_conflict_choose_theirs_full;
+      option_id = svn_wc_conflict_choose_theirs_full;
       break;
     case svn_cl__accept_mine_full:
-      conflict_choice = svn_wc_conflict_choose_mine_full;
+      option_id = svn_wc_conflict_choose_mine_full;
       break;
     case svn_cl__accept_unspecified:
       if (opt_state->non_interactive)
         return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                 _("missing --accept option"));
-      conflict_choice = svn_wc_conflict_choose_unspecified;
+      option_id = svn_wc_conflict_choose_unspecified;
       break;
     default:
       return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
@@ -342,13 +390,23 @@ svn_cl__resolve(apr_getopt_t *os,
 
           SVN_ERR(svn_client_conflict_get(&conflict, local_abspath, ctx,
                                           iterpool, iterpool));
-          err = svn_cl__resolve_conflict(&resolved, conflict, ctx,
-                                         conflict_choice, iterpool);
+          err = svn_cl__resolve_conflict(&resolved,
+                                         &opt_state->accept_which,
+                                         &quit, &external_failed,
+                                         &printed_summary,
+                                         conflict, opt_state->editor_cmd,
+                                         ctx->config, path_prefix,
+                                         pb, conflict_stats,
+                                         option_id, ctx,
+                                         iterpool);
         }
       else
         {
           err = walk_conflicts(ctx, local_abspath, opt_state->depth,
-                               conflict_choice, iterpool);
+                               option_id, &opt_state->accept_which,
+                               &quit, &external_failed, &printed_summary,
+                               opt_state->editor_cmd, ctx->config,
+                               path_prefix, pb, conflict_stats, iterpool);
         }
 
       if (err)

Modified: subversion/branches/reuse-ra-session/subversion/svn/svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/svn/svn.c?rev=1703974&r1=1703973&r2=1703974&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/svn/svn.c (original)
+++ subversion/branches/reuse-ra-session/subversion/svn/svn.c Sat Sep 19 10:19:47 2015
@@ -2793,6 +2793,7 @@ sub_main(int *exit_code, int argc, const
 
   /* Create a client context object. */
   command_baton.opt_state = &opt_state;
+  command_baton.conflict_stats = conflict_stats;
   SVN_ERR(svn_client_create_context2(&ctx, cfg_hash, pool));
   command_baton.ctx = ctx;
 

Modified: subversion/branches/reuse-ra-session/subversion/svnadmin/svnadmin.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/svnadmin/svnadmin.c?rev=1703974&r1=1703973&r2=1703974&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/svnadmin/svnadmin.c (original)
+++ subversion/branches/reuse-ra-session/subversion/svnadmin/svnadmin.c Sat Sep 19 10:19:47 2015
@@ -479,8 +479,12 @@ static const svn_opt_subcommand_desc2_t
 
   {"lstxns", subcommand_lstxns, {0}, N_
    ("usage: svnadmin lstxns REPOS_PATH\n\n"
-    "Print the names of all uncommitted transactions.\n"),
-   {0} },
+    "Print the names of uncommitted transactions. With -rN skip the output\n"
+    "of those that have a base revision more recent than rN.  Transactions\n"
+    "with base revisions much older than HEAD are likely to have been\n"
+    "abandonded and are candidates to be removed.\n"),
+   {'r'},
+   { {'r', "transaction base revision ARG"} } },
 
   {"pack", subcommand_pack, {0}, N_
    ("usage: svnadmin pack REPOS_PATH\n\n"
@@ -1109,8 +1113,7 @@ repos_notify_handler(void *baton,
                                             "%" APR_INT64_T_FMT,
                                             notify->shard);
         svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
-                              _("Packing revision properties"
-                                " in shard %s..."),
+                              _("Packed revision properties in shard %s\n"),
                               shardstr));
         return;
       }
@@ -1121,8 +1124,8 @@ repos_notify_handler(void *baton,
                                             "%" APR_INT64_T_FMT,
                                             notify->shard);
         svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
-                              _("Removing non-packed revision properties"
-                                " in shard %s..."),
+                              _("Removed non-packed revision properties"
+                                " in shard %s\n"),
                               shardstr));
         return;
       }
@@ -1576,21 +1579,46 @@ subcommand_lstxns(apr_getopt_t *os, void
   svn_repos_t *repos;
   svn_fs_t *fs;
   apr_array_header_t *txns;
+  apr_pool_t *iterpool;
+  svn_revnum_t youngest, limit;
   int i;
 
   /* Expect no more arguments. */
   SVN_ERR(parse_args(NULL, os, 0, 0, pool));
+  if (opt_state->end_revision.kind != svn_opt_revision_unspecified)
+    return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                             _("Revision range is not allowed"));
 
   SVN_ERR(open_repos(&repos, opt_state->repository_path, pool));
   fs = svn_repos_fs(repos);
   SVN_ERR(svn_fs_list_transactions(&txns, fs, pool));
 
-  /* Loop, printing revisions. */
+  SVN_ERR(svn_fs_youngest_rev(&youngest, fs, pool));
+  SVN_ERR(get_revnum(&limit, &opt_state->start_revision, youngest, repos,
+                     pool));
+  
+  iterpool = svn_pool_create(pool);
   for (i = 0; i < txns->nelts; i++)
     {
-      SVN_ERR(svn_cmdline_printf(pool, "%s\n",
-                                 APR_ARRAY_IDX(txns, i, const char *)));
+      const char *name = APR_ARRAY_IDX(txns, i, const char *);
+      svn_boolean_t show = TRUE;
+
+      svn_pool_clear(iterpool);
+      if (limit != SVN_INVALID_REVNUM)
+        {
+          svn_fs_txn_t *txn;
+          svn_revnum_t base;
+
+          SVN_ERR(svn_fs_open_txn(&txn, fs, name, iterpool));
+          base = svn_fs_txn_base_revision(txn);
+
+          if (base > limit)
+            show = FALSE;
+        }
+      if (show)
+        SVN_ERR(svn_cmdline_printf(pool, "%s\n", name));
     }
+  svn_pool_destroy(iterpool);
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/reuse-ra-session/subversion/svnbench/null-export-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/svnbench/null-export-cmd.c?rev=1703974&r1=1703973&r2=1703974&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/svnbench/null-export-cmd.c (original)
+++ subversion/branches/reuse-ra-session/subversion/svnbench/null-export-cmd.c Sat Sep 19 10:19:47 2015
@@ -165,6 +165,15 @@ close_file(void *file_baton,
   return SVN_NO_ERROR;
 }
 
+/* Implement svn_write_fn_t, simply counting the incoming data. */
+static svn_error_t *
+file_write_handler(void *baton, const char *data, apr_size_t *len)
+{
+  edit_baton_t *eb = baton;
+  eb->byte_count += *len;
+
+  return SVN_NO_ERROR;
+}
 
 /*** Public Interfaces ***/
 
@@ -198,6 +207,7 @@ bench_null_export(svn_revnum_t *result_r
       svn_client__pathrev_t *loc;
       svn_ra_session_t *ra_session;
       svn_node_kind_t kind;
+      edit_baton_t *eb = baton;
 
       /* Get the RA connection. */
       SVN_ERR(svn_client__ra_session_from_path2(&ra_session, &loc,
@@ -211,6 +221,11 @@ bench_null_export(svn_revnum_t *result_r
         {
           apr_hash_t *props;
 
+          /* Since we don't use the editor, we must count "manually". */
+          svn_stream_t *stream = svn_stream_create(eb, pool);
+          svn_stream_set_write(stream, file_write_handler);
+          eb->file_count++;
+
           /* Since you cannot actually root an editor at a file, we
            * manually drive a few functions of our editor. */
 
@@ -218,8 +233,7 @@ bench_null_export(svn_revnum_t *result_r
            * to the repository. */
           /* ### note: the stream will not be closed */
           SVN_ERR(svn_ra_get_file(ra_session, "", loc->rev,
-                                  svn_stream_empty(pool),
-                                  NULL, &props, pool));
+                                  stream, NULL, &props, pool));
         }
       else if (kind == svn_node_dir)
         {
@@ -268,6 +282,10 @@ bench_null_export(svn_revnum_t *result_r
                                      NULL, pool));
 
           SVN_ERR(reporter->finish_report(report_baton, pool));
+
+          /* We don't receive the "add directory" callback for the starting
+           * node. */
+          eb->dir_count++;
         }
       else if (kind == svn_node_none)
         {

Modified: subversion/branches/reuse-ra-session/subversion/tests/cmdline/merge_automatic_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/tests/cmdline/merge_automatic_tests.py?rev=1703974&r1=1703973&r2=1703974&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/tests/cmdline/merge_automatic_tests.py (original)
+++ subversion/branches/reuse-ra-session/subversion/tests/cmdline/merge_automatic_tests.py Sat Sep 19 10:19:47 2015
@@ -1352,6 +1352,53 @@ def merge_to_copy_and_add(sbox):
                                      'merge', '--reintegrate', '^/A',
                                      sbox.ospath('A3'))
 
+def merge_delete_crlf_file(sbox):
+  "merge the deletion of a strict CRLF file"
+
+  sbox.build()
+
+  sbox.simple_copy('A', 'AA')
+
+  # Let commit fix the eols
+  sbox.simple_add_text('with\rCRLF\rhere!', 'A/crlf')
+  sbox.simple_add_text('with\rnative\r\eol', 'A/native')
+  sbox.simple_add_text('with\rCR\r\eol', 'A/cr')
+  sbox.simple_add_text('with\rLF\r\eol', 'A/lf')
+
+  # And apply the magic property
+  sbox.simple_propset('svn:eol-style', 'CRLF',   'A/crlf')
+  sbox.simple_propset('svn:eol-style', 'native', 'A/native')
+  sbox.simple_propset('svn:eol-style', 'CR',     'A/cr')
+  sbox.simple_propset('svn:eol-style', 'LF',     'A/lf')
+
+  sbox.simple_commit('A') # r2
+
+  # Merge the addition of the files
+  svntest.actions.run_and_verify_svn(None, [],
+                                     'merge', '^/A', sbox.ospath('AA'))
+  sbox.simple_commit('AA') # r3
+
+  sbox.simple_rm('A/D', 'A/mu', 'A/crlf', 'A/native', 'A/cr', 'A/lf')
+  sbox.simple_commit('A') # r4
+
+  sbox.simple_update('') # Make single revision r4
+
+  # And now merge the deletes
+  expected_output = svntest.verify.UnorderedOutput([
+    '--- Merging r3 through r4 into \'%s\':\n' % sbox.ospath('AA'),
+    'D    %s\n' % sbox.ospath('AA/cr'),
+    'D    %s\n' % sbox.ospath('AA/crlf'),
+    'D    %s\n' % sbox.ospath('AA/lf'),
+    'D    %s\n' % sbox.ospath('AA/native'),
+    'D    %s\n' % sbox.ospath('AA/mu'),
+    'D    %s\n' % sbox.ospath('AA/D'),
+    '--- Recording mergeinfo for merge of r3 through r4 into \'%s\':\n'
+                % sbox.ospath('AA'),
+    ' U   %s\n' % sbox.ospath('AA')
+  ])
+  svntest.actions.run_and_verify_svn(expected_output, [],
+                                     'merge', '^/A', sbox.ospath('AA'))
+
 ########################################################################
 # Run the tests
 
@@ -1382,6 +1429,7 @@ test_list = [ None,
               effective_sync_results_in_reintegrate,
               reintegrate_subtree_not_updated,
               merge_to_copy_and_add,
+              merge_delete_crlf_file
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/reuse-ra-session/subversion/tests/cmdline/patch_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/tests/cmdline/patch_tests.py?rev=1703974&r1=1703973&r2=1703974&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/tests/cmdline/patch_tests.py (original)
+++ subversion/branches/reuse-ra-session/subversion/tests/cmdline/patch_tests.py Sat Sep 19 10:19:47 2015
@@ -5620,6 +5620,60 @@ def patch_obstructing_symlink_traversal(
                                        expected_output, expected_disk,
                                        expected_status, expected_skip)
 
+@XFail()
+def patch_binary_file(sbox):
+  "patch a binary file"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  # Make the file binary by putting some non ascii chars inside or propset
+  # will return a warning
+  sbox.simple_append('iota', '\0\202\203\204\205\206\207nsomething\nelse\xFF')
+  sbox.simple_propset('svn:mime-type', 'application/binary', 'iota')
+
+  expected_output = [
+    'Index: svn-test-work/working_copies/patch_tests-57/iota\n',
+    '===================================================================\n',
+    'diff --git a/iota b/iota\n',
+    'GIT binary patch\n',
+    'literal 25\n',
+    'ec$^E#$ShU>qLPeMg|y6^R0Z|S{E|d<JuU!m{s;*G\n',
+    '\n',
+    'literal 48\n',
+    'zc$^E#$ShU>qLPeMg|y6^R0Z|S{E|d<JuZf(=9bpB_PpZ!+|-hc%)E52)STkf{{Wp*\n',
+    'B5)uFa\n',
+    '\n',
+    'Property changes on: iota\n',
+    '___________________________________________________________________\n',
+    'Added: svn:mime-type\n',
+    '## -0,0 +1 ##\n',
+    '+application/binary\n',
+    '\ No newline at end of property\n',
+  ]
+
+  _, diff_output, _ = svntest.actions.run_and_verify_svn(expected_output, [],
+                                                         'diff', '--git',
+                                                         wc_dir)
+
+  sbox.simple_revert('iota')
+
+  tmp = sbox.get_tempname()
+  svntest.main.file_write(tmp, ''.join(diff_output))
+
+  expected_output = wc.State(wc_dir, {
+    'iota'              : Item(status='UU'),
+  })
+  expected_disk = None
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('iota', status='MM')
+  expected_skip = wc.State('', { })
+
+  svntest.actions.run_and_verify_patch(wc_dir, tmp,
+                                       expected_output, expected_disk,
+                                       expected_status, expected_skip)
+
+
 ########################################################################
 #Run the tests
 
@@ -5681,6 +5735,7 @@ test_list = [ None,
               patch_closest,
               patch_symlink_traversal,
               patch_obstructing_symlink_traversal,
+              patch_binary_file,
             ]
 
 if __name__ == '__main__':

Modified: subversion/branches/reuse-ra-session/subversion/tests/cmdline/svntest/main.py
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/tests/cmdline/svntest/main.py?rev=1703974&r1=1703973&r2=1703974&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/tests/cmdline/svntest/main.py (original)
+++ subversion/branches/reuse-ra-session/subversion/tests/cmdline/svntest/main.py Sat Sep 19 10:19:47 2015
@@ -1585,13 +1585,12 @@ class TestSpawningThread(threading.Threa
     args = []
     args.append(str(index))
     args.append('-c')
+    args.append('--set-log-level=%s' % logger.getEffectiveLevel())
     # add some startup arguments from this process
     if options.fs_type:
       args.append('--fs-type=' + options.fs_type)
     if options.test_area_url:
       args.append('--url=' + options.test_area_url)
-    if logger.getEffectiveLevel() <= logging.DEBUG:
-      args.append('-v')
     if options.cleanup:
       args.append('--cleanup')
     if options.enable_sasl:

Modified: subversion/branches/reuse-ra-session/tools/client-side/bash_completion
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/tools/client-side/bash_completion?rev=1703974&r1=1703973&r2=1703974&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/tools/client-side/bash_completion (original)
+++ subversion/branches/reuse-ra-session/tools/client-side/bash_completion Sat Sep 19 10:19:47 2015
@@ -1152,6 +1152,9 @@ _svnadmin ()
 		         --use-pre-commit-hook --use-post-commit-hook \
 		         --bypass-prop-validation -M --memory-cache-size"
 		;;
+	lstxns)
+        	cmdOpts="-r --revision"
+		;;
 	lock|unlock)
 		cmdOpts="--bypass-hooks"
 		;;

Modified: subversion/branches/reuse-ra-session/tools/client-side/svn-mergeinfo-normalizer/analyze-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/tools/client-side/svn-mergeinfo-normalizer/analyze-cmd.c?rev=1703974&r1=1703973&r2=1703974&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/tools/client-side/svn-mergeinfo-normalizer/analyze-cmd.c (original)
+++ subversion/branches/reuse-ra-session/tools/client-side/svn-mergeinfo-normalizer/analyze-cmd.c Sat Sep 19 10:19:47 2015
@@ -40,14 +40,16 @@ svn_min__analyze(apr_getopt_t *os,
 {
   svn_min__cmd_baton_t *cmd_baton = baton;
 
-  /* If no option is given, default to "remove redundant sub-node m/i". */
+  /* If no option is given, default to "remove all you can". */
   if (   !cmd_baton->opt_state->remove_redundants
       && !cmd_baton->opt_state->remove_obsoletes
-      && !cmd_baton->opt_state->combine_ranges)
+      && !cmd_baton->opt_state->combine_ranges
+      && !cmd_baton->opt_state->remove_redundant_misaligned)
     {
       cmd_baton->opt_state->remove_redundants = TRUE;
       cmd_baton->opt_state->remove_obsoletes = TRUE;
       cmd_baton->opt_state->combine_ranges = TRUE;
+      cmd_baton->opt_state->remove_redundant_misaligned = TRUE;
     }
 
   cmd_baton->opt_state->run_analysis = TRUE;

Modified: subversion/branches/reuse-ra-session/tools/client-side/svn-mergeinfo-normalizer/logic.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/tools/client-side/svn-mergeinfo-normalizer/logic.c?rev=1703974&r1=1703973&r2=1703974&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/tools/client-side/svn-mergeinfo-normalizer/logic.c (original)
+++ subversion/branches/reuse-ra-session/tools/client-side/svn-mergeinfo-normalizer/logic.c Sat Sep 19 10:19:47 2015
@@ -752,6 +752,161 @@ remove_overlapping_history(svn_rangelist
   return SVN_NO_ERROR;
 }
 
+/* Show the results of an attempt at "misaligned branch elision".
+ * SOURCE_BRANCH was to be elided because TARGET_BRANCH would cover it all.
+ * There were MISSING revisions exclusively in SOURCE_BRANCH.  OPT_STATE
+ * filters the output and SCRATCH_POOL is used for temporary allocations.
+ */
+static svn_error_t *
+show_misaligned_branch_elision(const char *source_branch,
+                               const char *target_branch,
+                               svn_rangelist_t *missing,
+                               svn_min__opt_state_t *opt_state,
+                               apr_pool_t *scratch_pool)
+{
+  if (opt_state->verbose || opt_state->run_analysis)
+    {
+      if (missing->nelts)
+        {
+          SVN_ERR(svn_cmdline_printf(scratch_pool,
+                        _("    CANNOT elide MISALIGNED branch %s\n"
+                          "        to likely correctly aligned branch %s\n"),
+                                     source_branch, target_branch));
+          SVN_ERR(print_ranges(missing,
+                        _("revisions not merged from likely correctly"
+                          " aligned branch: "),
+                               scratch_pool));
+        }
+      else
+        {
+          SVN_ERR(svn_cmdline_printf(scratch_pool,
+                        _("    elide misaligned branch %s\n"
+                          "        to likely correctly aligned branch %s\n"),
+                                     source_branch, target_branch));
+        }
+    }
+
+  return SVN_NO_ERROR;
+}
+
+/* Search MERGEINFO for branches that are sub-branches of one another.
+ * If exactly one of them shares the base with the FS_PATH to which the m/i
+ * is attached, than this is likely the properly aligned branch while the
+ * others are misaligned.
+ *
+ * Using LOG, determine those misaligned branches whose operative merged
+ * revisions are already covered by the merged revisions of the likely
+ * correctly aligned branch.  In that case, remove those misaligned branch
+ * entries from MERGEINFO.
+ *
+ * OPT_STATE filters the output and SCRATCH_POOL is used for temporaries.
+ */
+static svn_error_t *
+remove_redundant_misaligned_branches(svn_min__log_t *log,
+                                     const char *fs_path,
+                                     svn_mergeinfo_t mergeinfo,
+                                     svn_min__opt_state_t *opt_state,
+                                     apr_pool_t *scratch_pool)
+{
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+  int i, k;
+  const char *base_name = svn_dirent_basename(fs_path, scratch_pool);
+  apr_array_header_t *sorted_mi;
+
+  sorted_mi = svn_sort__hash(mergeinfo,
+                             svn_sort_compare_items_lexically,
+                             scratch_pool);
+
+  for (i = 0; i < sorted_mi->nelts - 1; i = k)
+    {
+      const char *item_path, *sub_item_path;
+      int maybe_aligned_index = -1;
+      int maybe_aligned_found = 0;
+      int sub_branch_count = 0;
+
+      svn_pool_clear(iterpool);
+
+      /* Find the range of branches that are sub-branches of the one at I. */
+      item_path = APR_ARRAY_IDX(sorted_mi, i, svn_sort__item_t).key;
+      if (!strcmp(base_name, svn_dirent_basename(item_path, iterpool)))
+        {
+          maybe_aligned_index = i;
+          maybe_aligned_found = 1;
+        }
+
+      for (k = i + 1; k < sorted_mi->nelts; ++k)
+        {
+          sub_item_path = APR_ARRAY_IDX(sorted_mi, k, svn_sort__item_t).key;
+          if (!svn_dirent_is_ancestor(item_path, sub_item_path))
+            break;
+
+          if (!strcmp(base_name,
+                      svn_dirent_basename(sub_item_path, iterpool)))
+            {
+              maybe_aligned_index = k;
+              maybe_aligned_found++;
+            }
+        }
+
+      /* Found any?  If so, did we identify exactly one of them as likely
+       * being properly aligned? */
+      sub_branch_count = k - i - 1;
+      if ((maybe_aligned_found != 1) || (sub_branch_count == 0))
+        continue;
+
+      /* Try to elide all misaligned branches individually. */
+      for (k = i; k < i + sub_branch_count + 1; ++k)
+        {
+          svn_sort__item_t *source_item, *target_item;
+          svn_rangelist_t *missing, *dummy;
+
+          /* Is this one of the misaligned branches? */
+          if (k == maybe_aligned_index)
+            continue;
+
+          source_item = &APR_ARRAY_IDX(sorted_mi, k, svn_sort__item_t);
+          target_item = &APR_ARRAY_IDX(sorted_mi, maybe_aligned_index,
+                                       svn_sort__item_t);
+
+          /* Elide into sub-branch or parent branch (can't be equal here).
+           * Because we only know these are within the I tree, source and
+           * target may be siblings.  Check that they actually have an
+           * ancestor relationship.
+           */
+          if (k < maybe_aligned_index)
+            {
+              if (!svn_dirent_is_ancestor(source_item->key, target_item->key))
+                continue;
+            }
+          else
+            {
+              if (!svn_dirent_is_ancestor(target_item->key, source_item->key))
+                continue;
+            }
+
+          /* Determine which revisions are MISSING in target. */
+          SVN_ERR(svn_rangelist_diff(&missing, &dummy,
+                                     source_item->value, target_item->value,
+                                     TRUE, iterpool));
+          missing = svn_min__operative(log, source_item->key, missing,
+                                       iterpool);
+
+          /* Show the result and elide the branch if we can. */
+          SVN_ERR(show_misaligned_branch_elision(source_item->key,
+                                                 target_item->key,
+                                                 missing,
+                                                 opt_state,
+                                                 iterpool));
+          if (!missing->nelts)
+            svn_hash_sets(mergeinfo, source_item->key, NULL);
+        }
+    }
+
+  svn_pool_destroy(iterpool);
+
+  return SVN_NO_ERROR;
+}
+
 /* Try to elide as many lines from SUBTREE_MERGEINFO for node at FS_PATH as
  * possible using LOG and LOOKUP.  OPT_STATE determines if we may remove
  * deleted branches.  Elision happens by comparing the node's mergeinfo
@@ -1274,7 +1429,15 @@ normalize(apr_array_header_t *wc_mergein
       SVN_ERR(show_elision_header(parent_path, relpath, opt_state,
                                   scratch_pool));
 
-      /* Modify the mergeinfo here. */
+      /* Get rid of some of the easier cases of misaligned branches.
+       * Directly modify the orignal mergeinfo. */
+      if (opt_state->remove_redundant_misaligned)
+        SVN_ERR(remove_redundant_misaligned_branches(log, fs_path,
+                                                     subtree_mergeinfo,
+                                                     opt_state, iterpool));
+
+      /* Modify this copy of the mergeinfo.
+       * If we can elide it all, drop the original. */
       subtree_mergeinfo_copy = svn_mergeinfo_dup(subtree_mergeinfo,
                                                  iterpool);
 

Modified: subversion/branches/reuse-ra-session/tools/client-side/svn-mergeinfo-normalizer/mergeinfo-normalizer.h
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/tools/client-side/svn-mergeinfo-normalizer/mergeinfo-normalizer.h?rev=1703974&r1=1703973&r2=1703974&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/tools/client-side/svn-mergeinfo-normalizer/mergeinfo-normalizer.h (original)
+++ subversion/branches/reuse-ra-session/tools/client-side/svn-mergeinfo-normalizer/mergeinfo-normalizer.h Sat Sep 19 10:19:47 2015
@@ -67,6 +67,7 @@ typedef struct svn_min__opt_state_t
   svn_boolean_t remove_obsoletes;
   svn_boolean_t combine_ranges;
   svn_boolean_t remove_redundants;
+  svn_boolean_t remove_redundant_misaligned;
   svn_boolean_t run_analysis;
 
   /* trust server SSL certs that would otherwise be rejected as "untrusted" */

Modified: subversion/branches/reuse-ra-session/tools/client-side/svn-mergeinfo-normalizer/normalize-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/tools/client-side/svn-mergeinfo-normalizer/normalize-cmd.c?rev=1703974&r1=1703973&r2=1703974&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/tools/client-side/svn-mergeinfo-normalizer/normalize-cmd.c (original)
+++ subversion/branches/reuse-ra-session/tools/client-side/svn-mergeinfo-normalizer/normalize-cmd.c Sat Sep 19 10:19:47 2015
@@ -43,7 +43,8 @@ svn_min__normalize(apr_getopt_t *os,
   /* If no option is given, default to "remove redundant sub-node m/i". */
   if (   !cmd_baton->opt_state->remove_redundants
       && !cmd_baton->opt_state->remove_obsoletes
-      && !cmd_baton->opt_state->combine_ranges)
+      && !cmd_baton->opt_state->combine_ranges
+      && !cmd_baton->opt_state->remove_redundant_misaligned)
     cmd_baton->opt_state->remove_redundants = TRUE;
 
   SVN_ERR(svn_min__run_normalize(baton, pool));

Modified: subversion/branches/reuse-ra-session/tools/client-side/svn-mergeinfo-normalizer/svn-mergeinfo-normalizer.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/tools/client-side/svn-mergeinfo-normalizer/svn-mergeinfo-normalizer.c?rev=1703974&r1=1703973&r2=1703974&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/tools/client-side/svn-mergeinfo-normalizer/svn-mergeinfo-normalizer.c (original)
+++ subversion/branches/reuse-ra-session/tools/client-side/svn-mergeinfo-normalizer/svn-mergeinfo-normalizer.c Sat Sep 19 10:19:47 2015
@@ -88,6 +88,7 @@ typedef enum svn_min__longopt_t {
   opt_remove_obsoletes,
   opt_remove_redundant,
   opt_combine_ranges,
+  opt_remove_redundant_misaligned
 } svn_cl__longopt_t;
 
 
@@ -177,6 +178,10 @@ const apr_getopt_option_t svn_min__optio
                        N_("Remove mergeinfo on sub-nodes if it is\n"
                        "                             "
                        "redundant with the parent mergeinfo.")},
+  {"remove-redundant-misaligned", opt_remove_redundant_misaligned, 0,
+                       N_("Remove mergeinfo of a misaligned branch if it\n"
+                       "                             "
+                       "is already covered by a correctly aligned one.\n")},
   {"combine-ranges",   opt_combine_ranges, 0,
                        N_("Try to combine adjacent revision ranges\n"
                        "                             "
@@ -238,14 +243,16 @@ const svn_opt_subcommand_desc2_t svn_min
      "  branches.\n"
     ),
     {opt_targets, opt_depth, 'v',
-     opt_remove_obsoletes, opt_remove_redundant, opt_combine_ranges} },
+     opt_remove_obsoletes, opt_remove_redundant,
+     opt_remove_redundant_misaligned, opt_combine_ranges} },
 
   { "normalize", svn_min__normalize, { 0 }, N_
     ("Normalize / reduce the mergeinfo throughout the working copy sub-tree.\n"
      "usage: normalize [WCPATH...]\n"
      "\n"
-     "  If neither --remove-obsoletes, --remove-redundant nor --combine-ranges\n"
-     "  option is given, --remove-redundant will be used implicitly.\n"
+     "  If neither --remove-obsoletes, --remove-redundant, --combine-ranges\n"
+     "  nor --remove-redundant-misaligned option is given, --remove-redundant\n"
+     "  will be used implicitly.\n"
      "\n"
      "  In non-verbose mode, only general progress as well as a summary before\n"
      "  and after the normalization process will be shown.  Note that sub-node\n"
@@ -278,6 +285,9 @@ const svn_opt_subcommand_desc2_t svn_min
      "                             mergeinfo because they did not change it.\n"
      "    remove deleted branch  - The branch no longer exists in the repository.\n"
      "                             We will remove its mergeinfo line.\n"
+     "    elide misaligned branch- All revisions merged from that misaligned\n"
+     "                             branch have also been merged from the likely\n"
+     "                             correctly aligned branch.\n"
      "    CANNOT elide branch    - Mergeinfo differs from parent's significantly\n"
      "                             and can't be elided because ...\n"
      "      revisions not movable to parent\n"
@@ -300,6 +310,12 @@ const svn_opt_subcommand_desc2_t svn_min
      "    MISSING in parent      - The branch for the parent node exists in the\n"
      "                             repository but is not in its mergeinfo.\n"
      "                             The sub-tree mergeinfo will not be elided.\n"
+     "    CANNOT elide MISALIGNED branch\n"
+     "                             The misaligned branch cannot be elide because\n"
+     "                             the revisions listed ...\n"
+     "      revisions not merged from likely correctly aligned branch\n"
+     "                             ... here have not also been merged from the\n"
+     "                             likely correctly aligned branch.\n"
      "    MISALIGNED branch      - There is no such branch for the parent node.\n"
      "                             The sub-tree mergeinfo cannot be elided.\n"
      "    REVERSE RANGE(S) found - The mergeinfo contains illegal reverse ranges.\n"
@@ -310,7 +326,8 @@ const svn_opt_subcommand_desc2_t svn_min
      "  branches will be removed.  In verbose mode, a list of branches that\n"
      "  could not be removed will be shown per node.\n"),
     {opt_targets, opt_depth, opt_dry_run, 'q', 'v',
-     opt_remove_obsoletes, opt_remove_redundant, opt_combine_ranges} },
+     opt_remove_obsoletes, opt_remove_redundant,
+     opt_remove_redundant_misaligned, opt_combine_ranges} },
 
   { "remove-branches", svn_min__remove_branches, { 0 }, N_
     ("Read a list of branch names from the given file and remove all\n"
@@ -565,6 +582,9 @@ sub_main(int *exit_code, int argc, const
       case opt_combine_ranges:
         opt_state.combine_ranges = TRUE;
         break;
+      case opt_remove_redundant_misaligned:
+        opt_state.remove_redundant_misaligned = TRUE;
+        break;
 
       default:
         /* Hmmm. Perhaps this would be a good place to squirrel away




Mime
View raw message