@@ -168,6 +168,9 @@ BEGIN
168168 ' Create a .gitignore per svn:ignore' ,
169169 { ' revision|r=i' => \$_revision
170170 } ],
171+ ' mkdirs' => [ \&cmd_mkdirs ,
172+ " recreate empty directories after a checkout" ,
173+ { ' revision|r=i' => \$_revision } ],
171174 ' propget' => [ \&cmd_propget,
172175 ' Print the value of a property on a file or directory' ,
173176 { ' revision|r=i' => \$_revision } ],
@@ -274,7 +277,7 @@ BEGIN
274277
275278my %opts = %{$cmd {$cmd }-> [2]} if (defined $cmd );
276279
277- read_repo_config (\%opts );
280+ read_git_config (\%opts );
278281if ($cmd && ($cmd eq ' log' || $cmd eq ' blame' )) {
279282 Getopt::Long::Configure(' pass_through' );
280283}
@@ -769,6 +772,7 @@ sub cmd_rebase {
769772 $_fetch_all ? $gs -> fetch_all : $gs -> fetch;
770773 }
771774 command_noisy(rebase_cmd(), $gs -> refname);
775+ $gs -> mkemptydirs;
772776}
773777
774778sub cmd_show_ignore {
@@ -830,6 +834,12 @@ sub cmd_create_ignore {
830834 });
831835}
832836
837+ sub cmd_mkdirs {
838+ my ($url , $rev , $uuid , $gs ) = working_head_info(' HEAD' );
839+ $gs ||= Git::SVN-> new;
840+ $gs -> mkemptydirs($_revision);
841+ }
842+
833843sub canonicalize_path {
834844 my ($path ) = @_ ;
835845 my $dot_slash_added = 0;
@@ -1196,6 +1206,7 @@ sub post_fetch_checkout {
11961206 command_noisy(qw/ read-tree -m -u -v HEAD HEAD/ );
11971207 print STDERR " Checked out HEAD:\n " ,
11981208 $gs -> full_url, " r" , $gs -> last_rev, " \n " ;
1209+ $gs -> mkemptydirs($gs -> last_rev);
11991210}
12001211
12011212sub complete_svn_url {
@@ -1390,8 +1401,7 @@ sub load_authors {
13901401}
13911402
13921403# convert GetOpt::Long specs for use by git-config
1393- sub read_repo_config {
1394- return unless -d $ENV {GIT_DIR };
1404+ sub read_git_config {
13951405 my $opts = shift ;
13961406 my @config_only ;
13971407 foreach my $o (keys %$opts ) {
@@ -2725,6 +2735,34 @@ sub do_fetch {
27252735 $self -> make_log_entry($rev , \@parents , $ed );
27262736}
27272737
2738+ sub mkemptydirs {
2739+ my ($self , $r ) = @_ ;
2740+ my %empty_dirs = ();
2741+
2742+ open my $fh , ' <' , " $self ->{dir}/unhandled.log" or return ;
2743+ binmode $fh or croak " binmode: $! " ;
2744+ while (<$fh >) {
2745+ if (defined $r && / ^r(\d +)$ / ) {
2746+ last if $1 > $r ;
2747+ } elsif (/ ^ \+ empty_dir: (.+)$ / ) {
2748+ $empty_dirs {$1 } = 1;
2749+ } elsif (/ ^ \- empty_dir: (.+)$ / ) {
2750+ delete $empty_dirs {$1 };
2751+ }
2752+ }
2753+ close $fh ;
2754+ foreach my $d (sort keys %empty_dirs ) {
2755+ $d = uri_decode($d );
2756+ next if -d $d ;
2757+ if (-e _) {
2758+ warn " $d exists but is not a directory\n " ;
2759+ } else {
2760+ print " creating empty directory: $d \n " ;
2761+ mkpath([$d ]);
2762+ }
2763+ }
2764+ }
2765+
27282766sub get_untracked {
27292767 my ($self , $ed ) = @_ ;
27302768 my @out ;
@@ -2950,8 +2988,11 @@ sub find_extra_svn_parents {
29502988 my $bottom_commit =
29512989 $gs -> rev_map_get($bottom , $self -> ra_uuid) ||
29522990 $gs -> rev_map_get($bottom +1, $self -> ra_uuid);
2953- my $top_commit =
2954- $gs -> rev_map_get($top , $self -> ra_uuid);
2991+ my $top_commit ;
2992+ for (; !$top_commit && $top >= $bottom ; --$top ) {
2993+ $top_commit =
2994+ $gs -> rev_map_get($top , $self -> ra_uuid);
2995+ }
29552996
29562997 unless ($top_commit and $bottom_commit ) {
29572998 warn " W:unknown path/rev in svn:mergeinfo "
@@ -3554,6 +3595,12 @@ sub uri_encode {
35543595 $f
35553596}
35563597
3598+ sub uri_decode {
3599+ my ($f ) = @_ ;
3600+ $f =~ s # %([0-9a-fA-F]{2})# chr(hex($1 ))# eg ;
3601+ $f
3602+ }
3603+
35573604sub remove_username {
35583605 $_ [0] =~ s { ^([^:]*://)[^@]+@} { $1 } ;
35593606}
0 commit comments