33use strict;
44use Git;
55
6+ binmode (STDOUT , " :raw" );
7+
68my $repo = Git-> repository();
79
810my $menu_use_color = $repo -> get_colorbool(' color.interactive' );
@@ -91,6 +93,47 @@ sub run_cmd_pipe {
9193}
9294chomp ($GIT_DIR );
9395
96+ my %cquote_map = (
97+ " b" => chr (8),
98+ " t" => chr (9),
99+ " n" => chr (10),
100+ " v" => chr (11),
101+ " f" => chr (12),
102+ " r" => chr (13),
103+ " \\ " => " \\ " ,
104+ " \042 " => " \042 " ,
105+ );
106+
107+ sub unquote_path {
108+ local ($_ ) = @_ ;
109+ my ($retval , $remainder );
110+ if (!/^\042(.*)\042$/ ) {
111+ return $_ ;
112+ }
113+ ($_ , $retval ) = ($1 , " " );
114+ while (/ ^([^\\ ]*)\\ (.*)$ / ) {
115+ $remainder = $2 ;
116+ $retval .= $1 ;
117+ for ($remainder ) {
118+ if (/ ^([0-3][0-7][0-7])(.*)$ / ) {
119+ $retval .= chr (oct ($1 ));
120+ $_ = $2 ;
121+ last ;
122+ }
123+ if (/ ^([\\\042 btnvfr])(.*)$ / ) {
124+ $retval .= $cquote_map {$1 };
125+ $_ = $2 ;
126+ last ;
127+ }
128+ # This is malformed -- just return it as-is for now.
129+ return $_ [0];
130+ }
131+ $_ = $remainder ;
132+ }
133+ $retval .= $_ ;
134+ return $retval ;
135+ }
136+
94137sub refresh {
95138 my $fh ;
96139 open $fh , ' git update-index --refresh |'
@@ -104,7 +147,7 @@ sub refresh {
104147sub list_untracked {
105148 map {
106149 chomp $_ ;
107- $_ ;
150+ unquote_path( $_ ) ;
108151 }
109152 run_cmd_pipe(qw( git ls-files --others --exclude-standard --) , @ARGV );
110153}
@@ -141,7 +184,8 @@ sub list_modified {
141184
142185 if (@ARGV ) {
143186 @tracked = map {
144- chomp $_ ; $_ ;
187+ chomp $_ ;
188+ unquote_path($_ );
145189 } run_cmd_pipe(qw( git ls-files --exclude-standard --) , @ARGV );
146190 return if (!@tracked );
147191 }
@@ -153,6 +197,7 @@ sub list_modified {
153197 if (($add , $del , $file ) =
154198 / ^([-\d ]+) ([-\d ]+) (.*)/ ) {
155199 my ($change , $bin );
200+ $file = unquote_path($file );
156201 if ($add eq ' -' && $del eq ' -' ) {
157202 $change = ' binary' ;
158203 $bin = 1;
@@ -168,13 +213,15 @@ sub list_modified {
168213 }
169214 elsif (($adddel , $file ) =
170215 / ^ (create|delete) mode [0-7]+ (.*)$ / ) {
216+ $file = unquote_path($file );
171217 $data {$file }{INDEX_ADDDEL } = $adddel ;
172218 }
173219 }
174220
175221 for (run_cmd_pipe(qw( git diff-files --numstat --summary --) , @tracked )) {
176222 if (($add , $del , $file ) =
177223 / ^([-\d ]+) ([-\d ]+) (.*)/ ) {
224+ $file = unquote_path($file );
178225 if (!exists $data {$file }) {
179226 $data {$file } = +{
180227 INDEX => ' unchanged' ,
@@ -196,6 +243,7 @@ sub list_modified {
196243 }
197244 elsif (($adddel , $file ) =
198245 / ^ (create|delete) mode [0-7]+ (.*)$ / ) {
246+ $file = unquote_path($file );
199247 $data {$file }{FILE_ADDDEL } = $adddel ;
200248 }
201249 }
@@ -302,7 +350,8 @@ sub find_unique_prefixes {
302350 }
303351 %search = %{$search {$letter }};
304352 }
305- if ($soft_limit && $j + 1 > $soft_limit ) {
353+ if (ord ($letters [0]) > 127 ||
354+ ($soft_limit && $j + 1 > $soft_limit )) {
306355 $prefix = undef ;
307356 $remainder = $ret ;
308357 }
0 commit comments