{"thread":{"id":"9598","subject":"[PATCH] Allow multiple tag and branch directories in git-svnimport","startedAt":"2007-08-21T17:08:58Z","lastAt":"2007-08-22T10:24:15Z","messageCount":4,"participants":["Stefan Sperling","Randal L. Schwartz"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"51178","messageId":"20070821170858.GA1721@jack.stsp.lan","threadId":"9598","inReplyTo":null,"subject":"[PATCH] Allow multiple tag and branch directories in git-svnimport","fromName":"Stefan Sperling","fromEmail":"stsp@elego.de","sentAt":"2007-08-21T17:08:58Z","receivedAt":"2007-08-21T17:08:58Z","isPatch":true,"sender":{"key":"stsp@elego.de","avatar":"https://avatars.githubusercontent.com/u/9281333?v=4"},"body":"With this patch, users can specify colon-seperated lists of\ndirectories containing tags and branches, respectively.\n\nThis makes git-svnimport much more usable in the real world\nbecause there are Subversion repositories that use a deeper\ntag and branch hierarchy than the recommended hierarchy of\n\n\ttrunk/\n\ttags/\n\tbranches/\n\nThe patch assumes my memleak fix patch from\nhttp://marc.info/?l=git&m=118554191513822&w=2\nbut applies cleanly to current vanilla git head as well.\n\nI'm not subscribed to the list so please Cc me in replies, thanks.\n\n\ndiff --git a/Documentation/git-svnimport.txt b/Documentation/git-svnimport.txt\nindex e97d15e..2cfc407 100644\n--- a/Documentation/git-svnimport.txt\n+++ b/Documentation/git-svnimport.txt\n@@ -12,11 +12,11 @@ SYNOPSIS\n [verse]\n 'git-svnimport' [ -o <branch-for-HEAD> ] [ -h ] [ -v ] [ -d | -D ]\n \t\t[ -C <GIT_repository> ] [ -i ] [ -u ] [-l limit_rev]\n-\t\t[ -b branch_subdir ] [ -T trunk_subdir ] [ -t tag_subdir ]\n-\t\t[ -s start_chg ] [ -m ] [ -r ] [ -M regex ]\n-\t\t[ -I <ignorefile_name> ] [ -A <author_file> ]\n-\t\t[ -R <repack_each_revs>] [ -P <path_from_trunk> ]\n-\t\t<SVN_repository_URL> [ <path> ]\n+\t\t[ -b branch_subdir[:branch_subdir:...] ] [ -T trunk_subdir ]\n+\t\t[ -t tag_subdir[:tag_subdir:...] ] [ -s start_chg ] [ -m ]\n+\t\t[ -r ] [ -M regex ] [ -I <ignorefile_name> ]\n+\t\t[ -A <author_file> ] [ -R <repack_each_revs>]\n+\t\t[ -P <path_from_trunk> ] <SVN_repository_URL> [ <path> ]\n \n \n DESCRIPTION\n@@ -26,11 +26,6 @@ repository, or incrementally import into an existing one.\n \n SVN access is done by the SVN::Perl module.\n \n-git-svnimport assumes that SVN repositories are organized into one\n-\"trunk\" directory where the main development happens, \"branches/FOO\"\n-directories for branches, and \"/tags/FOO\" directories for tags.\n-Other subdirectories are ignored.\n-\n git-svnimport creates a file \".git/svn2git\", which is required for\n incremental SVN imports.\n \n@@ -53,11 +48,13 @@ When importing incrementally, you might need to edit the .git/svn2git file.\n -T <trunk_subdir>::\n \tName the SVN trunk. Default \"trunk\".\n \n--t <tag_subdir>::\n-\tName the SVN subdirectory for tags. Default \"tags\".\n+-t <tag_subdir[:tag_subdir:..]>::\n+\tColon-seperated list of names of subdirectories containing tags.\n+\tDefault \"tags\".\n \n--b <branch_subdir>::\n-\tName the SVN subdirectory for branches. Default \"branches\".\n+-b <branch_subdir[:branch_subdir:...]>::\n+\tColon-seperated list of names of subdirectories containing branches.\n+\tDefault \"branches\".\n \n -o <branch-for-HEAD>::\n \tThe 'trunk' branch from SVN is imported to the 'origin' branch within\ndiff --git a/git-svnimport.perl b/git-svnimport.perl\nindex fc9ea71..96f0926 100755\n--- a/git-svnimport.perl\n+++ b/git-svnimport.perl\n@@ -38,9 +38,10 @@ sub usage() {\n \tprint STDERR <<END;\n Usage: ${\\basename $0}     # fetch/update GIT from SVN\n        [-o branch-for-HEAD] [-h] [-v] [-l max_rev] [-R repack_each_revs]\n-       [-C GIT_repository] [-t tagname] [-T trunkname] [-b branchname]\n-       [-d|-D] [-i] [-u] [-r] [-I ignorefilename] [-s start_chg]\n-       [-m] [-M regex] [-A author_file] [-S] [-F] [-P project_name] [SVN_URL]\n+       [-C GIT_repository] [-t tag_subdir[:tag_subdir:...]] [-T trunk_subdir]\n+       [-b branch_subdir[:branch_subdir:...]] [-d|-D] [-i] [-u] [-r]\n+       [-I ignorefilename] [-s start_chg] [-m] [-M regex]\n+       [-A author_file] [-S] [-F] [-P project_name] [SVN_URL]\n END\n \texit(1);\n }\n@@ -48,9 +49,9 @@ END\n getopts(\"A:b:C:dDFhiI:l:mM:o:rs:t:T:SP:R:uv\") or usage();\n usage if $opt_h;\n \n-my $tag_name = $opt_t || \"tags\";\n-my $trunk_name = defined $opt_T ? $opt_T : \"trunk\";\n-my $branch_name = $opt_b || \"branches\";\n+my @tag_dirs = defined $opt_t ? split /:/,$opt_t : \"tags\";\n+my $trunk_dir = defined $opt_T ? $opt_T : \"trunk\";\n+my @branch_dirs = defined $opt_b ? split /:/,$opt_b : \"branches\";\n my $project_name = $opt_P || \"\";\n $project_name = \"/\" . $project_name if ($project_name);\n my $repack_after = $opt_R || 1000;\n@@ -68,14 +69,18 @@ my $svn_dir = $ARGV[1];\n \n our @mergerx = ();\n if ($opt_m) {\n-\tmy $branch_esc = quotemeta ($branch_name);\n-\tmy $trunk_esc  = quotemeta ($trunk_name);\n-\t@mergerx =\n-\t(\n-\t\tqr!\\b(?:merg(?:ed?|ing))\\b.*?\\b((?:(?<=$branch_esc/)[\\w\\.\\-]+)|(?:$trunk_esc))\\b!i,\n-\t\tqr!\\b(?:from|of)\\W+((?:(?<=$branch_esc/)[\\w\\.\\-]+)|(?:$trunk_esc))\\b!i,\n-\t\tqr!\\b(?:from|of)\\W+(?:the )?([\\w\\.\\-]+)[-\\s]branch\\b!i\n-\t);\n+\tmy @branch_escs;\n+\tforeach (@branch_dirs) { push @branch_escs, quotemeta ($_); }\n+\tmy $trunk_esc  = quotemeta ($trunk_dir);\n+\n+\tforeach my $branch_esc (@branch_escs) {\n+\t\tpush (@mergerx,\n+\t\t(\n+\t\t\tqr!\\b(?:merg(?:ed?|ing))\\b.*?\\b((?:(?<=$branch_esc/)[\\w\\.\\-]+)|(?:$trunk_esc))\\b!i,\n+\t\t\tqr!\\b(?:from|of)\\W+((?:(?<=$branch_esc/)[\\w\\.\\-]+)|(?:$trunk_esc))\\b!i,\n+\t\t\tqr!\\b(?:from|of)\\W+(?:the )?([\\w\\.\\-]+)[-\\s]branch\\b!i\n+\t\t));\n+\t}\n }\n if ($opt_M) {\n \tunshift (@mergerx, qr/$opt_M/);\n@@ -452,29 +457,39 @@ sub project_path($$)\n \n sub split_path($$) {\n \tmy($rev,$path) = @_;\n-\tmy $branch;\n+\tmy $dir; # tag or branch dir\n+\n+\tOUTER: foreach my $tag_dir (@tag_dirs) {\n+\t\tforeach my $branch_dir (@branch_dirs) {\n+\t\t\tif ($path =~ s#^/\\Q$tag_dir\\E/([^/]+)/?##) {\n+\t\t\t\t$dir = \"/$1\";\n+\t\t\t} elsif ($path =~ s#^/\\Q$trunk_dir\\E/?##) {\n+\t\t\t\t$dir = \"/\";\n+\t\t\t} elsif ($path =~ s#^/\\Q$branch_dir\\E/([^/]+)/?##) {\n+\t\t\t\t$dir = $1;\n+\t\t\t}\n+\t\t\tlast OUTER if $dir;\n+\t\t}\n+\t}\n \n-\tif($path =~ s#^/\\Q$tag_name\\E/([^/]+)/?##) {\n-\t\t$branch = \"/$1\";\n-\t} elsif($path =~ s#^/\\Q$trunk_name\\E/?##) {\n-\t\t$branch = \"/\";\n-\t} elsif($path =~ s#^/\\Q$branch_name\\E/([^/]+)/?##) {\n-\t\t$branch = $1;\n-\t} else {\n-\t\tmy %no_error = (\n-\t\t\t\"/\" => 1,\n-\t\t\t\"/$tag_name\" => 1,\n-\t\t\t\"/$branch_name\" => 1\n-\t\t);\n-\t\tprint STDERR \"$rev: Unrecognized path: $path\\n\" unless (defined $no_error{$path});\n-\t\treturn ()\n+\tif (! $dir) {\n+\t\tmy %no_error = ( \"/\" => 1, \"/tags\" => 1, \"/branches\" => 1 );\n+\t\tforeach (@tag_dirs) {\n+\t\t\t$no_error{\"/$_\"} = 1;\n+\t\t}\n+\t\tforeach (@branch_dirs) {\n+\t\t\t$no_error{\"/$_\"} = 1;\n+\t\t}\n+\t\tprint STDERR \"$rev: Could not determine tag or branch \",\n+\t\t\t\"directory for path '$path'\\n\",\n+\t\t\tunless (defined $no_error{$path});\n \t}\n \tif ($path eq \"\") {\n \t\t$path = \"/\";\n \t} elsif ($project_name) {\n \t\t$path = project_path($path, $project_name);\n \t}\n-\treturn ($branch,$path);\n+\treturn ($dir,$path);\n }\n \n sub branch_rev($$) {\n@@ -874,9 +889,32 @@ sub commit {\n \n \t\t$dest =~ tr/_/\\./ if $opt_u;\n \n-\t\tsystem('git-tag', $dest, $cid) == 0\n-\t\t\tor die \"Cannot create tag $dest: $!\\n\";\n-\n+\t\t# Since we support multiple directories that host tags we\n+\t\t# must support repositories that contain the same tag name\n+\t\t# in different tag directories for whatever reason,\n+\t\t# e.g. tags/jim/1.0-rc3 and tags/huck/1.0-rc3\n+\t\t#\n+\t\t# Also, because in Subversion a given tag directory could\n+\t\t# exist in revision A, be deleted in revision B and later\n+\t\t# recreated under the same name in revision C, we\n+\t\t# cannot guarantee that a tag is unique simply by\n+\t\t# looking at the tag's path.\n+\t\t#\n+\t\t# So if we fail to create the tag the first time, we try\n+\t\t# to create the tag with the same name except with the\n+\t\t# revision number of the current commit appended.\n+\t\t# Users can rename tags again later after the repository\n+\t\t# has been converted if they don't like this.\n+\t\t# It's still much better than failing to convert the\n+\t\t# repository alltogether.\n+\t\tif (system('git-tag', $dest, $cid) != 0) {\n+\t\t\tprint STDERR \"Could not create tag $dest, \",\n+\t\t\t\t\"trying to create tag $dest-r$revision \",\n+\t\t\t\t\"instead\\n\";\n+\t\t\t$dest = \"$dest-r$revision\";\n+\t\t\tsystem('git-tag', $dest, $cid) == 0\n+\t\t\t\tor die \"Cannot create tag $dest: $? $!\\n\";\n+\t\t}\n \t\tprint \"Created tag '$dest' on '$branch'\\n\" if $opt_v;\n \t}\n \t$branches{$branch}{\"LAST\"} = $cid;\n\n-- \nStefan Sperling <stsp@elego.de>                 Software Developer\nelego Software Solutions GmbH                            HRB 77719\nGustav-Meyer-Allee 25, Gebaeude 12        Tel:  +49 30 23 45 86 96 \n13355 Berlin                              Fax:  +49 30 23 45 86 95\nhttp://www.elego.de                 Geschaeftsfuehrer: Olaf Wagner\n"},{"id":"51183","messageId":"20070821173838.GC1721@jack.stsp.lan","threadId":"9598","inReplyTo":"20070821170858.GA1721@jack.stsp.lan","subject":"Re: [PATCH] Allow multiple tag and branch directories in git-svnimport","fromName":"Stefan Sperling","fromEmail":"stsp@elego.de","sentAt":"2007-08-21T17:38:38Z","receivedAt":"2007-08-21T17:38:38Z","isPatch":true,"sender":{"key":"stsp@elego.de","avatar":"https://avatars.githubusercontent.com/u/9281333?v=4"},"body":"On Tue, Aug 21, 2007 at 07:08:58PM +0200, Stefan Sperling wrote:\n> +my @tag_dirs = defined $opt_t ? split /:/,$opt_t : \"tags\";\n      ^                                                ^^^^^\n> +my @branch_dirs = defined $opt_b ? split /:/,$opt_b : \"branches\";\n      ^                                                  ^^^^^^^^^^\n\nOuch, just noticed it's a bad idea to try to initialise\nan array with a scalar. Sorry :-/\n\nUpdated diff:\n\ndiff --git a/Documentation/git-svnimport.txt b/Documentation/git-svnimport.txt\nindex e97d15e..2cfc407 100644\n--- a/Documentation/git-svnimport.txt\n+++ b/Documentation/git-svnimport.txt\n@@ -12,11 +12,11 @@ SYNOPSIS\n [verse]\n 'git-svnimport' [ -o <branch-for-HEAD> ] [ -h ] [ -v ] [ -d | -D ]\n \t\t[ -C <GIT_repository> ] [ -i ] [ -u ] [-l limit_rev]\n-\t\t[ -b branch_subdir ] [ -T trunk_subdir ] [ -t tag_subdir ]\n-\t\t[ -s start_chg ] [ -m ] [ -r ] [ -M regex ]\n-\t\t[ -I <ignorefile_name> ] [ -A <author_file> ]\n-\t\t[ -R <repack_each_revs>] [ -P <path_from_trunk> ]\n-\t\t<SVN_repository_URL> [ <path> ]\n+\t\t[ -b branch_subdir[:branch_subdir:...] ] [ -T trunk_subdir ]\n+\t\t[ -t tag_subdir[:tag_subdir:...] ] [ -s start_chg ] [ -m ]\n+\t\t[ -r ] [ -M regex ] [ -I <ignorefile_name> ]\n+\t\t[ -A <author_file> ] [ -R <repack_each_revs>]\n+\t\t[ -P <path_from_trunk> ] <SVN_repository_URL> [ <path> ]\n \n \n DESCRIPTION\n@@ -26,11 +26,6 @@ repository, or incrementally import into an existing one.\n \n SVN access is done by the SVN::Perl module.\n \n-git-svnimport assumes that SVN repositories are organized into one\n-\"trunk\" directory where the main development happens, \"branches/FOO\"\n-directories for branches, and \"/tags/FOO\" directories for tags.\n-Other subdirectories are ignored.\n-\n git-svnimport creates a file \".git/svn2git\", which is required for\n incremental SVN imports.\n \n@@ -53,11 +48,13 @@ When importing incrementally, you might need to edit the .git/svn2git file.\n -T <trunk_subdir>::\n \tName the SVN trunk. Default \"trunk\".\n \n--t <tag_subdir>::\n-\tName the SVN subdirectory for tags. Default \"tags\".\n+-t <tag_subdir[:tag_subdir:..]>::\n+\tColon-seperated list of names of subdirectories containing tags.\n+\tDefault \"tags\".\n \n--b <branch_subdir>::\n-\tName the SVN subdirectory for branches. Default \"branches\".\n+-b <branch_subdir[:branch_subdir:...]>::\n+\tColon-seperated list of names of subdirectories containing branches.\n+\tDefault \"branches\".\n \n -o <branch-for-HEAD>::\n \tThe 'trunk' branch from SVN is imported to the 'origin' branch within\ndiff --git a/git-svnimport.perl b/git-svnimport.perl\nindex fc9ea71..96f0926 100755\n--- a/git-svnimport.perl\n+++ b/git-svnimport.perl\n@@ -38,9 +38,10 @@ sub usage() {\n \tprint STDERR <<END;\n Usage: ${\\basename $0}     # fetch/update GIT from SVN\n        [-o branch-for-HEAD] [-h] [-v] [-l max_rev] [-R repack_each_revs]\n-       [-C GIT_repository] [-t tagname] [-T trunkname] [-b branchname]\n-       [-d|-D] [-i] [-u] [-r] [-I ignorefilename] [-s start_chg]\n-       [-m] [-M regex] [-A author_file] [-S] [-F] [-P project_name] [SVN_URL]\n+       [-C GIT_repository] [-t tag_subdir[:tag_subdir:...]] [-T trunk_subdir]\n+       [-b branch_subdir[:branch_subdir:...]] [-d|-D] [-i] [-u] [-r]\n+       [-I ignorefilename] [-s start_chg] [-m] [-M regex]\n+       [-A author_file] [-S] [-F] [-P project_name] [SVN_URL]\n END\n \texit(1);\n }\n@@ -48,9 +49,9 @@ END\n getopts(\"A:b:C:dDFhiI:l:mM:o:rs:t:T:SP:R:uv\") or usage();\n usage if $opt_h;\n \n-my $tag_name = $opt_t || \"tags\";\n-my $trunk_name = defined $opt_T ? $opt_T : \"trunk\";\n-my $branch_name = $opt_b || \"branches\";\n+my @tag_dirs = defined $opt_t ? split /:/,$opt_t : (\"tags\");\n+my $trunk_dir = defined $opt_T ? $opt_T : \"trunk\";\n+my @branch_dirs = defined $opt_b ? split /:/,$opt_b : (\"branches\");\n my $project_name = $opt_P || \"\";\n $project_name = \"/\" . $project_name if ($project_name);\n my $repack_after = $opt_R || 1000;\n@@ -68,14 +69,18 @@ my $svn_dir = $ARGV[1];\n \n our @mergerx = ();\n if ($opt_m) {\n-\tmy $branch_esc = quotemeta ($branch_name);\n-\tmy $trunk_esc  = quotemeta ($trunk_name);\n-\t@mergerx =\n-\t(\n-\t\tqr!\\b(?:merg(?:ed?|ing))\\b.*?\\b((?:(?<=$branch_esc/)[\\w\\.\\-]+)|(?:$trunk_esc))\\b!i,\n-\t\tqr!\\b(?:from|of)\\W+((?:(?<=$branch_esc/)[\\w\\.\\-]+)|(?:$trunk_esc))\\b!i,\n-\t\tqr!\\b(?:from|of)\\W+(?:the )?([\\w\\.\\-]+)[-\\s]branch\\b!i\n-\t);\n+\tmy @branch_escs;\n+\tforeach (@branch_dirs) { push @branch_escs, quotemeta ($_); }\n+\tmy $trunk_esc  = quotemeta ($trunk_dir);\n+\n+\tforeach my $branch_esc (@branch_escs) {\n+\t\tpush (@mergerx,\n+\t\t(\n+\t\t\tqr!\\b(?:merg(?:ed?|ing))\\b.*?\\b((?:(?<=$branch_esc/)[\\w\\.\\-]+)|(?:$trunk_esc))\\b!i,\n+\t\t\tqr!\\b(?:from|of)\\W+((?:(?<=$branch_esc/)[\\w\\.\\-]+)|(?:$trunk_esc))\\b!i,\n+\t\t\tqr!\\b(?:from|of)\\W+(?:the )?([\\w\\.\\-]+)[-\\s]branch\\b!i\n+\t\t));\n+\t}\n }\n if ($opt_M) {\n \tunshift (@mergerx, qr/$opt_M/);\n@@ -452,29 +457,39 @@ sub project_path($$)\n \n sub split_path($$) {\n \tmy($rev,$path) = @_;\n-\tmy $branch;\n+\tmy $dir; # tag or branch dir\n+\n+\tOUTER: foreach my $tag_dir (@tag_dirs) {\n+\t\tforeach my $branch_dir (@branch_dirs) {\n+\t\t\tif ($path =~ s#^/\\Q$tag_dir\\E/([^/]+)/?##) {\n+\t\t\t\t$dir = \"/$1\";\n+\t\t\t} elsif ($path =~ s#^/\\Q$trunk_dir\\E/?##) {\n+\t\t\t\t$dir = \"/\";\n+\t\t\t} elsif ($path =~ s#^/\\Q$branch_dir\\E/([^/]+)/?##) {\n+\t\t\t\t$dir = $1;\n+\t\t\t}\n+\t\t\tlast OUTER if $dir;\n+\t\t}\n+\t}\n \n-\tif($path =~ s#^/\\Q$tag_name\\E/([^/]+)/?##) {\n-\t\t$branch = \"/$1\";\n-\t} elsif($path =~ s#^/\\Q$trunk_name\\E/?##) {\n-\t\t$branch = \"/\";\n-\t} elsif($path =~ s#^/\\Q$branch_name\\E/([^/]+)/?##) {\n-\t\t$branch = $1;\n-\t} else {\n-\t\tmy %no_error = (\n-\t\t\t\"/\" => 1,\n-\t\t\t\"/$tag_name\" => 1,\n-\t\t\t\"/$branch_name\" => 1\n-\t\t);\n-\t\tprint STDERR \"$rev: Unrecognized path: $path\\n\" unless (defined $no_error{$path});\n-\t\treturn ()\n+\tif (! $dir) {\n+\t\tmy %no_error = ( \"/\" => 1, \"/tags\" => 1, \"/branches\" => 1 );\n+\t\tforeach (@tag_dirs) {\n+\t\t\t$no_error{\"/$_\"} = 1;\n+\t\t}\n+\t\tforeach (@branch_dirs) {\n+\t\t\t$no_error{\"/$_\"} = 1;\n+\t\t}\n+\t\tprint STDERR \"$rev: Could not determine tag or branch \",\n+\t\t\t\"directory for path '$path'\\n\",\n+\t\t\tunless (defined $no_error{$path});\n \t}\n \tif ($path eq \"\") {\n \t\t$path = \"/\";\n \t} elsif ($project_name) {\n \t\t$path = project_path($path, $project_name);\n \t}\n-\treturn ($branch,$path);\n+\treturn ($dir,$path);\n }\n \n sub branch_rev($$) {\n@@ -874,9 +889,32 @@ sub commit {\n \n \t\t$dest =~ tr/_/\\./ if $opt_u;\n \n-\t\tsystem('git-tag', $dest, $cid) == 0\n-\t\t\tor die \"Cannot create tag $dest: $!\\n\";\n-\n+\t\t# Since we support multiple directories that host tags we\n+\t\t# must support repositories that contain the same tag name\n+\t\t# in different tag directories for whatever reason,\n+\t\t# e.g. tags/jim/1.0-rc3 and tags/huck/1.0-rc3\n+\t\t#\n+\t\t# Also, because in Subversion a given tag directory could\n+\t\t# exist in revision A, be deleted in revision B and later\n+\t\t# recreated under the same name in revision C, we\n+\t\t# cannot guarantee that a tag is unique simply by\n+\t\t# looking at the tag's path.\n+\t\t#\n+\t\t# So if we fail to create the tag the first time, we try\n+\t\t# to create the tag with the same name except with the\n+\t\t# revision number of the current commit appended.\n+\t\t# Users can rename tags again later after the repository\n+\t\t# has been converted if they don't like this.\n+\t\t# It's still much better than failing to convert the\n+\t\t# repository alltogether.\n+\t\tif (system('git-tag', $dest, $cid) != 0) {\n+\t\t\tprint STDERR \"Could not create tag $dest, \",\n+\t\t\t\t\"trying to create tag $dest-r$revision \",\n+\t\t\t\t\"instead\\n\";\n+\t\t\t$dest = \"$dest-r$revision\";\n+\t\t\tsystem('git-tag', $dest, $cid) == 0\n+\t\t\t\tor die \"Cannot create tag $dest: $? $!\\n\";\n+\t\t}\n \t\tprint \"Created tag '$dest' on '$branch'\\n\" if $opt_v;\n \t}\n \t$branches{$branch}{\"LAST\"} = $cid;\n\n-- \nStefan Sperling <stsp@elego.de>                 Software Developer\nelego Software Solutions GmbH                            HRB 77719\nGustav-Meyer-Allee 25, Gebaeude 12        Tel:  +49 30 23 45 86 96 \n13355 Berlin                              Fax:  +49 30 23 45 86 95\nhttp://www.elego.de                 Geschaeftsfuehrer: Olaf Wagner\n"},{"id":"51185","messageId":"86wsvook5s.fsf@blue.stonehenge.com","threadId":"9598","inReplyTo":"20070821173838.GC1721@jack.stsp.lan","subject":"Re: [PATCH] Allow multiple tag and branch directories in git-svnimport","fromName":"Randal L. Schwartz","fromEmail":"merlyn@stonehenge.com","sentAt":"2007-08-21T17:46:23Z","receivedAt":"2007-08-21T17:46:23Z","isPatch":true,"sender":{"key":"merlyn@stonehenge.com","avatar":"https://gravatar.com/avatar/dc528d210743ff0333e6213f9ee7b33b23f1b7bc1f3c5a8c2d819074ecd7ab19?d=mp&s=160"},"body":">>>>> \"Stefan\" == Stefan Sperling <stsp@elego.de> writes:\n\nStefan> On Tue, Aug 21, 2007 at 07:08:58PM +0200, Stefan Sperling wrote:\n>> +my @tag_dirs = defined $opt_t ? split /:/,$opt_t : \"tags\";\nStefan>       ^                                                ^^^^^\n>> +my @branch_dirs = defined $opt_b ? split /:/,$opt_b : \"branches\";\nStefan>       ^                                                  ^^^^^^^^^^\n\nStefan> Ouch, just noticed it's a bad idea to try to initialise\nStefan> an array with a scalar. Sorry :-/\n\nThat's completely normal.  Perl predictably promotes the single scalar to an\narray of one element.  I wouldn't have even noticed it in a detailed code\nreview, since it's so normal to do that.\n\nIn fact, the parens that you added do *not* make it a list.  The parens\nare purely for precedence in:\n\n    @a = (3, 5, 7);\n\nbecause otherwise, the text:\n\n    @a = 3, 5, 7;\n\nwould be parsed as:\n\n    (@a = 3), 5, 7;\n\nwhich would be pretty pointless.  It's the *comma* in a list context that\nmakes it a list.\n\nSo, your parens are not only uncommon, they are also completely ineffective,\nsimilar to replacing 2 + 3 with (2) + (3) :)\n\n-- \nRandal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095\n<merlyn@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>\nPerl/Unix/security consulting, Technical writing, Comedy, etc. etc.\nSee PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!\n"},{"id":"51240","messageId":"20070822102415.GA24305@jack.stsp.lan","threadId":"9598","inReplyTo":"86wsvook5s.fsf@blue.stonehenge.com","subject":"Re: [PATCH] Allow multiple tag and branch directories in git-svnimport","fromName":"Stefan Sperling","fromEmail":"stsp@elego.de","sentAt":"2007-08-22T10:24:15Z","receivedAt":"2007-08-22T10:24:15Z","isPatch":true,"sender":{"key":"stsp@elego.de","avatar":"https://avatars.githubusercontent.com/u/9281333?v=4"},"body":"On Tue, Aug 21, 2007 at 10:46:23AM -0700, Randal L. Schwartz wrote:\n> Stefan> Ouch, just noticed it's a bad idea to try to initialise\n> Stefan> an array with a scalar. Sorry :-/\n> \n> That's completely normal.  Perl predictably promotes the single scalar to an\n> array of one element.  I wouldn't have even noticed it in a detailed code\n> review, since it's so normal to do that.\n> \n> In fact, the parens that you added do *not* make it a list.  The parens\n> are purely for precedence\n\n> So, your parens are not only uncommon, they are also completely ineffective,\n> similar to replacing 2 + 3 with (2) + (3) :)\n\nThanks for clarifying. Prior to hacking on git-svnimport\nmy perl \"skills\" (if any) were strictly read-only.\nSo I'm quite a noob wrt perl.\nFeel free to nit the patch further :)\n\n-- \nStefan Sperling <stsp@elego.de>                 Software Developer\nelego Software Solutions GmbH                            HRB 77719\nGustav-Meyer-Allee 25, Gebaeude 12        Tel:  +49 30 23 45 86 96 \n13355 Berlin                              Fax:  +49 30 23 45 86 95\nhttp://www.elego.de                 Geschaeftsfuehrer: Olaf Wagner\n"}]}