You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2012/02/17 11:52:41 UTC

svn commit: r1245385 [4/5] - in /subversion/branches/1.7.x-r1210147: ./ contrib/server-side/mod_dontdothat/ notes/api-errata/1.7/ subversion/bindings/javahl/src/org/apache/subversion/javahl/ subversion/bindings/javahl/tests/org/apache/subversion/javahl...

Modified: subversion/branches/1.7.x-r1210147/subversion/svn/main.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1210147/subversion/svn/main.c?rev=1245385&r1=1245384&r2=1245385&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1210147/subversion/svn/main.c (original)
+++ subversion/branches/1.7.x-r1210147/subversion/svn/main.c Fri Feb 17 10:52:38 2012
@@ -662,267 +662,330 @@ const svn_opt_subcommand_desc2_t svn_cl_
      {'c', N_("the change made in revision ARG")}} },
 
   { "merge", svn_cl__merge, {0}, N_
-    ("Apply the differences between two sources to a working copy path.\n"
-     "usage: 1. merge [-c M[,N...] | -r N:M ...] SOURCE[@REV] [TARGET_WCPATH]\n"
-     "       2. merge --reintegrate SOURCE[@REV] [TARGET_WCPATH]\n"
-     "       3. merge SOURCE1[@N] SOURCE2[@M] [TARGET_WCPATH]\n"
-     "\n"
-     "  1. The first form is called a \"sync\", or \"cherry-pick\", merge:\n"
-     "     svn merge [-c M[,N...] | -r N:M ...] SOURCE[@REV] [TARGET_WCPATH]\n"
-     "\n"
-     "     A sync merge is used to merge into a branch any unmerged changes\n"
-     "     made on its immediate ancestor branch.\n"
-     "\n"
-     "     A cherry-picking merge is used to merge specific revisions from\n"
-     "     one branch to another.\n"
-     "\n"
-     "     SOURCE is usually a URL. The source of a cherry-picking merge can\n"
-     "     also be a working copy path, in which case the corresponding URL\n"
-     "     of the path is used.\n"
-     "\n"
-     "     If REV is specified, it is used as the peg revision for SOURCE,\n"
-     "     i.e. SOURCE is looked up in the repository at revision REV.\n"
-     "     If REV is not specified, the HEAD revision is assumed.\n"
-     "\n"
-     "     TARGET_WCPATH is a working copy of the branch the changes will\n"
-     "     be applied to.\n"
-     "\n"
-     "     '-r N:M' specifies a revision range to be merged. The difference\n"
-     "     between SOURCE@REV as it existed at revision N, and SOURCE@REV at\n"
-     "     it existed at revision M, is merged into TARGET_WCPATH.  If no\n"
-     "     revision range is specified, the default range of 0:REV is used.\n"
-     "     \n"
-     "     If mergeinfo within TARGET_WCPATH indicates that revisions within\n"
-     "     the range were already merged, changes made in those revisions\n"
-     "     are not merged again. If needed, the range is broken into multiple\n"
-     "     sub-ranges, and each sub-range is merged separately.\n"
-     "\n"
-     "     If N is greater than M, the range is a \"reverse range\".\n"
-     "     A reverse range can be used to undo changes made to SOURCE\n"
-     "     between revisions N and M.\n"
-     "\n"
-     "     '-c M' is equivalent to the range '-r <M-1>:M'.\n"
-     "     '-c -M' does the reverse: '-r M:<M-1>'.\n"
-     "     \n"
-     "     Multiple '-c' and/or '-r' options may be specified and mixing of\n"
-     "     forward and reverse ranges is allowed.\n"
-     "\n"
-     "       - Sync Merge Example -\n"
-     "\n"
-     "     A feature is being developed on a branch called \"feature\".\n"
-     "     The feature branch is regularly synced with trunk to keep up with\n"
-     "     changes made there.\n"
-     "\n"
-     "                 feature  +------------------------o-----\n"
-     "                         /                         ^\n"
-     "                        /                         /\n"
-     "                       /          .............../\n"
-     "         trunk ------+------------L--------------R------\n"
-     "                                r100           r200\n"
-     "     \n"
-     "     In the above diagram, L marks the \"left\" side of the merge\n"
-     "     (trunk@100), and R marks the \"right\" side of the merge (trunk@200).\n"
-     "     The difference between the left and right side is merged into the target.\n"
-     "\n"
-     "     To perform the merge, check out a working copy of the feature\n"
-     "     branch and run the following command in the top-level directory\n"
-     "     of the working copy:\n"
-     "\n"
-     "         svn merge ^/trunk\n"
-     "\n"
-     "     The default revision range is -r0:HEAD, so any unmerged changes\n"
-     "     will be merged.\n"
-     "\n"
-     "       - Cherry-picking Merge Example -\n"
-     "\n"
-     "     A bug has been fixed on trunk on revision 50. This fix needs to\n"
-     "     be merged from the trunk into the release branch.\n"
-     "\n"
-     "            1.x-release  +-----------------------o-----\n"
-     "                        /                        ^\n"
-     "                       /                         |\n"
-     "                      /                          |\n"
-     "         trunk ------+--------------------------LR-----\n"
-     "                                                r50\n"
-     "     \n"
-     "     In the above diagram, L marks the left side of the merge (trunk@49)\n"
-     "     and R marks the right side of the merge (trunk@50).\n"
-     "     The difference between the left and right side is merged into the target.\n"
-     "\n"
-     "     To perform the merge, check out a working copy of the release\n"
-     "     branch and run the following command in the top-level directory\n"
-     "     of the working copy:\n"
-     "\n"
-     "         svn merge -c50 ^/trunk\n"
-     "\n"
-     "     If several commits to trunk were related to the fix, multiple\n"
-     "     revisions can be merged:\n"
-     "\n"
-     "         svn merge -c50,54,60 ^/trunk\n"
-     "\n"
-     "\n"
-     "  2. The second form is called a \"reintegrate merge\":\n"
-     "     svn merge --reintegrate SOURCE[@REV] [TARGET_WCPATH]\n"
-     "\n"
-     "     SOURCE is the URL of a branch to be merged back into (usually) its\n"
-     "     immediate ancestor branch.  If REV is specified, it is used a\n"
-     "     the peg revision for SOURCE, i.e. SOURCE is looked up in the\n"
-     "     repository at revision REV.  If REV is not specified, the HEAD\n"
-     "     revision is assumed.\n"
-     "\n"
-     "     TARGET_WCPATH is a working copy of the branch the changes will\n"
-     "     be applied to.\n"
-     "\n"
-     "       - Reintegrate Merge Example -\n"
-     "\n"
-     "     A feature has been developed on a branch called \"feature\".\n"
-     "     The feature branch started as a copy of trunk@W. Work on the\n"
-     "     feature has completed and it should be merged back into the trunk.\n"
-     "     \n"
-     "     The feature branch was last synced with its immediate ancestor,\n"
-     "     the trunk, in revision X. So the difference between trunk@X and\n"
-     "     feature@HEAD contains the complete set of changes that implement\n"
-     "     the feature, and no other changes. These changes are applied to\n"
-     "     the trunk.\n"
-     "\n"
-     "                 feature  +-------------------------------R\n"
-     "                         /                               . \\\n"
-     "                        /                  ..............   \\\n"
-     "                       /                  .                  v\n"
-     "         trunk ------+--------------------L------------------o\n"
-     "                    rW                   rX\n"
-     "\n"
-     "     In the diagram above, L marks the left side of the merge (trunk@X),\n"
-     "     and R marks the right side of the merge (feature@HEAD). The difference\n"
-     "     between the left and right side is merged into the target.\n"
-     "\n"
-     "     To perform the merge, check out a working copy of the trunk, and run\n"
-     "     the following command in the top-level directory of the working copy:\n"
-     "\n"
-     "         svn merge --reintegrate ^/feature\n"
-     "\n"
-     "     To prevent unnecessary merge conflicts, reintegrate merges require\n"
-     "     that TARGET_WCPATH is not a mixed-revision working copy, has no\n"
-     "     local modifications, and has no switched subtrees.\n"
-     "\n"
-     "     Reintegrate merges also require that the reintegrate source be fully\n"
-     "     synced with the target since their common branch point.\n"
-     "     In the above example this means that all of the changes made\n"
-     "     on trunk between revision W and revision X are fully merged to\n"
-     "     the feature branch before it can be reintegrated back to trunk.\n"
-     "\n"
-     "     After the reintegrate merge, the feature branch cannot be synced\n"
-     "     to the trunk again without merge conflicts. If further work must\n"
-     "     be done on the feature branch, it should be deleted and then re-created.\n"
-     "\n"
-     "\n"
-     "  3. The third form is called a \"2-URL merge\":\n"
-     "     svn merge SOURCE1[@N] SOURCE2[@M] [TARGET_WCPATH]\n"
-     "\n"
-     "     Two source URLs are specified, together with two revisions N and M.\n"
-     "     The two sources to be compared at the specified revisions, and the\n"
-     "     difference is applied to TARGET_WCPATH, which is a path to a working\n"
-     "     copy of another branch.\n"
-     "\n"
-     "     The revisions default to HEAD if omitted.\n"
-     "\n"
-     "     If TARGET_WCPATH is omitted, a default value of '.' is assumed,\n"
-     "     unless the sources have identical basenames that match a file\n"
-     "     within '.'; In which case, the differences will be applied to\n"
-     "     that file.\n"
-     "\n"
-     "     The sources can also be specified as working copy paths, in which\n"
-     "     case the URLs of the merge sources are derived from the working copies.\n"
-     "\n"
-     "     This is the most flexible type of merge, but also the most difficult\n"
-     "     to use. It can be used to merge the differences between two (possibly\n"
-     "     ancestrally unrelated) branches into a working copy of another branch.\n"
-     "     This type of merge should be used very carefully because the probability\n"
-     "     of merge conflicts is quite high. In most use cases, a sync, cherry-pick,\n"
-     "     or reintegrate merge is sufficient and reduces the chances of mistakes.\n"
-     "\n"
-     "       - 2-URL Merge Example -\n"
-     "\n"
-     "     A feature has been developed on a branch called \"feature\".\n"
-     "     Development for the upcoming 3.0 release has happened in parallel on\n"
-     "     the \"3.x-release\" branch. The work on the feature branch must be\n"
-     "     merged to the 3.x-release branch. However, the feature branch and\n"
-     "     the 3.x-release branch are not directly related, so a 2-URL merge\n"
-     "     is needed.\n"
-     "     The feature branch was last synced with its immediate ancestor,\n"
-     "     the trunk, up to revision 500. So the difference between trunk@500\n"
-     "     and feature@HEAD contains the complete set of changes related to\n"
-     "     the feature, and no other changes. These changes are applied to\n"
-     "     the 3.x-release branch.\n"
-     "\n"
-     "                   3.x-release  +-----------------------------------o\n"
-     "                               /                                    ^\n"
-     "                              /                                    /\n"
-     "                             /              r500                  /\n"
-     "         trunk ------+------+-----------------L--------->        /\n"
-     "                      \\                         .               /\n"
-     "                       \\                         ...........   /\n"
-     "                        \\                                   . /\n"
-     "                feature  +-----------------------------------R\n"
-     "\n"
-     "     In the diagram above, L marks the left side of the merge (trunk@500),\n"
-     "     and R marks the right side of the merge is (feature@HEAD).\n"
-     "     The difference between the left and right side is merged into the target.\n"
-     "\n"
-     "     To perform the merge, check out a working copy of the 3.x-release\n"
-     "     branch and run the following command in the top-level directory\n"
-     "     of the working copy:\n"
-     "       \n"
-     "         svn merge ^/trunk@500 ^/feature\n"
-     "\n"
-     "     Before performing a 2-URL merge, it is a good idea to preview the\n"
-     "     changes which will be merged, because there is no guarantee that\n"
-     "     the merge will be free of conflicts. The preview can be done with\n"
-     "     the svn diff command:\n"
-     "\n"
-     "         svn diff ^/trunk@500 ^/feature@HEAD\n"
-     "\n"
-     "     Note that a 2-URL merge can also merge from foreign repositories.\n"
-     "     While SOURCE1 and SOURCE2 must both come from the same repository,\n"
-     "     TARGET_WCPATH may come from a different repository than the sources.\n"
-     "     However, there are some caveats. Most notably, copies made in the\n"
-     "     merge source will be transformed into plain additions in the merge\n"
-     "     target. Also, merge-tracking is not supported.\n"
-     "\n"
-     "\n"
-     "  The following applies to all types of merges:\n"
-     "\n"
-     "  To prevent unnecessary merge conflicts, svn merge requires that\n"
-     "  TARGET_WCPATH is not a mixed-revision working copy.\n"
-     "  Running 'svn update' before starting a merge ensures that all\n"
-     "  items in the working copy are based on the same revision.\n"
-     "\n"
-     "  For each merged item a line will be printed with characters reporting\n"
-     "  the action taken. These characters have the following meaning:\n"
-     "\n"
-     "    A  Added\n"
-     "    D  Deleted\n"
-     "    U  Updated\n"
-     "    C  Conflict\n"
-     "    G  Merged\n"
-     "    E  Existed\n"
-     "    R  Replaced\n"
-     "\n"
-     "  Characters in the first column report about the item itself.\n"
-     "  Characters in the second column report about properties of the item.\n"
-     "  A 'C' in the third column indicates a tree conflict, while a 'C' in\n"
-     "  the first and second columns indicate textual conflicts in files\n"
-     "  and in property values, respectively.\n"
-     "\n"
-     "  NOTE:  Subversion uses the svn:mergeinfo property to track merge\n"
-     "  history.  This property is considered at the start of a merge to\n"
-     "  determine what to merge and it is updated at the conclusion of the\n"
-     "  merge to describe the merge that took place.  Mergeinfo is used only\n"
-     "  if the two sources are on the same line of history -- if the first\n"
-     "  source is an ancestor of the second, or vice-versa.  This is guaranteed\n"
-     "  to be the case when using sync merges and reintegrate merges.\n"
-     "  The --ignore-ancestry option prevents merge tracking and thus\n"
-     "  ignores mergeinfo, neither considering it nor recording it.\n"),
+    ( /* For this large section, let's keep it unindented for easier
+       * viewing/editing. It has been vim-treated with a textwidth=75 and 'gw'
+       * (with quotes and newlines removed). */
+"Merge changes into a working copy.\n"
+"usage: 1. merge SOURCE[@REV] [TARGET_WCPATH]\n"
+"          (the 'sync' merge)\n"
+"       2. merge [-c M[,N...] | -r N:M ...] SOURCE[@REV] [TARGET_WCPATH]\n"
+"          (the 'cherry-pick' merge)\n"
+"       3. merge --reintegrate SOURCE[@REV] [TARGET_WCPATH]\n"
+"          (the 'reintegrate' merge)\n"
+"       4. merge SOURCE1[@N] SOURCE2[@M] [TARGET_WCPATH]\n"
+"          (the '2-URL' merge)\n"
+"\n"
+"  1. This form is called a 'sync' (or 'catch-up') merge:\n"
+"\n"
+"       svn merge SOURCE[@REV] [TARGET_WCPATH]\n"
+"\n"
+"     A sync merge is used to fetch all the latest changes made on a parent\n"
+"     branch. In other words, the target branch has originally been created\n"
+"     by copying the source branch, and any changes committed on the source\n"
+"     branch since branching are applied to the target branch. This uses\n"
+"     merge tracking to skip all those revisions that have already been\n"
+"     merged, so a sync merge can be repeated periodically to stay up-to-\n"
+"     date with the source branch.\n"
+"\n"
+"     SOURCE specifies the branch from where the changes will be pulled, and\n"
+"     TARGET_WCPATH specifies a working copy of the target branch to which\n"
+"     the changes will be applied. Normally SOURCE and TARGET_WCPATH should\n"
+"     each correspond to the root of a branch. (If you want to merge only a\n"
+"     subtree, then the subtree path must be included in both SOURCE and\n"
+"     TARGET_WCPATH; this is discouraged, to avoid subtree mergeinfo.)\n"
+"\n"
+"     SOURCE is usually a URL. The optional '@REV' specifies both the peg\n"
+"     revision of the URL and the latest revision that will be considered\n"
+"     for merging; if REV is not specified, the HEAD revision is assumed. If\n"
+"     SOURCE is a working copy path, the corresponding URL of the path is\n"
+"     used, and the default value of 'REV' is the base revision (usually the\n"
+"     revision last updated to).\n"
+"\n"
+"     TARGET_WCPATH is a working copy path; if omitted, '.' is assumed.\n"
+"\n"
+"       - Sync Merge Example -\n"
+"\n"
+"     A feature is being developed on a branch called 'feature', which has\n"
+"     originally been a copy of trunk. The feature branch has been regularly\n"
+"     synced with trunk to keep up with the changes made there. The previous\n"
+"     sync merges are not shown on this diagram, and the last of them was\n"
+"     done when HEAD was r100. Currently, HEAD is r200.\n"
+"\n"
+"                feature  +------------------------o-----\n"
+"                        /                         ^\n"
+"                       /            ............  |\n"
+"                      /            .            . /\n"
+"         trunk ------+------------L--------------R------\n"
+"                                r100           r200\n"
+"\n"
+"     Subversion will locate all the changes on 'trunk' that have not yet\n"
+"     been merged into the 'feature' branch. In this case that is a single\n"
+"     range, r100:200. In the diagram above, L marks the left side\n"
+"     (trunk@100) and R marks the right side (trunk@200) of the merge. The\n"
+"     difference between L and R will be applied to the target working copy\n"
+"     path. In this case, the working copy is a clean checkout of the entire\n"
+"     'feature' branch.\n"
+"\n"
+"     To perform this sync merge, have a clean working copy of the feature\n"
+"     branch and run the following command in its top-level directory:\n"
+"\n"
+"         svn merge ^/trunk\n"
+"\n"
+"     Note that the merge is now only in your local working copy and still\n"
+"     needs to be committed to the repository so that it can be seen by\n"
+"     others. You can review the changes and you may have to resolve\n"
+"     conflicts before you commit the merge.\n"
+"\n"
+"\n"
+"  2. This form is called a 'cherry-pick' merge:\n"
+"\n"
+"       svn merge [-c M[,N...] | -r N:M ...] SOURCE[@REV] [TARGET_WCPATH]\n"
+"\n"
+"     A cherry-pick merge is used to merge specific revisions (or revision\n"
+"     ranges) from one branch to another. By default, this uses merge\n"
+"     tracking to automatically skip any revisions that have already been\n"
+"     merged to the target; you can use the --ignore-ancestry option to\n"
+"     disable such skipping.\n"
+"\n"
+"     SOURCE is usually a URL. The optional '@REV' specifies only the peg\n"
+"     revision of the URL and does not affect the merge range; if REV is not\n"
+"     specified, the HEAD revision is assumed. If SOURCE is a working copy\n"
+"     path, the corresponding URL of the path is used, and the default value\n"
+"     of 'REV' is the base revision (usually the revision last updated to).\n"
+"\n"
+"     TARGET_WCPATH is a working copy path; if omitted, '.' is assumed.\n"
+"\n"
+"     The revision ranges to be merged are specified by the '-r' and/or '-c'\n"
+"     options. '-r N:M' refers to the difference in the history of the\n"
+"     source branch between revisions N and M. You can use '-c M' to merge\n"
+"     single revisions: '-c M' is equivalent to '-r <M-1>:M'. Each such\n"
+"     difference is applied to TARGET_WCPATH.\n"
+"\n"
+"     If the mergeinfo in TARGET_WCPATH indicates that revisions within the\n"
+"     range were already merged, changes made in those revisions are not\n"
+"     merged again. If needed, the range is broken into multiple sub-ranges,\n"
+"     and each sub-range is merged separately.\n"
+"\n"
+"     A 'reverse range' can be used to undo changes. For example, when\n"
+"     source and target refer to the same branch, a previously committed\n"
+"     revision can be 'undone'. In a reverse range, N is greater than M in\n"
+"     '-r N:M', or the '-c' option is used with a negative number: '-c -M'\n"
+"     is equivalent to '-r M:<M-1>'.\n"
+"\n"
+"     Multiple '-c' and/or '-r' options may be specified and mixing of\n"
+"     forward and reverse ranges is allowed.\n"
+"\n"
+"       - Cherry-pick Merge Example -\n"
+"\n"
+"     A bug has been fixed on trunk in revision 50. This fix needs to\n"
+"     be merged from trunk onto the release branch.\n"
+"\n"
+"            1.x-release  +-----------------------o-----\n"
+"                        /                        ^\n"
+"                       /                         |\n"
+"                      /                          |\n"
+"         trunk ------+--------------------------LR-----\n"
+"                                                r50\n"
+"\n"
+"     In the above diagram, L marks the left side (trunk@49) and R marks the\n"
+"     right side (trunk@50) of the merge. The difference between the left\n"
+"     and right side is applied to the target working copy path.\n"
+"\n"
+"     Note that the difference between revision 49 and 50 is exactly those\n"
+"     changes that were committed in revision 50, not including changes\n"
+"     committed in revision 49.\n"
+"\n"
+"     To perform the merge, have a clean working copy of the release branch\n"
+"     and run the following command in its top-level directory; remember\n"
+"     that the default target is '.':\n"
+"\n"
+"         svn merge -c50 ^/trunk\n"
+"\n"
+"     You can also cherry-pick several revisions and/or revision ranges:\n"
+"\n"
+"         svn merge -c50,54,60 -r65:68 ^/trunk\n"
+"\n"
+"\n"
+"  3. This form is called a 'reintegrate merge':\n"
+"\n"
+"       svn merge --reintegrate SOURCE[@REV] [TARGET_WCPATH]\n"
+"\n"
+"     In a reintegrate merge, an (e.g. feature) branch is merged back to its\n"
+"     originating branch. In other words, the source branch has originally\n"
+"     been created by copying the target branch, development has concluded\n"
+"     on the source branch and it should now be merged back into the target\n"
+"     branch.\n"
+"     \n"
+"     SOURCE is the URL of a branch to be merged back. If REV is specified,\n"
+"     it is used as the peg revision for SOURCE; if REV is not specified,\n"
+"     the HEAD revision is assumed.\n"
+"\n"
+"     TARGET_WCPATH is a working copy of the branch the changes will be\n"
+"     applied to.\n"
+"\n"
+"       - Reintegrate Merge Example -\n"
+"\n"
+"     A feature has been developed on a branch called 'feature'. The feature\n"
+"     branch started as a copy of trunk@W. Work on the feature has completed\n"
+"     and it should be merged back into the trunk.\n"
+"\n"
+"     The feature branch was last synced with trunk up to revision X. So the\n"
+"     difference between trunk@X and feature@HEAD contains the complete set\n"
+"     of changes that implement the feature, and no other changes. These\n"
+"     changes are applied to trunk.\n"
+"\n"
+"                feature  +--------------------------------R\n"
+"                        /                                . \\\n"
+"                       /                    .............   \\\n"
+"                      /                    .                 v\n"
+"         trunk ------+--------------------L------------------o\n"
+"                    rW                   rX\n"
+"\n"
+"     In the diagram above, L marks the left side (trunk@X) and R marks the\n"
+"     right side (feature@HEAD) of the merge. The difference between the\n"
+"     left and right side is merged into trunk, the target.\n"
+"\n"
+"     To perform the merge, have a clean working copy of trunk and run the\n"
+"     following command in its top-level directory:\n"
+"\n"
+"         svn merge --reintegrate ^/feature\n"
+"\n"
+"     To prevent unnecessary merge conflicts, a reintegrate merge requires\n"
+"     that TARGET_WCPATH is not a mixed-revision working copy, has no local\n"
+"     modifications, and has no switched subtrees.\n"
+"\n"
+"     A reintegrate merge also requires that the source branch is coherently\n"
+"     synced with the target -- in the above example, this means that all\n"
+"     revisions between the branch point W and the last merged revision X\n"
+"     are merged to the feature branch, so that there are no unmerged\n"
+"     revisions in-between.\n"
+"\n"
+"     After the reintegrate merge, the feature branch cannot be synced to\n"
+"     the trunk again without merge conflicts. If further work must be done\n"
+"     on the feature branch, it should be deleted and then re-created.\n"
+"\n"
+"\n"
+"  4. This form is called a '2-URL merge':\n"
+"\n"
+"       svn merge SOURCE1[@N] SOURCE2[@M] [TARGET_WCPATH]\n"
+"\n"
+"     Two source URLs are specified, together with two revisions N and M.\n"
+"     The two sources are compared at the specified revisions, and the\n"
+"     difference is applied to TARGET_WCPATH, which is a path to a working\n"
+"     copy of another branch. The three branches involved can be completely\n"
+"     unrelated.\n"
+"\n"
+"     You should use this merge variant only if the other variants do not\n"
+"     apply to your situation, as this variant can be quite complex to\n"
+"     master.\n"
+"\n"
+"     If TARGET_WCPATH is omitted, a default value of '.' is assumed.\n"
+"     However, in the special case where both sources refer to a file node\n"
+"     with the same basename and a similarly named file is also found within\n"
+"     '.', the differences will be applied to that local file.  The source\n"
+"     revisions default to HEAD if omitted.\n"
+"\n"
+"     The sources can also be specified as working copy paths, in which case\n"
+"     the URLs of the merge sources are derived from the working copies.\n"
+"\n"
+"       - 2-URL Merge Example -\n"
+"\n"
+"     Two features have been developed on separate branches called 'foo' and\n"
+"     'bar'. It has since become clear that 'bar' should be combined with\n"
+"     the 'foo' branch for further development before reintegration.\n"
+"\n"
+"     Although both feature branches originate from trunk, they are not\n"
+"     directly related -- one is not a direct copy of the other. A 2-URL\n"
+"     merge is necessary.\n"
+"\n"
+"     The 'bar' branch has been synced with trunk up to revision 500.\n"
+"     (If this revision number is not known, it can be located using the\n"
+"     'svn log' and/or 'svn mergeinfo' commands.)\n"
+"     The difference between trunk@500 and bar@HEAD contains the complete\n"
+"     set of changes related to feature 'bar', and no other changes. These\n"
+"     changes are applied to the 'foo' branch.\n"
+"\n"
+"                           foo  +-----------------------------------o\n"
+"                               /                                    ^\n"
+"                              /                                    /\n"
+"                             /              r500                  /\n"
+"         trunk ------+------+-----------------L--------->        /\n"
+"                      \\                        .                /\n"
+"                       \\                        ............   /\n"
+"                        \\                                   . /\n"
+"                    bar  +-----------------------------------R\n"
+"\n"
+"     In the diagram above, L marks the left side (trunk@500) and R marks\n"
+"     the right side (bar@HEAD) of the merge. The difference between the\n"
+"     left and right side is applied to the target working copy path, in\n"
+"     this case a working copy of the 'foo' branch.\n"
+"\n"
+"     To perform the merge, have a clean working copy of the 'foo' branch\n"
+"     and run the following command in its top-level directory:\n"
+"\n"
+"         svn merge ^/trunk@500 ^/bar\n"
+"\n"
+"     The exact changes applied by a 2-URL merge can be previewed with svn's\n"
+"     diff command, which is a good idea to verify if you do not have the\n"
+"     luxury of a clean working copy to merge to. In this case:\n"
+"\n"
+"         svn diff ^/trunk@500 ^/bar@HEAD\n"
+"\n"
+"\n"
+"  The following applies to all types of merges:\n"
+"\n"
+"  To prevent unnecessary merge conflicts, svn merge requires that\n"
+"  TARGET_WCPATH is not a mixed-revision working copy. Running 'svn update'\n"
+"  before starting a merge ensures that all items in the working copy are\n"
+"  based on the same revision.\n"
+"\n"
+"  If possible, you should have no local modifications in the merge's target\n"
+"  working copy prior to the merge, to keep things simpler. It will be\n"
+"  easier to revert the merge and to understand the branch's history.\n"
+"\n"
+"  Switched sub-paths should also be avoided during merging, as they may\n"
+"  cause incomplete merges and create subtree mergeinfo.\n"
+"\n"
+"  For each merged item a line will be printed with characters reporting the\n"
+"  action taken. These characters have the following meaning:\n"
+"\n"
+"    A  Added\n"
+"    D  Deleted\n"
+"    U  Updated\n"
+"    C  Conflict\n"
+"    G  Merged\n"
+"    E  Existed\n"
+"    R  Replaced\n"
+"\n"
+"  Characters in the first column report about the item itself.\n"
+"  Characters in the second column report about properties of the item.\n"
+"  A 'C' in the third column indicates a tree conflict, while a 'C' in\n"
+"  the first and second columns indicate textual conflicts in files\n"
+"  and in property values, respectively.\n"
+"\n"
+"    - Merge Tracking -\n"
+"\n"
+"  Subversion uses the svn:mergeinfo property to track merge history. This\n"
+"  property is considered at the start of a merge to determine what to merge\n"
+"  and it is updated at the conclusion of the merge to describe the merge\n"
+"  that took place. Mergeinfo is used only if the two sources are on the\n"
+"  same line of history -- if the first source is an ancestor of the second,\n"
+"  or vice-versa (i.e. if one has originally been created by copying the\n"
+"  other). This is verified and enforced when using sync merges and\n"
+"  reintegrate merges.\n"
+"\n"
+"  The --ignore-ancestry option prevents merge tracking and thus ignores\n"
+"  mergeinfo, neither considering it nor recording it.\n"
+"\n"
+"    - Merging from foreign repositories -\n"
+"\n"
+"  Subversion does support merging from foreign repositories.\n"
+"  While all merge source URLs must point to the same repository, the merge\n"
+"  target working copy may come from a different repository than the source.\n"
+"  However, there are some caveats. Most notably, copies made in the\n"
+"  merge source will be transformed into plain additions in the merge\n"
+"  target. Also, merge-tracking is not supported for merges from foreign\n"
+"  repositories.\n"),
     {'r', 'c', 'N', opt_depth, 'q', opt_force, opt_dry_run, opt_merge_cmd,
      opt_record_only, 'x', opt_ignore_ancestry, opt_accept, opt_reintegrate,
      opt_allow_mixed_revisions} },
@@ -1158,7 +1221,7 @@ const svn_opt_subcommand_desc2_t svn_cl_
      "     complete old and new URLs if you wish.)  Use 'svn info' to determine\n"
      "     the current working copy URL.\n"
      "\n"
-     "  2. TO-URL is the (complete) new repository URL to use for for PATH.\n"
+     "  2. TO-URL is the (complete) new repository URL to use for PATH.\n"
      "\n"
      "  Examples:\n"
      "    svn relocate http:// svn:// project1 project2\n"

Modified: subversion/branches/1.7.x-r1210147/subversion/svn/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1210147/subversion/svn/status.c?rev=1245385&r1=1245384&r2=1245385&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1210147/subversion/svn/status.c (original)
+++ subversion/branches/1.7.x-r1210147/subversion/svn/status.c Fri Feb 17 10:52:38 2012
@@ -332,7 +332,8 @@ svn_cl__print_status_xml(const char *pat
   const char *local_abspath = status->local_abspath;
   svn_boolean_t tree_conflicted = FALSE;
 
-  if (status->node_status == svn_wc_status_none)
+  if (status->node_status == svn_wc_status_none
+      && status->repos_node_status == svn_wc_status_none)
     return SVN_NO_ERROR;
 
   if (status->conflicted)

Modified: subversion/branches/1.7.x-r1210147/subversion/svnlook/main.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1210147/subversion/svnlook/main.c?rev=1245385&r1=1245384&r2=1245385&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1210147/subversion/svnlook/main.c (original)
+++ subversion/branches/1.7.x-r1210147/subversion/svnlook/main.c Fri Feb 17 10:52:38 2012
@@ -784,18 +784,25 @@ generate_label(const char **label,
    If TOKEN is empty, or is already terminated by an EOL marker,
    return TOKEN unmodified. Else, return a new string consisting
    of the concatenation of TOKEN and the system's default EOL marker.
-   The new string is allocated from POOL. */
+   The new string is allocated from POOL.
+   If HAD_EOL is not NULL, indicate in *HAD_EOL if the token had a EOL. */
 static const svn_string_t *
-maybe_append_eol(const svn_string_t *token, apr_pool_t *pool)
+maybe_append_eol(const svn_string_t *token, svn_boolean_t *had_eol,
+                 apr_pool_t *pool)
 {
   const char *curp;
 
+  if (had_eol)
+    *had_eol = FALSE;
+
   if (token->len == 0)
     return token;
 
   curp = token->data + token->len - 1;
   if (*curp == '\r')
     {
+      if (had_eol)
+        *had_eol = TRUE;
       return token;
     }
   else if (*curp != '\n')
@@ -804,6 +811,8 @@ maybe_append_eol(const svn_string_t *tok
     }
   else
     {
+      if (had_eol)
+        *had_eol = TRUE;
       return token;
     }
 }
@@ -860,19 +869,20 @@ display_prop_diffs(const apr_array_heade
         const svn_string_t *tmp;
         const svn_string_t *orig;
         const svn_string_t *val;
+        svn_boolean_t val_has_eol;
 
         SVN_ERR(svn_stream_for_stdout(&out, pool));
 
         /* The last character in a property is often not a newline.
-           Since the diff is not useful anyway for patching properties an
-           eol character is appended when needed to remove those pescious
-           ' \ No newline at end of file' lines. */
+           An eol character is appended to prevent the diff API to add a
+           ' \ No newline at end of file' line. We add 
+           ' \ No newline at end of property' manually if needed. */
         tmp = orig_value ? orig_value : svn_string_create("", pool);
-        orig = maybe_append_eol(tmp, pool);
+        orig = maybe_append_eol(tmp, NULL, pool);
 
         tmp = pc->value ? pc->value :
                                   svn_string_create("", pool);
-        val = maybe_append_eol(tmp, pool);
+        val = maybe_append_eol(tmp, &val_has_eol, pool);
 
         SVN_ERR(svn_diff_mem_string_diff(&diff, orig, val, &options, pool));
 
@@ -888,6 +898,12 @@ display_prop_diffs(const apr_array_heade
                                            svn_dirent_local_style(path, pool),
                                            svn_cmdline_output_encoding(pool),
                                            orig, val, pool));
+        if (!val_has_eol)
+          {
+            const char *s = "\\ No newline at end of property" APR_EOL_STR;
+            apr_size_t len = strlen(s);
+            SVN_ERR(svn_stream_write(out, s, &len));
+          }
       }
     }
   return svn_cmdline_fflush(stdout);

Modified: subversion/branches/1.7.x-r1210147/subversion/tests/cmdline/commit_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1210147/subversion/tests/cmdline/commit_tests.py?rev=1245385&r1=1245384&r2=1245385&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1210147/subversion/tests/cmdline/commit_tests.py (original)
+++ subversion/branches/1.7.x-r1210147/subversion/tests/cmdline/commit_tests.py Fri Feb 17 10:52:38 2012
@@ -1136,19 +1136,26 @@ def commit_in_dir_scheduled_for_addition
 
   A_path = os.path.join(wc_dir, 'A')
   Z_path = os.path.join(wc_dir, 'Z')
+  Z_abspath = os.path.abspath(Z_path)
   mu_path = os.path.join(wc_dir, 'Z', 'mu')
 
   svntest.main.run_svn(None, 'move', A_path, Z_path)
+  
+  # Make sure mu is a committable
+  svntest.main.file_write(mu_path, "xxxx")
 
   # Commit a copied thing inside an added-with-history directory,
   # expecting a specific error to occur!
   svntest.actions.run_and_verify_commit(wc_dir,
                                         None,
                                         None,
-                                        "not under version control",
+                                        "svn: E200009: '" +
+                                        re.escape(Z_abspath) +
+                                        "' is not known to exist in the",
                                         mu_path)
 
   Q_path = os.path.join(wc_dir, 'Q')
+  Q_abspath = os.path.abspath(Q_path)
   bloo_path = os.path.join(Q_path, 'bloo')
 
   os.mkdir(Q_path)
@@ -1160,9 +1167,24 @@ def commit_in_dir_scheduled_for_addition
   svntest.actions.run_and_verify_commit(wc_dir,
                                         None,
                                         None,
-                                        "not under version control",
+                                        "svn: E200009: '" +
+                                        re.escape(Q_abspath) +
+                                        "' is not known to exist in the",
                                         bloo_path)
 
+  R_path = sbox.ospath('Z/B/R')
+  sbox.simple_mkdir('Z/B/R')
+
+  # Commit a d added thing inside an added directory,
+  # expecting a specific error to occur!
+  svntest.actions.run_and_verify_commit(wc_dir,
+                                        None,
+                                        None,
+                                        "svn: E200009: '" +
+                                        re.escape(Z_abspath) +
+                                        "' is not known to exist in the.*",
+                                        R_path)                                        
+
 #----------------------------------------------------------------------
 
 # Does this make sense now that deleted files are always removed from the wc?
@@ -2825,6 +2847,35 @@ def commit_incomplete(sbox):
                                         None,
                                         wc_dir)
   
+#----------------------------------------------------------------------
+# Reported here:
+#   Message-ID: <4E...@gmail.com>
+#   Date: Sun, 13 Nov 2011 13:31:05 +1300
+#   From: Fergus Slorach <su...@gmail.com>
+#   Subject: svn commit --targets behaviour change in 1.7?
+def commit_add_subadd(sbox):
+  "committing add with explicit subadd targets"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  targets_file = sbox.ospath('targets') # ### better tempdir?
+  targets_file = os.path.abspath(targets_file)
+
+  # prepare targets file
+  targets = "A/D A/D/H A/D/H/chi A/D/H/omega A/D/H/psi".split()
+  open(targets_file, 'w').write("\n".join(targets))
+
+  # r2: rm A/D
+  sbox.simple_rm('A/D')
+  sbox.simple_commit(message='rm')
+
+  # r3: revert r2, with specific invocation
+  os.chdir(wc_dir)
+  svntest.main.run_svn(None, 'up')
+  svntest.main.run_svn(None, 'merge', '-c', '-2', './')
+  svntest.main.run_svn(None, 'commit', '--targets', targets_file, '-mm')
+
 
 ########################################################################
 # Run the tests
@@ -2894,6 +2945,7 @@ test_list = [ None,
               tree_conflicts_resolved,
               commit_multiple_nested_deletes,
               commit_incomplete,
+              commit_add_subadd,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/1.7.x-r1210147/subversion/tests/cmdline/copy_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1210147/subversion/tests/cmdline/copy_tests.py?rev=1245385&r1=1245384&r2=1245385&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1210147/subversion/tests/cmdline/copy_tests.py (original)
+++ subversion/branches/1.7.x-r1210147/subversion/tests/cmdline/copy_tests.py Fri Feb 17 10:52:38 2012
@@ -4653,9 +4653,15 @@ def changed_dir_data_should_match_checko
 
   os.chdir(was_cwd)
   os.chdir(wc_dir)
-  svntest.actions.run_and_verify_svn(None, verify_out, [], 'status', '-v')
+  rv, verify_out2, err = main.run_svn (None, 'status', '-v')
   os.chdir(was_cwd)
 
+  # The order of the status output is not absolutely defined, but
+  # otherwise should match
+  svntest.verify.verify_outputs(None,
+                                sorted(verify_out2), None,
+                                sorted(verify_out), None)
+
 def move_added_nodes(sbox):
   """move added nodes"""
 

Modified: subversion/branches/1.7.x-r1210147/subversion/tests/cmdline/depth_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1210147/subversion/tests/cmdline/depth_tests.py?rev=1245385&r1=1245384&r2=1245385&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1210147/subversion/tests/cmdline/depth_tests.py (original)
+++ subversion/branches/1.7.x-r1210147/subversion/tests/cmdline/depth_tests.py Fri Feb 17 10:52:38 2012
@@ -1076,7 +1076,8 @@ def diff_in_depthy_wc(sbox):
     "___________________________________________________________________\n",
     "Deleted: foo\n",
     "## -1 +0,0 ##\n",
-    "-foo-val\n"]
+    "-foo-val\n",
+    "\\ No newline at end of property\n"]
 
   os.chdir(wc_empty)
 

Modified: subversion/branches/1.7.x-r1210147/subversion/tests/cmdline/diff_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1210147/subversion/tests/cmdline/diff_tests.py?rev=1245385&r1=1245384&r2=1245385&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1210147/subversion/tests/cmdline/diff_tests.py (original)
+++ subversion/branches/1.7.x-r1210147/subversion/tests/cmdline/diff_tests.py Fri Feb 17 10:52:38 2012
@@ -153,6 +153,47 @@ def make_git_diff_header(target_path, re
     ]
   return output
 
+def make_diff_prop_header(path):
+  """Return a property diff sub-header, as a list of newline-terminated
+     strings."""
+  return [
+    "\n",
+    "Property changes on: " + path.replace('\\', '/') + "\n",
+    "___________________________________________________________________\n"
+  ]
+
+def make_diff_prop_val(plus_minus, pval):
+  "Return diff for prop value PVAL, with leading PLUS_MINUS (+ or -)."
+  if len(pval) > 0 and pval[-1] != '\n':
+    return [plus_minus + pval + "\n","\\ No newline at end of property\n"]
+  return [plus_minus + pval]
+  
+def make_diff_prop_deleted(pname, pval):
+  """Return a property diff for deletion of property PNAME, old value PVAL.
+     PVAL is a single string with no embedded newlines.  Return the result
+     as a list of newline-terminated strings."""
+  return [
+    "Deleted: " + pname + "\n",
+    "## -1 +0,0 ##\n"
+  ] + make_diff_prop_val("-", pval)
+
+def make_diff_prop_added(pname, pval):
+  """Return a property diff for addition of property PNAME, new value PVAL.
+     PVAL is a single string with no embedded newlines.  Return the result
+     as a list of newline-terminated strings."""
+  return [
+    "Added: " + pname + "\n",
+    "## -0,0 +1 ##\n",
+  ] + make_diff_prop_val("+", pval)
+
+def make_diff_prop_modified(pname, pval1, pval2):
+  """Return a property diff for modification of property PNAME, old value
+     PVAL1, new value PVAL2.  PVAL is a single string with no embedded
+     newlines.  Return the result as a list of newline-terminated strings."""
+  return [
+    "Modified: " + pname + "\n",
+    "## -1 +1 ##\n",
+  ] + make_diff_prop_val("-", pval1) + make_diff_prop_val("+", pval2)
 
 ######################################################################
 # Diff output checker
@@ -744,29 +785,20 @@ def diff_only_property_change(sbox):
   sbox.build()
   wc_dir = sbox.wc_dir
 
-  expected_output = [
-    "Index: iota\n",
-    "===================================================================\n",
-    "--- iota\t(revision 1)\n",
-    "+++ iota\t(revision 2)\n",
-    "\n",
-    "Property changes on: iota\n",
-    "___________________________________________________________________\n",
-    "Added: svn:eol-style\n",
-    "## -0,0 +1 ##\n",
-    "+native\n" ]
-
-  expected_reverse_output = list(expected_output)
-  expected_reverse_output[2] = expected_reverse_output[2].replace("1", "2")
-  expected_reverse_output[3] = expected_reverse_output[3].replace("2", "1")
-  expected_reverse_output[7] = expected_reverse_output[7].replace("Added",
-                                                                  "Deleted")
-  expected_reverse_output[8] = "## -1 +0,0 ##\n"
-  expected_reverse_output[9] = "-native\n"
-
-  expected_rev1_output = list(expected_output)
-  expected_rev1_output[3] = expected_rev1_output[3].replace("revision 2",
-                                                            "working copy")
+  expected_output = \
+    make_diff_header("iota", "revision 1", "revision 2") + \
+    make_diff_prop_header("iota") + \
+    make_diff_prop_added("svn:eol-style", "native")
+
+  expected_reverse_output = \
+    make_diff_header("iota", "revision 2", "revision 1") + \
+    make_diff_prop_header("iota") + \
+    make_diff_prop_deleted("svn:eol-style", "native")
+
+  expected_rev1_output = \
+    make_diff_header("iota", "revision 1", "working copy") + \
+    make_diff_prop_header("iota") + \
+    make_diff_prop_added("svn:eol-style", "native")
 
   os.chdir(sbox.wc_dir)
   svntest.actions.run_and_verify_svn(None, None, [],
@@ -2025,33 +2057,17 @@ def diff_property_changes_to_base(sbox):
   wc_dir = sbox.wc_dir
 
 
-  add_diff = [
-    "\n",
-    "Property changes on: A\n",
-    "___________________________________________________________________\n",
-    "Added: dirprop\n",
-    "## -0,0 +1 ##\n",
-    "+r2value\n",
-    "\n",
-    "Property changes on: iota\n",
-    "___________________________________________________________________\n",
-    "Added: fileprop\n",
-    "## -0,0 +1 ##\n",
-    "+r2value\n"]
-
-  del_diff = [
-    "\n",
-    "Property changes on: A\n",
-    "___________________________________________________________________\n",
-    "Deleted: dirprop\n",
-    "## -1 +0,0 ##\n",
-    "-r2value\n",
-    "\n",
-    "Property changes on: iota\n",
-    "___________________________________________________________________\n",
-    "Deleted: fileprop\n",
-    "## -1 +0,0 ##\n",
-    "-r2value\n"]
+  add_diff = \
+    make_diff_prop_header("A") + \
+    make_diff_prop_added("dirprop", "r2value") + \
+    make_diff_prop_header("iota") + \
+    make_diff_prop_added("fileprop", "r2value")
+
+  del_diff = \
+    make_diff_prop_header("A") + \
+    make_diff_prop_deleted("dirprop", "r2value") + \
+    make_diff_prop_header("iota") + \
+    make_diff_prop_deleted("fileprop", "r2value")
 
 
   expected_output_r1_r2 = list(make_diff_header('A', 'revision 1', 'revision 2')
@@ -2287,35 +2303,15 @@ def diff_prop_change_local_propmod(sbox)
 
   sbox.build()
 
-  expected_output_r2_wc = [
-    "Index: A\n",
-    "===================================================================\n",
-    "--- A\t(revision 2)\n",
-    "+++ A\t(working copy)\n",
-    "\n",
-    "Property changes on: A\n",
-    "___________________________________________________________________\n",
-    "Modified: dirprop\n",
-    "## -1 +1 ##\n",
-    "-r2value\n",
-    "+workingvalue\n",
-    "Added: newdirprop\n",
-    "## -0,0 +1 ##\n",
-    "+newworkingvalue\n",
-    "Index: iota\n",
-    "===================================================================\n",
-    "--- iota\t(revision 2)\n",
-    "+++ iota\t(working copy)\n",
-    "\n",
-    "Property changes on: iota\n",
-    "___________________________________________________________________\n",
-    "Modified: fileprop\n",
-    "## -1 +1 ##\n",
-    "-r2value\n",
-    "+workingvalue\n",
-    "Added: newfileprop\n",
-    "## -0,0 +1 ##\n",
-    "+newworkingvalue\n" ]
+  expected_output_r2_wc = \
+    make_diff_header("A", "revision 2", "working copy") + \
+    make_diff_prop_header("A") + \
+    make_diff_prop_modified("dirprop", "r2value", "workingvalue") + \
+    make_diff_prop_added("newdirprop", "newworkingvalue") + \
+    make_diff_header("iota", "revision 2", "working copy") + \
+    make_diff_prop_header("iota") + \
+    make_diff_prop_modified("fileprop", "r2value", "workingvalue") + \
+    make_diff_prop_added("newfileprop", "newworkingvalue")
 
   os.chdir(sbox.wc_dir)
 
@@ -2378,31 +2374,16 @@ def diff_repos_wc_add_with_props(sbox):
   diff_foo = [
     "@@ -0,0 +1 @@\n",
     "+content\n",
-    "\n",
-    "Property changes on: foo\n",
-    "___________________________________________________________________\n",
-    "Added: propname\n",
-    "## -0,0 +1 ##\n",
-    "+propvalue\n",
-    ]
-  diff_X = [
-    "\n",
-    "Property changes on: X\n",
-    "___________________________________________________________________\n",
-    "Added: propname\n",
-    "## -0,0 +1 ##\n",
-    "+propvalue\n",
-    ]
+    ] + make_diff_prop_header("foo") + \
+    make_diff_prop_added("propname", "propvalue")
+  diff_X = \
+    make_diff_prop_header("X") + \
+    make_diff_prop_added("propname", "propvalue")
   diff_X_bar = [
     "@@ -0,0 +1 @@\n",
     "+content\n",
-    "\n",
-    "Property changes on: X/bar\n",
-    "___________________________________________________________________\n",
-    "Added: propname\n",
-    "## -0,0 +1 ##\n",
-    "+propvalue\n",
-    ]
+    ] + make_diff_prop_header("X/bar") + \
+    make_diff_prop_added("propname", "propvalue")
 
   diff_X_r1_base = make_diff_header("X", "revision 1",
                                          "working copy") + diff_X
@@ -2876,49 +2857,32 @@ def diff_with_depth(sbox):
   sbox.build()
   B_path = os.path.join('A', 'B')
 
-  diff = [
-    "\n",
-    "Property changes on: .\n",
-    "___________________________________________________________________\n",
-    "Added: foo1\n",
-    "## -0,0 +1 ##\n",
-    "+bar1\n",
-    "\n",
-    "Property changes on: iota\n",
-    "___________________________________________________________________\n",
-    "Added: foo2\n",
-    "## -0,0 +1 ##\n",
-    "+bar2\n",
-    "\n",
-    "Property changes on: A\n",
-    "___________________________________________________________________\n",
-    "Added: foo3\n",
-    "## -0,0 +1 ##\n",
-    "+bar3\n",
-    "\n",
-    "Property changes on: A/B\n",
-    "___________________________________________________________________\n",
-    "Added: foo4\n",
-    "## -0,0 +1 ##\n",
-    "+bar4\n"]
+  diff = make_diff_prop_header(".") + \
+         make_diff_prop_added("foo1", "bar1") + \
+         make_diff_prop_header("iota") + \
+         make_diff_prop_added("foo2", "bar2") + \
+         make_diff_prop_header("A") + \
+         make_diff_prop_added("foo3", "bar3") + \
+         make_diff_prop_header("A/B") + \
+         make_diff_prop_added("foo4", "bar4")
 
   dot_header = make_diff_header(".", "revision 1", "working copy")
   iota_header = make_diff_header('iota', "revision 1", "working copy")
   A_header = make_diff_header('A', "revision 1", "working copy")
   B_header = make_diff_header(B_path, "revision 1", "working copy")
 
-  expected_empty = svntest.verify.UnorderedOutput(dot_header + diff[:6])
-  expected_files = svntest.verify.UnorderedOutput(dot_header + diff[:6]
-                                                  + iota_header + diff[7:12])
-  expected_immediates = svntest.verify.UnorderedOutput(dot_header + diff[:6]
+  expected_empty = svntest.verify.UnorderedOutput(dot_header + diff[:7])
+  expected_files = svntest.verify.UnorderedOutput(dot_header + diff[:7]
+                                                  + iota_header + diff[8:14])
+  expected_immediates = svntest.verify.UnorderedOutput(dot_header + diff[:7]
                                                        + iota_header
-                                                       + diff[7:12]
-                                                       +  A_header + diff[8:18])
-  expected_infinity = svntest.verify.UnorderedOutput(dot_header + diff[:6]
+                                                       + diff[8:14]
+                                                       + A_header + diff[15:21])
+  expected_infinity = svntest.verify.UnorderedOutput(dot_header + diff[:7]
                                                        + iota_header
-                                                       + diff[7:12]
-                                                       +  A_header + diff[8:18]
-                                                       + B_header + diff[12:])
+                                                       + diff[8:14]
+                                                       + A_header + diff[15:21]
+                                                       + B_header + diff[22:])
 
   os.chdir(sbox.wc_dir)
 
@@ -2954,18 +2918,18 @@ def diff_with_depth(sbox):
   A_header = make_diff_header('A', "revision 1", "revision 2")
   B_header = make_diff_header(B_path, "revision 1", "revision 2")
 
-  expected_empty = svntest.verify.UnorderedOutput(dot_header + diff[:6])
-  expected_files = svntest.verify.UnorderedOutput(dot_header + diff[:6]
-                                                  + iota_header + diff[7:12])
-  expected_immediates = svntest.verify.UnorderedOutput(dot_header + diff[:6]
+  expected_empty = svntest.verify.UnorderedOutput(dot_header + diff[:7])
+  expected_files = svntest.verify.UnorderedOutput(dot_header + diff[:7]
+                                                  + iota_header + diff[8:14])
+  expected_immediates = svntest.verify.UnorderedOutput(dot_header + diff[:7]
                                                        + iota_header
-                                                       + diff[7:12]
-                                                       +  A_header + diff[8:18])
+                                                       + diff[8:14]
+                                                       + A_header + diff[15:21])
   expected_infinity = svntest.verify.UnorderedOutput(dot_header + diff[:6]
                                                        + iota_header
-                                                       + diff[7:12]
-                                                       +  A_header + diff[8:18]
-                                                       + B_header + diff[12:])
+                                                       + diff[8:14]
+                                                       + A_header + diff[15:21]
+                                                       + B_header + diff[22:])
 
   # Test repos-repos diff.
   svntest.actions.run_and_verify_svn(None, expected_empty, [],
@@ -2977,66 +2941,31 @@ def diff_with_depth(sbox):
   svntest.actions.run_and_verify_svn(None, expected_infinity, [],
                                      'diff', '-c2', '--depth', 'infinity')
 
-  diff_wc_repos = [
-    "Index: A/B\n",
-    "===================================================================\n",
-    "--- A/B\t(revision 2)\n",
-    "+++ A/B\t(working copy)\n",
-    "\n",
-    "Property changes on: A/B\n",
-    "___________________________________________________________________\n",
-    "Modified: foo4\n",
-    "## -1 +1 ##\n",
-    "-bar4\n",
-    "+baz4\n",
-    "Index: A\n",
-    "===================================================================\n",
-    "--- A\t(revision 2)\n",
-    "+++ A\t(working copy)\n",
-    "\n",
-    "Property changes on: A\n",
-    "___________________________________________________________________\n",
-    "Modified: foo3\n",
-    "## -1 +1 ##\n",
-    "-bar3\n",
-    "+baz3\n",
-    "Index: A/mu\n",
-    "===================================================================\n",
-    "--- A/mu\t(revision 1)\n",
-    "+++ A/mu\t(working copy)\n",
+  diff_wc_repos = \
+    make_diff_header("A/B", "revision 2", "working copy") + \
+    make_diff_prop_header("A/B") + \
+    make_diff_prop_modified("foo4", "bar4", "baz4") + \
+    make_diff_header("A", "revision 2", "working copy") + \
+    make_diff_prop_header("A") + \
+    make_diff_prop_modified("foo3", "bar3", "baz3") + \
+    make_diff_header("A/mu", "revision 1", "working copy") + [
     "@@ -1 +1,2 @@\n",
     " This is the file 'mu'.\n",
     "+new text\n",
-    "Index: iota\n",
-    "===================================================================\n",
-    "--- iota\t(revision 2)\n",
-    "+++ iota\t(working copy)\n",
+    ] + make_diff_header("iota", "revision 2", "working copy") + [
     "@@ -1 +1,2 @@\n",
     " This is the file 'iota'.\n",
     "+new text\n",
-    "\n",
-    "Property changes on: iota\n",
-    "___________________________________________________________________\n",
-    "Modified: foo2\n",
-    "## -1 +1 ##\n",
-    "-bar2\n",
-    "+baz2\n",
-    "Index: .\n",
-    "===================================================================\n",
-    "--- .\t(revision 2)\n",
-    "+++ .\t(working copy)\n",
-    "\n",
-    "Property changes on: .\n",
-    "___________________________________________________________________\n",
-    "Modified: foo1\n",
-    "## -1 +1 ##\n",
-    "-bar1\n",
-    "+baz1\n" ]
-
-  expected_empty = svntest.verify.UnorderedOutput(diff_wc_repos[43:])
-  expected_files = svntest.verify.UnorderedOutput(diff_wc_repos[29:])
-  expected_immediates = svntest.verify.UnorderedOutput(diff_wc_repos[11:22]
-                                                       +diff_wc_repos[29:])
+    ] + make_diff_prop_header("iota") + \
+    make_diff_prop_modified("foo2", "bar2", "baz2") + \
+    make_diff_header(".", "revision 2", "working copy") + \
+    make_diff_prop_header(".") + \
+    make_diff_prop_modified("foo1", "bar1", "baz1")
+
+  expected_empty = svntest.verify.UnorderedOutput(diff_wc_repos[49:])
+  expected_files = svntest.verify.UnorderedOutput(diff_wc_repos[33:])
+  expected_immediates = svntest.verify.UnorderedOutput(diff_wc_repos[13:26]
+                                                       +diff_wc_repos[33:])
   expected_infinity = svntest.verify.UnorderedOutput(diff_wc_repos[:])
 
   svntest.actions.run_and_verify_svn(None, None, [],
@@ -3549,10 +3478,8 @@ def diff_prop_missing_context(sbox):
   svntest.main.run_svn(None,
                        "propset", "prop", prop_val, iota_path)
   expected_output = make_diff_header(iota_path, 'revision 2',
-                                     'working copy') + [
-    "\n",
-    "Property changes on: %s\n" % iota_path.replace('\\', '/'),
-    "___________________________________________________________________\n",
+                                     'working copy') + \
+                    make_diff_prop_header(iota_path) + [
     "Modified: prop\n",
     "## -1,7 +1,4 ##\n",
     "-line 1\n",
@@ -3619,10 +3546,8 @@ def diff_prop_multiple_hunks(sbox):
   svntest.main.run_svn(None,
                        "propset", "prop", prop_val, iota_path)
   expected_output = make_diff_header(iota_path, 'revision 2',
-                                     'working copy') + [
-    "\n",
-    "Property changes on: %s\n" % iota_path.replace('\\', '/'),
-    "___________________________________________________________________\n",
+                                     'working copy') + \
+                    make_diff_prop_header(iota_path) + [
     "Modified: prop\n",
     "## -1,6 +1,7 ##\n",
     " line 1\n",
@@ -3704,24 +3629,16 @@ def diff_git_with_props(sbox):
   svntest.main.run_svn(None, 'propset', 'svn:eol-style', 'native', new_path)
   svntest.main.run_svn(None, 'propset', 'svn:keywords', 'Id', iota_path)
 
-  expected_output = make_git_diff_header(new_path, "new", "revision 0",
-                                         "working copy",
-                                         add=True, text_changes=False) + [
-      "\n",
-      "Property changes on: new\n",
-      "___________________________________________________________________\n",
-      "Added: svn:eol-style\n",
-      "## -0,0 +1 ##\n",
-      "+native\n",
-  ] + make_git_diff_header(iota_path, "iota", "revision 1", "working copy",
-                           text_changes=False) + [
-      "\n",
-      "Property changes on: iota\n",
-      "___________________________________________________________________\n",
-      "Added: svn:keywords\n",
-      "## -0,0 +1 ##\n",
-      "+Id\n",
-  ]
+  expected_output = make_git_diff_header(new_path, "new",
+                                         "revision 0", "working copy",
+                                         add=True, text_changes=False) + \
+                    make_diff_prop_header("new") + \
+                    make_diff_prop_added("svn:eol-style", "native") + \
+                    make_git_diff_header(iota_path, "iota",
+                                         "revision 1", "working copy",
+                                         text_changes=False) + \
+                    make_diff_prop_header("iota") + \
+                    make_diff_prop_added("svn:keywords", "Id")
 
   svntest.actions.run_and_verify_svn(None, expected_output, [], 'diff',
                                      '--git', wc_dir)
@@ -3749,14 +3666,9 @@ def diff_git_with_props_on_dir(sbox):
   os.chdir(wc_dir)
   expected_output = make_git_diff_header(".", "", "revision 1",
                                          "revision 2",
-                                         add=False, text_changes=False) + [
-      "\n",
-      "Property changes on: \n",
-      "___________________________________________________________________\n",
-      "Added: a\n",
-      "## -0,0 +1 ##\n",
-      "+b\n",
-  ]
+                                         add=False, text_changes=False) + \
+                    make_diff_prop_header("") + \
+                    make_diff_prop_added("a", "b")
 
   svntest.actions.run_and_verify_svn(None, expected_output, [], 'diff',
                                      '-c2', '--git')

Modified: subversion/branches/1.7.x-r1210147/subversion/tests/cmdline/externals_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1210147/subversion/tests/cmdline/externals_tests.py?rev=1245385&r1=1245384&r2=1245385&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1210147/subversion/tests/cmdline/externals_tests.py (original)
+++ subversion/branches/1.7.x-r1210147/subversion/tests/cmdline/externals_tests.py Fri Feb 17 10:52:38 2012
@@ -2060,6 +2060,110 @@ def copy_file_externals(sbox):
   actions.run_and_verify_update(wc_dir, expected_output, expected_disk,
     expected_status, None, None, None, None, None, True, wc_dir)
 
+# Test for issue #4093 'remapping a file external can segfault due to
+# "deleted" props'.
+@Issue(4093)
+def remap_file_external_with_prop_del(sbox):
+  "file external remap segfaults due to deleted props"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  A_path  = os.path.join(wc_dir, "A")
+  mu_path = os.path.join(wc_dir, "A", "mu")
+
+  # Add a property to A/mu
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'ps', 'propname', 'propval', mu_path)
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'commit', '-m', 'New property on a file',
+                                     wc_dir)
+  svntest.actions.run_and_verify_svn(None, None, [], 'up', wc_dir)
+
+  # Add a new file external A/external pointing to ^/A/mu
+  externals_prop = "^/A/mu external\n"
+  change_external(A_path, externals_prop)
+  svntest.actions.run_and_verify_svn(None, None, [], 'up', wc_dir)
+
+  # Change A/external to point to ^/iota
+  externals_prop = "^/iota external\n"
+  change_external(A_path, externals_prop)
+
+  # Now update to bring the new external down.
+  # This previously segfaulted as described in
+  # http://subversion.tigris.org/issues/show_bug.cgi?id=4093#desc1
+  svntest.actions.run_and_verify_svn(None, None, [], 'up', wc_dir)
+
+
+# Test for issue #4053 'svn:externals with explicit rev checks out HEAD'
+@Issue(4053)
+def dir_external_with_dash_r_only(sbox):
+  "whether '-r1 ^/A B' updates properly"
+  # svntest.factory.make(sbox,"""
+  #   echo 'newer alpha' > A/B/E/alpha
+  #   svn ci
+  #   svn ps svn:externals ' -r1 ^/A/B/E E_ext' .
+  #   svn up
+  #   # ^ move the 'status.tweak(wc_rev=2)' above the 'add()' call
+  #   svn info E_ext
+  #   # ^ change the 'svn info' call to
+  #   #  expected_info = { 'Revision': '1' }
+  #   #  actions.run_and_verify_info([expected_info], E_ext)
+  #   """)
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+  url = sbox.repo_url
+
+  A_B_E_alpha = os.path.join(wc_dir, 'A', 'B', 'E', 'alpha')
+  E_ext = os.path.join(wc_dir, 'E_ext')
+
+  # echo 'newer alpha' > A/B/E/alpha
+  main.file_write(A_B_E_alpha, 'newer alpha\n')
+
+  # svn ci
+  expected_output = svntest.wc.State(wc_dir, {
+    'A/B/E/alpha'       : Item(verb='Sending'),
+  })
+
+  expected_status = actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('A/B/E/alpha', wc_rev='2')
+
+  actions.run_and_verify_commit(wc_dir, expected_output, expected_status,
+    None, wc_dir)
+
+  # svn ps svn:externals ' -r1 ^/A/B/E E_ext' .
+  expected_stdout = ["property 'svn:externals' set on '" + wc_dir + "'\n"]
+
+  actions.run_and_verify_svn2('OUTPUT', expected_stdout, [], 0, 'ps',
+    'svn:externals', ' -r1 ^/A/B/E E_ext', wc_dir)
+
+  # svn up
+  expected_output = svntest.wc.State(wc_dir, {
+    'E_ext/beta'        : Item(status='A '),
+    'E_ext/alpha'       : Item(status='A '),
+  })
+
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.add({
+    'E_ext'             : Item(),
+    'E_ext/alpha'       : Item(contents="This is the file 'alpha'.\n"),
+    'E_ext/beta'        : Item(contents="This is the file 'beta'.\n"),
+  })
+  expected_disk.tweak('A/B/E/alpha', contents='newer alpha\n')
+
+  expected_status.tweak(wc_rev='2')
+  expected_status.tweak('', status=' M')
+  expected_status.add({
+    'E_ext'             : Item(status='X '),
+  })
+
+  actions.run_and_verify_update(wc_dir, expected_output, expected_disk,
+    expected_status, None, None, None, None, None, False, wc_dir)
+
+  # svn info E_ext/alpha
+  expected_info = { 'Revision': '1' }
+  actions.run_and_verify_info([expected_info], E_ext)
 
 ########################################################################
 # Run the tests
@@ -2101,6 +2205,8 @@ test_list = [ None,
               exclude_externals,
               file_external_in_unversioned,
               copy_file_externals,
+              remap_file_external_with_prop_del,
+              dir_external_with_dash_r_only,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/1.7.x-r1210147/subversion/tests/cmdline/merge_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1210147/subversion/tests/cmdline/merge_tests.py?rev=1245385&r1=1245384&r2=1245385&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1210147/subversion/tests/cmdline/merge_tests.py (original)
+++ subversion/branches/1.7.x-r1210147/subversion/tests/cmdline/merge_tests.py Fri Feb 17 10:52:38 2012
@@ -12005,7 +12005,7 @@ def subtree_source_missing_in_requested_
   sbox.build()
   wc_dir = sbox.wc_dir
 
-  # Make a branche to merge to.
+  # Make a branch to merge to.
   wc_disk, wc_status = set_up_branch(sbox, False, 1)
 
   # Some paths we'll care about.
@@ -12015,16 +12015,14 @@ def subtree_source_missing_in_requested_
   psi_COPY_path   = os.path.join(wc_dir, "A_COPY", "D", "H", "psi")
   omega_COPY_path = os.path.join(wc_dir, "A_COPY", "D", "H", "omega")
 
-  # r7 Delete a A/D/H/psi.
+  # r7 Delete A/D/H/psi.
   svntest.actions.run_and_verify_svn(None, None, [],
                                      'delete', psi_path)
-  svntest.actions.run_and_verify_svn(None, None, [],
-                                     'ci', '-m', 'delete psi', wc_dir)
+  sbox.simple_commit(message='delete psi')
 
   # r8 - modify A/D/H/omega.
   svntest.main.file_write(os.path.join(omega_path), "Even newer content")
-  svntest.actions.run_and_verify_svn(None, None, [],
-                                     'ci', '-m', 'modify omega', wc_dir)
+  sbox.simple_commit(message='modify omega')
 
   # r9 - Merge r3 to A_COPY/D/H/psi
   expected_output = expected_merge_output(
@@ -12034,9 +12032,7 @@ def subtree_source_missing_in_requested_
                                      'merge', '-c', '3',
                                      sbox.repo_url + '/A/D/H/psi@3',
                                      psi_COPY_path)
-  svntest.actions.run_and_verify_svn(None, None, [],
-                                     'ci', '-m', 'merge r3 to A_COPY/D/H/psi',
-                                     wc_dir)
+  sbox.simple_commit(message='merge r3 to A_COPY/D/H/psi')
 
   # r10 - Merge r6 to A_COPY/D/H/omega.
   expected_output = expected_merge_output(
@@ -12046,9 +12042,7 @@ def subtree_source_missing_in_requested_
                                      'merge', '-c', '6',
                                      sbox.repo_url + '/A/D/H/omega',
                                      omega_COPY_path)
-  svntest.actions.run_and_verify_svn(None, None, [], 'ci', '-m',
-                                     'merge r6 to A_COPY',
-                                     wc_dir)
+  sbox.simple_commit(message='merge r6 to A_COPY')
   svntest.actions.run_and_verify_svn(None, exp_noop_up_out(10), [], 'up',
                                      wc_dir)
 
@@ -12075,17 +12069,14 @@ def subtree_source_missing_in_requested_
                                      'merge', '-c', '8',
                                      sbox.repo_url + '/A',
                                      A_COPY_path, '--record-only')
-  svntest.actions.run_and_verify_svn(None, None, [], 'ci', '-m',
-                                     'merge r8 to A_COPY/D/H/omega',
-                                     wc_dir)
+  sbox.simple_commit(message='merge r8 to A_COPY/D/H/omega')
   svntest.actions.run_and_verify_svn(None, exp_noop_up_out(11), [], 'up',
                                      wc_dir)
 
   # r12 - modify A/D/H/omega yet again.
   svntest.main.file_write(os.path.join(omega_path),
                           "Now with fabulous new content!")
-  svntest.actions.run_and_verify_svn(None, None, [],
-                                     'ci', '-m', 'modify omega', wc_dir)
+  sbox.simple_commit(message='modify omega')
 
   # r13 - Merge all available revs to A_COPY/D/H/omega.
   expected_output = expected_merge_output(
@@ -12095,9 +12086,7 @@ def subtree_source_missing_in_requested_
                                      'merge',
                                      sbox.repo_url + '/A/D/H/omega',
                                      omega_COPY_path)
-  svntest.actions.run_and_verify_svn(None, None, [], 'ci', '-m',
-                                     'cherry harvest to A_COPY/D/H/omega',
-                                     wc_dir)
+  sbox.simple_commit(message='cherry harvest to A_COPY/D/H/omega')
   svntest.actions.run_and_verify_svn(None, exp_noop_up_out(13), [], 'up',
                                      wc_dir)
 
@@ -12258,9 +12247,7 @@ def subtree_source_missing_in_requested_
                                      'merge', '-c', '12',
                                      sbox.repo_url + '/A',
                                      A_COPY_path, '--record-only')
-  svntest.actions.run_and_verify_svn(None, None, [], 'ci', '-m',
-                                     'Merge r12 to A_COPY',
-                                     wc_dir)
+  sbox.simple_commit(message='Merge r12 to A_COPY')
 
   # Update A_COPY/D/H/rho back to r13 so it's mergeinfo doesn't include
   # r12.  Then merge a range, -r6:12 which should delete a subtree
@@ -13735,14 +13722,12 @@ def subtree_gets_changes_even_if_ultimat
 
   # r7: Make an additional text mod to A/D/H/psi.
   svntest.main.file_write(psi_path, "Even newer content")
-  svntest.actions.run_and_verify_svn(None, None, [],
-                                     'ci', '-m', 'mod psi', wc_dir)
+  sbox.simple_commit(message='mod psi')
 
   # r8: Delete A/D/H/psi.
   svntest.actions.run_and_verify_svn(None, None, [],
                                      'delete', psi_path)
-  svntest.actions.run_and_verify_svn(None, None, [],
-                                     'ci', '-m', 'delete psi', wc_dir)
+  sbox.simple_commit(message='delete psi')
 
   # Update WC before merging so mergeinfo elision and inheritance
   # occur smoothly.
@@ -13788,11 +13773,8 @@ def subtree_gets_changes_even_if_ultimat
                           ['G    ' + psi_COPY_path + '\n',
                            ' G   ' + psi_COPY_path + '\n',]),
     [], 'merge', '-c-7', sbox.repo_url + '/A/D/H/psi@7', psi_COPY_path)
-  svntest.actions.run_and_verify_svn(None, None, [],
-                                     'ci', '-m',
-                                     'merge -c3,7 from A/D/H,' \
-                                     'reverse merge -c-7 from A/D/H/psi',
-                                     wc_dir)
+  sbox.simple_commit(message='merge -c3,7 from A/D/H,' \
+                             'reverse merge -c-7 from A/D/H/psi')
 
   # Merge all available revisions from A/D/H to A_COPY/D/H.  This merge
   # ultimately tries to delete A_COPY/D/H/psi, but first it should merge

Modified: subversion/branches/1.7.x-r1210147/subversion/tests/cmdline/mergeinfo_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1210147/subversion/tests/cmdline/mergeinfo_tests.py?rev=1245385&r1=1245384&r2=1245385&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1210147/subversion/tests/cmdline/mergeinfo_tests.py (original)
+++ subversion/branches/1.7.x-r1210147/subversion/tests/cmdline/mergeinfo_tests.py Fri Feb 17 10:52:38 2012
@@ -679,6 +679,55 @@ def natural_history_is_not_eligible_nor_
     ['3','4','5','6','7','9'], sbox.repo_url + '/A',
     A_COPY_path, '--show-revs', 'merged', '-R')
 
+#----------------------------------------------------------------------
+# A test for issue 4050 "'svn mergeinfo' always considers non-inheritable
+# ranges as partially merged".
+@Issue(4050)
+@SkipUnless(server_has_mergeinfo)
+def noninheritabled_mergeinfo_not_always_eligible(sbox):
+  "noninheritabled mergeinfo not always eligible"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  A_path      = os.path.join(wc_dir, 'A')
+  branch_path = os.path.join(wc_dir, 'branch')
+
+  # r2 - Branch ^/A to ^/branch.
+  svntest.main.run_svn(None, 'copy', sbox.repo_url + '/A',
+                       sbox.repo_url + '/branch', '-m', 'make a branch')
+
+  # r3 - Make prop edit to A.
+  svntest.main.run_svn(None, 'ps', 'prop', 'val', A_path)
+  svntest.main.run_svn(None, 'commit', '-m', 'file edit', wc_dir)
+  svntest.main.run_svn(None, 'up', wc_dir)
+
+  # r4 - Merge r3 from ^/A to branch at depth=empty.
+  svntest.actions.run_and_verify_svn(None, None, [], 'merge',
+                                     sbox.repo_url + '/A', branch_path,
+                                     '-c3', '--depth=empty')
+  svntest.main.run_svn(None, 'commit', '-m', 'shallow merge', wc_dir)
+
+  # A sanity check that we really have non-inheritable mergeinfo.
+  # If issue #4057 is ever fixed then the above merge will record
+  # inheritable mergeinfo and this test will spuriously pass.
+  svntest.actions.run_and_verify_svn(None, ["/A:3*\n"], [],
+                                     'propget', SVN_PROP_MERGEINFO,
+                                     branch_path)
+
+  # Now check that r3 is reported as fully merged from ^/A to ^/branch
+  # and does not show up all when asking for eligible revs.
+  svntest.actions.run_and_verify_mergeinfo(
+    adjust_error_for_server_version(''),
+    ['3'], sbox.repo_url + '/A', sbox.repo_url + '/branch',
+    '--show-revs', 'merged', '-R')
+  # Likewise r3 shows up as partially eligible when asking about
+  # for --show-revs=eligible.
+  svntest.actions.run_and_verify_mergeinfo(
+    adjust_error_for_server_version(''),
+    [], sbox.repo_url + '/A', sbox.repo_url + '/branch',
+    '--show-revs', 'eligible', '-R')
+
 ########################################################################
 # Run the tests
 
@@ -695,6 +744,7 @@ test_list = [ None,
               mergeinfo_on_pegged_wc_path,
               wc_target_inherits_mergeinfo_from_repos,
               natural_history_is_not_eligible_nor_merged,
+              noninheritabled_mergeinfo_not_always_eligible,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/1.7.x-r1210147/subversion/tests/cmdline/patch_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1210147/subversion/tests/cmdline/patch_tests.py?rev=1245385&r1=1245384&r2=1245385&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1210147/subversion/tests/cmdline/patch_tests.py (original)
+++ subversion/branches/1.7.x-r1210147/subversion/tests/cmdline/patch_tests.py Fri Feb 17 10:52:38 2012
@@ -3427,7 +3427,6 @@ def patch_strip_cwd(sbox):
   "patch --strip propchanges cwd"
   return patch_one_property(sbox, True)
 
-@XFail()
 @Issue(3814)
 def patch_set_prop_no_eol(sbox):
   "patch doesn't append newline to properties"
@@ -3805,6 +3804,169 @@ def patch_delete_and_skip(sbox):
                                        1, # check-props
                                        1) # dry-run
 
+@Issue(3991)
+def patch_lacking_trailing_eol(sbox):
+  "patch file lacking trailing eol"
+  sbox.build(read_only = True)
+  wc_dir = sbox.wc_dir
+
+  patch_file_path = make_patch_path(sbox)
+  iota_path = os.path.join(wc_dir, 'iota')
+  mu_path = os.path.join(wc_dir, 'A', 'mu')
+
+  # Prepare
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+
+  # Apply patch
+  unidiff_patch = [
+    "Index: iota\n",
+    "===================================================================\n",
+    "--- iota\t(revision 1)\n",
+    "+++ iota\t(working copy)\n",
+    # TODO: -1 +1
+    "@@ -1 +1,2 @@\n",
+    " This is the file 'iota'.\n",
+    "+Some more bytes", # No trailing \n on this line!
+  ]
+
+  svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+  gamma_contents = "It is the file 'gamma'.\n"
+  iota_contents = "This is the file 'iota'.\n"
+  new_contents = "new\n"
+
+  expected_output = [
+    'U         %s\n' % os.path.join(wc_dir, 'iota'),
+  ]
+
+  # Expect a newline to be appended
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.tweak('iota', contents=iota_contents + "Some more bytes")
+
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('iota', status='M ')
+
+  expected_skip = wc.State('', { })
+
+  svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+                                       expected_output,
+                                       expected_disk,
+                                       expected_status,
+                                       expected_skip,
+                                       None, # expected err
+                                       1, # check-props
+                                       1) # dry-run
+
+def patch_target_no_eol_at_eof(sbox):
+  "patch target with no eol at eof"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  patch_file_path = make_patch_path(sbox)
+  iota_path = os.path.join(wc_dir, 'iota')
+
+  iota_contents = [
+    "This is the file iota."
+  ]
+
+  svntest.main.file_write(iota_path, ''.join(iota_contents))
+  expected_output = svntest.wc.State(wc_dir, {
+    'iota'  : Item(verb='Sending'),
+    })
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('iota', wc_rev=2)
+  svntest.actions.run_and_verify_commit(wc_dir, expected_output,
+                                        expected_status, None, wc_dir)
+  unidiff_patch = [
+    "--- iota\t(revision 1)\n",
+    "+++ iota\t(working copy)\n",
+    "@@ -1,7 +1,7 @@\n",
+    "-This is the file iota.\n"
+    "\\ No newline at end of file\n",
+    "+It is really the file 'iota'.\n",
+    "\\ No newline at end of file\n",
+  ]
+
+  svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+  iota_contents = [
+    "It is really the file 'iota'."
+  ]
+  expected_output = [
+    'U         %s\n' % os.path.join(wc_dir, 'iota'),
+  ]
+
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.tweak('iota', contents=''.join(iota_contents))
+
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('iota', status='M ', wc_rev=2)
+
+  expected_skip = wc.State('', { })
+
+  svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+                                       expected_output,
+                                       expected_disk,
+                                       expected_status,
+                                       expected_skip,
+                                       None, # expected err
+                                       1, # check-props
+                                       1) # dry-run
+
+def patch_add_and_delete(sbox):
+  "patch add multiple levels and delete"
+
+  sbox.build(read_only = True)
+  wc_dir = sbox.wc_dir
+  patch_file_path = make_patch_path(sbox)
+
+  unidiff_patch = [
+    "Index: foo\n",
+    "===================================================================\n",
+    "--- P/Q/foo\t(revision 0)\n"
+    "+++ P/Q/foo\t(working copy)\n"
+    "@@ -0,0 +1 @@\n",
+    "+This is the file 'foo'.\n",
+    "Index: iota\n"
+    "===================================================================\n",
+    "--- iota\t(revision 1)\n"
+    "+++ iota\t(working copy)\n"
+    "@@ -1 +0,0 @@\n",
+    "-This is the file 'iota'.\n",
+    ]
+
+  svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+  expected_output = [
+    'A         %s\n' % os.path.join(wc_dir, 'P'),
+    'A         %s\n' % os.path.join(wc_dir, 'P', 'Q'),
+    'A         %s\n' % os.path.join(wc_dir, 'P', 'Q', 'foo'),
+    'D         %s\n' % os.path.join(wc_dir, 'iota'),
+  ]
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.remove('iota')
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_disk.add({'P/Q/foo' : Item(contents="This is the file 'foo'.\n")})
+  expected_status.tweak('iota', status='D ')
+  expected_status.add({
+      'P'       : Item(status='A ', wc_rev=0),
+      'P/Q'     : Item(status='A ', wc_rev=0),
+      'P/Q/foo' : Item(status='A ', wc_rev=0),
+      })
+  expected_skip = wc.State('', { })
+
+  # Failed with "The node 'P' was not found" when erroneously checking
+  # whether 'P/Q' should be deleted.
+  svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+                                       expected_output,
+                                       expected_disk,
+                                       expected_status,
+                                       expected_skip,
+                                       None, # expected err
+                                       1, # check-props
+                                       1) # dry-run
+
 ########################################################################
 #Run the tests
 
@@ -3845,6 +4007,9 @@ test_list = [ None,
               patch_reversed_add_with_props2,
               patch_dev_null,
               patch_delete_and_skip,
+              patch_lacking_trailing_eol,
+              patch_target_no_eol_at_eof,
+              patch_add_and_delete,
             ]
 
 if __name__ == '__main__':

Modified: subversion/branches/1.7.x-r1210147/subversion/tests/cmdline/special_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1210147/subversion/tests/cmdline/special_tests.py?rev=1245385&r1=1245384&r2=1245385&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1210147/subversion/tests/cmdline/special_tests.py (original)
+++ subversion/branches/1.7.x-r1210147/subversion/tests/cmdline/special_tests.py Fri Feb 17 10:52:38 2012
@@ -551,7 +551,9 @@ def diff_symlink_to_dir(sbox):
     "___________________________________________________________________\n",
     "Added: svn:special\n",
     "## -0,0 +1 ##\n",
-    "+*\n" ]
+    "+*\n",
+    "\\ No newline at end of property\n"
+  ]
   svntest.actions.run_and_verify_svn(None, expected_output, [], 'diff',
                                      '.')
   # We should get the same output if we the diff the symlink itself.