Code

git-svn: fix commiting renames over DAV with funky file names
authorEric Wong <normalperson@yhbt.net>
Mon, 16 Jul 2007 04:53:50 +0000 (21:53 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 16 Jul 2007 05:35:09 +0000 (22:35 -0700)
Renaming files with non-URI friendly characters caused
breakage when committing to DAV repositories (over http(s)).

Even if I try leaving out the $self->{url} from the return value
of url_path(), a partial (without host), unescaped path name
does not work.

Filenames for DAV repos need to be URI-encoded before being
passed to the library.  Since this bug did not affect file://
and svn:// repos, the git-svn test library needed to be expanded
to include support for starting Apache with mod_dav_svn enabled.

This new test is not enabled by default, but can be enabled by
setting SVN_HTTPD_PORT to any available TCP/IP port on
127.0.0.1.

Additionally, for running this test, the following variables
(with defaults shown) can be changed for the suitable system.
The default values are set for Debian systems:

  SVN_HTTPD_MODULE_PATH=/usr/lib/apache2/modules
  SVN_HTTPD_PATH=/usr/sbin/apache2

Signed-off-by: Eric Wong <normalperson@yhbt.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
git-svn.perl
t/lib-git-svn.sh
t/t9115-git-svn-dcommit-funky-renames.sh [new file with mode: 0755]
t/t9115/funky-names.dump [new file with mode: 0644]

index 299b40f93829eeef982b04f7f53dbb2d6baf9a6a..01c39042717c60c9a5b100ac60d2569c991736ea 100755 (executable)
@@ -2724,6 +2724,9 @@ sub repo_path {
 
 sub url_path {
        my ($self, $path) = @_;
+       if ($self->{url} =~ m#^https?://#) {
+               $path =~ s/([^a-zA-Z0-9_.-])/uc sprintf("%%%02x",ord($1))/eg;
+       }
        $self->{url} . '/' . $self->repo_path($path);
 }
 
index f6fe78cd278bd25f47b8c17e14f5f419d639fb7a..8d4a44721380213369668ea74dc4dbe3cf360485 100644 (file)
@@ -48,3 +48,37 @@ svnrepo="file://$svnrepo"
 poke() {
        test-chmtime +1 "$1"
 }
+
+SVN_HTTPD_MODULE_PATH=${SVN_HTTPD_MODULE_PATH-'/usr/lib/apache2/modules'}
+SVN_HTTPD_PATH=${SVN_HTTPD_PATH-'/usr/sbin/apache2'}
+
+start_httpd () {
+       if test -z "$SVN_HTTPD_PORT"
+       then
+               echo >&2 'SVN_HTTPD_PORT is not defined!'
+               return
+       fi
+
+       mkdir "$GIT_DIR"/logs
+
+       cat > "$GIT_DIR/httpd.conf" <<EOF
+ServerName "git-svn test"
+ServerRoot "$GIT_DIR"
+DocumentRoot "$GIT_DIR"
+PidFile "$GIT_DIR/httpd.pid"
+Listen 127.0.0.1:$SVN_HTTPD_PORT
+LoadModule dav_module $SVN_HTTPD_MODULE_PATH/mod_dav.so
+LoadModule dav_svn_module $SVN_HTTPD_MODULE_PATH/mod_dav_svn.so
+<Location /svn>
+       DAV svn
+       SVNPath $rawsvnrepo
+</Location>
+EOF
+       "$SVN_HTTPD_PATH" -f "$GIT_DIR"/httpd.conf -k start
+       svnrepo=http://127.0.0.1:$SVN_HTTPD_PORT/svn
+}
+
+stop_httpd () {
+       test -z "$SVN_HTTPD_PORT" && return
+       "$SVN_HTTPD_PATH" -f "$GIT_DIR"/httpd.conf -k stop
+}
diff --git a/t/t9115-git-svn-dcommit-funky-renames.sh b/t/t9115-git-svn-dcommit-funky-renames.sh
new file mode 100755 (executable)
index 0000000..182299c
--- /dev/null
@@ -0,0 +1,54 @@
+#!/bin/sh
+#
+# Copyright (c) 2007 Eric Wong
+
+
+test_description='git-svn dcommit can commit renames of files with ugly names'
+
+. ./lib-git-svn.sh
+
+test_expect_success 'load repository with strange names' "
+       svnadmin load -q $rawsvnrepo < ../t9115/funky-names.dump &&
+       start_httpd
+       "
+
+test_expect_success 'init and fetch repository' "
+       git svn init $svnrepo &&
+       git svn fetch &&
+       git reset --hard git-svn
+       "
+
+test_expect_success 'create file in existing ugly and empty dir' '
+       mkdir "#{bad_directory_name}" &&
+       echo hi > "#{bad_directory_name}/ foo" &&
+       git update-index --add "#{bad_directory_name}/ foo" &&
+       git commit -m "new file in ugly parent" &&
+       git svn dcommit
+       '
+
+test_expect_success 'rename ugly file' '
+       git mv "#{bad_directory_name}/ foo" "file name with feces" &&
+       git commit -m "rename ugly file" &&
+       git svn dcommit
+       '
+
+test_expect_success 'rename pretty file' '
+       echo :x > pretty &&
+       git update-index --add pretty &&
+       git commit -m "pretty :x" &&
+       git svn dcommit &&
+       mkdir regular_dir_name &&
+       git mv pretty regular_dir_name/pretty &&
+       git commit -m "moved pretty file" &&
+       git svn dcommit
+       '
+
+test_expect_success 'rename pretty file into ugly one' '
+       git mv regular_dir_name/pretty "#{bad_directory_name}/ booboo" &&
+       git commit -m booboo &&
+       git svn dcommit
+       '
+
+stop_httpd
+
+test_done
diff --git a/t/t9115/funky-names.dump b/t/t9115/funky-names.dump
new file mode 100644 (file)
index 0000000..42422f7
--- /dev/null
@@ -0,0 +1,103 @@
+SVN-fs-dump-format-version: 2
+
+UUID: 819c44fe-2bcc-4066-88e4-985e2bc0b418
+
+Revision-number: 0
+Prop-content-length: 56
+Content-length: 56
+
+K 8
+svn:date
+V 27
+2007-07-12T07:54:26.062914Z
+PROPS-END
+
+Revision-number: 1
+Prop-content-length: 152
+Content-length: 152
+
+K 7
+svn:log
+V 44
+what will those wacky people think of next?
+
+K 10
+svn:author
+V 12
+normalperson
+K 8
+svn:date
+V 27
+2007-07-12T08:00:05.011573Z
+PROPS-END
+
+Node-path:  leading space
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
+
+
+Node-path:  leading space file
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 5
+Text-content-md5: e4fa20c67542cdc21271e08d329397ab
+Content-length: 15
+
+PROPS-END
+ugly
+
+
+Node-path: #{bad_directory_name}
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
+
+
+Node-path: #{cool_name}
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 18
+Text-content-md5: 87dac40ca337dfa3dcc8911388c3ddda
+Content-length: 28
+
+PROPS-END
+strange name here
+
+
+Node-path: dir name with spaces
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
+
+
+Node-path: file name with spaces
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 7
+Text-content-md5: c1f10cfd640618484a2a475c11410fd3
+Content-length: 17
+
+PROPS-END
+spaces
+
+
+Node-path: regular_dir_name
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END