{"thread":{"id":"9258","subject":"[PATCH] git-svn: Translate invalid characters in refname","startedAt":"2007-07-27T14:40:07Z","lastAt":"2007-07-27T14:40:07Z","messageCount":1,"participants":["Robert Ewald"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"48801","messageId":"f8d04a$gvf$1@sea.gmane.org","threadId":"9258","inReplyTo":null,"subject":"[PATCH] git-svn: Translate invalid characters in refname","fromName":"Robert Ewald","fromEmail":"robert.ewald@nov.com","sentAt":"2007-07-27T14:40:07Z","receivedAt":"2007-07-27T14:40:07Z","isPatch":true,"sender":{"key":"robert.ewald@nov.com","avatar":null},"body":"Hello,\n\nMy first patch, please be gentle.\n\nThis is a first attempt to get the escaping behavior into git-svn.\nI hope I have not screwed up too badly since this I have been looking\nat Perl for more or less the first time.\n\nSo I would appreciate if any mistakes would be pointed out to me.\n\nThe patch works for me during clone, fetch and dcommit. I haven't\ntried anything else yet.\n\nRobert\n\nPS: There is a testing script I have used. I suppose it should be put into\nthe testing infrastructure, something I am not yet familiar with. If\nsomeone is interested I can send it as is.\n\n---\n\nIn git some characters are invalid as documented\nin git-check-ref-format. In subversion these characters might\nbe valid, so a translation is required.\n\nThis patch does this translation by url escaping characters, that\nare not allowed.\n\nCredit for ideas and code snippets goes to Eric Wong, martin f. krafft and\nJan Hudec\n\nSigned-off-by: Robert Ewald <robewald@gmx.net>\n---\n git-svn.perl |   43 ++++++++++++++++++++++++++++++++++++++++---\n 1 files changed, 40 insertions(+), 3 deletions(-)\n\ndiff --git a/git-svn.perl b/git-svn.perl\nindex 6c692a7..68e62ab 100755\n--- a/git-svn.perl\n+++ b/git-svn.perl\n@@ -938,8 +938,8 @@ sub resolve_local_globs {\n        foreach (command(qw#for-each-ref --format=%(refname) refs/remotes#)) {\n                next unless m#^refs/remotes/$ref->{regex}$#;\n                my $p = $1;\n-               my $pathname = $path->full_path($p);\n-               my $refname = $ref->full_path($p);\n+               my $pathname = desanitize_refname($path->full_path($p));\n+               my $refname = desanitize_refname($ref->full_path($p));\n                if (my $existing = $fetch->{$pathname}) {\n                        if ($existing ne $refname) {\n                                die \"Refspec conflict:\\n\",\n@@ -1239,7 +1239,44 @@ sub new {\n        $self;\n }\n \n-sub refname { \"refs/remotes/$_[0]->{ref_id}\" }\n+sub refname { \n+        my ($refname) = \"refs/remotes/$_[0]->{ref_id}\" ;\n+\n+        # It cannot end with a slash /, we'll throw up on this because\n+        # SVN can't have directories with a slash in their name, either:\n+        if ($refname =~ m{/$}) {\n+                die \"ref: '$refname' ends with a trailing slash, this is \",\n+                    \"not permitted by git nor Subversion\\n\";\n+        }\n+\n+        # It cannot have ASCII control character space, tilde ~, caret ^,\n+        # colon :, question-mark ?, asterisk *, space, or open bracket[\nanywhere\n+       #\n+        # Additionally, % must be escaped because it is used for escaping\n+        # and we want our escaped refname to be reversible\n+        $refname =~ s{([ \\%~\\^:\\?\\*\\[\\t])}{uc sprintf('%%%02x',ord($1))}eg;\n+\n+        # no slash-separated component can begin with a dot .\n+        # /.* becomes /%2E*\n+        $refname =~ s{/\\.}{/%2E}g;\n+        # It cannot have two consecutive dots .. anywhere\n+        # .. becomes %2E%2E\n+        $refname =~ s{\\.\\.}{%2E%2E}g;\n+\n+        $refname;\n+}\n+\n+sub desanitize_refname {\n+    my ($refname) = @_;\n+\n+    print \"bob: desanitized from $refname \";\n+\n+    $refname =~ s{%(?:([0-9A-F]{2}))}{chr hex($1)}eg;\n+\n+    print \" to $refname \\n\";\n+\n+    $refname;\n+}\n \n sub svm_uuid {\n        my ($self) = @_;\n-- \n1.5.3.rc3-dirty\n\n-- \nRobert Ewald\n"}]}