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