Hello! I've found a bug when applying a patch in Git format to the working copy root. Steps to reproduce:
#!/bin/sh SVN=svn #1. Create an empty SVN repository. REPOSITORY_PATH="$PWD/svn.repo" svnadmin create "$REPOSITORY_PATH" # 2. Create a patch that sets some property on a root directory. E.g. WC_PATH="/tmp/wc" REPOSITORY_URL="file://$REPOSITORY_PATH" PATCH_PATH=/tmp/patch EXPECTED_PROPERTY_VALUE=value $SVN co $REPOSITORY_URL $WC_PATH svn propset svn:ignore $EXPECTED_PROPERTY_VALUE $WC_PATH $SVN diff --git $WC_PATH > $PATCH_PATH # 3. Create another clean working copy for that repository # E.g. we can just clean an existing one: $SVN revert $WC_PATH # 4. Apply the patch $SVN patch $PATCH_PATH $WC_PATH # 5. Check the property of $WC_PATH ACTUAL_PROPERTY_VALUE=`svn propget svn:ignore $WC_PATH` echo "====" if [ x"$EXPECTED_PROPERTY_VALUE" != x"$ACTUAL_PROPERTY_VALUE" ] ; then echo "Bug!" echo "Expected value: $EXPECTED_PROPERTY_VALUE" echo "Actual value: $ACTUAL_PROPERTY_VALUE" else echo "Test passed!" fi echo "====" Note that the patch looks like Index: /tmp/wc =================================================================== diff --git a/ b/ --- a/ (revision 0) +++ b/ (working copy) Property changes on: ___________________________________________________________________ Added: svn:ignore ## -0,0 +1 ## +value The problem happens in parse-diff.c in git_start() function when parsing diff --git a/ b/ line in 2 places. The first one is: if (! *(new_path_marker + 3)) { *new_state = state_start; return SVN_NO_ERROR; } We get inside the check as there's no continuation after "b/" and SVN thinks the patch is invalid. Another place is: /* No path after the marker. */ if (! *new_path_start) break; The logic is the same. When I comment out both check the code works correctly even though now there's an asymmetry between "old" and "new" path processing code. [[[ Fix "patch" command: allow empty path when patch is in Git format. * subversion/libsvn_diff/parse-diff.c (git_start): Remove empty path checks. ]]] [[[ Index: subversion/libsvn_diff/parse-diff.c =================================================================== --- subversion/libsvn_diff/parse-diff.c (revision 1835430) +++ subversion/libsvn_diff/parse-diff.c (working copy) @@ -1587,12 +1587,6 @@ git_start(enum parse_state *new_state, char *line, return SVN_NO_ERROR; } - if (! *(new_path_marker + 3)) - { - *new_state = state_start; - return SVN_NO_ERROR; - } - /* By now, we know that we have a line on the form '--git diff a/.+ b/.+' * We only need the filenames when we have deleted or added empty * files. In those cases the old_path and new_path is identical on the @@ -1616,10 +1610,6 @@ git_start(enum parse_state *new_state, char *line, old_path_end = new_path_marker; new_path_start = new_path_marker + STRLEN_LITERAL(" b/"); - /* No path after the marker. */ - if (! *new_path_start) - break; - len_old = old_path_end - old_path_start; len_new = new_path_end - new_path_start; ]]] -- Dmitry Pavlenko, TMate Software, http://subgit.com/ - git-svn bridge