{"thread":{"id":"7858","subject":"[RFH] git-svn: sanitizing refnames","startedAt":"2007-04-26T19:49:01Z","lastAt":"2007-04-26T19:49:01Z","messageCount":1,"participants":["Eric Wong"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"40528","messageId":"20070426194901.GA913@untitled","threadId":"7858","inReplyTo":null,"subject":"[RFH] git-svn: sanitizing refnames","fromName":"Eric Wong","fromEmail":"normalperson@yhbt.net","sentAt":"2007-04-26T19:49:01Z","receivedAt":"2007-04-26T19:49:01Z","isPatch":false,"sender":{"key":"e@80x24.org","avatar":null},"body":"I had a small pocket of time on Sunday and started working on this, but\nprobably won't finish soon (the segfault issue take precedence, and\n*that* is taking a while to complete with other things going on...).\n\nProblem: git-svn maps directory names (branches and tags) from SVN into\nrefnames for git.  Unfortunately, some SVN users create branches and\ntags with characters that git doesn't like.\n\nBelow is my work-in-progress patch to handle sanitation of\nrefnames.\n\nIt seems that storing a refmap dictionary in .git/config (or\ngit/svn/config) of already-translated refnames is necessary\nso we can avoid conflicts with different refs sanitizing.\n\nHow to populate that dictionary is another problem.  Should we prompt\nthe user for input[1]?  Or should we just escape and append[2] characters\nto the end?\n\nWe could probably just copy and modify the uri_encode() function\nto %xx escape all the characters we don't like, and append '-'\n\n\n[1] - keep in mind that some people probably run cron-jobs to keep\ntheir mirrors synced.\n[2] - parent following appends a \"@<revision_number>\", and\nthen enough '-'s until it's unique.\n\ndiff --git a/git-svn.perl b/git-svn.perl\nindex 4ea6f20..8d08572 100755\n--- a/git-svn.perl\n+++ b/git-svn.perl\n@@ -987,6 +987,29 @@ sub sanitize_remote_name {\n \t$name;\n }\n \n+sub sanitize_ref_name {\n+\tmy ($ref) = @_;\n+\teval { command('check-ref-format', $ref) };\n+\treturn unless $@;\n+\tmy ($cfg, $ctx) = command_output_pipe('config', '--get-all',\n+\t                                      \"svn-remote.$repo_id.refmap\");\n+\tmy $ref_encoded = uri_encode($ref);\n+\tmy $re = qr/^\\Q$ref_encoded\\E=/;\n+\tmy $ret;\n+\twhile (<$ls>) {\n+\t\tnext unless s/$re//;\n+\t\tchomp;\n+\t\t$ret = $_;\n+\t\tlast;\n+\t}\n+\tclose $cfg; # break the pipe\n+\tunless (defined $ret) {\n+\t\tcommand_noisy('config', '--add', \"svn-remote.$repo_id.refmap\",\n+\t\t              \"$ref_encoded=$ret\");\n+\t}\n+\t$ret;\n+}\n+\n sub find_existing_remote {\n \tmy ($url, $remotes) = @_;\n \treturn undef if $no_reuse_existing;\n@@ -2088,6 +2111,7 @@ sub _new {\n \t\t$_[2] = $ref_id = $Git::SVN::default_ref_id;\n \t}\n \t$_[1] = $repo_id = sanitize_remote_name($repo_id);\n+\t$_[2] = $ref_id = sanitize_ref_name($repo_id, $ref_id);\n \tmy $dir = \"$ENV{GIT_DIR}/svn/$ref_id\";\n \t$_[3] = $path = '' unless (defined $path);\n \tmkpath([\"$ENV{GIT_DIR}/svn\"]);\n-- \nEric Wong\n"}]}