nix

configuration files that power my machines
Log | Files | Refs | README | LICENSE

git-list (5173B)


      1 #!/usr/bin/perl
      2 # vim: sts=4 sw=4 ts=4 expandtab:
      3 # gl - List files from .git/gitids.txt
      4 
      5 use strict;
      6 use warnings;
      7 use File::Spec;
      8 use Cwd qw/getcwd abs_path/;
      9 
     10 =pod
     11 
     12 =head1 NAME
     13 
     14 git-list
     15 
     16 =head1 SYNOPSIS
     17 
     18     git-list [-h] [number pattern]
     19 
     20 =head1 DESCRIPTION
     21 
     22 git-list lists the corresponding filenames given their numbers that was
     23 previously assigned by git-id. It lists one filename per line of output. Any
     24 other argument or numbers that has no filenames associated with it will be
     25 printed as is.
     26 
     27 [number pattern] can either be a single number or a range:
     28 
     29     git-list 1 5-6
     30 
     31 =head1 OPTIONS
     32 
     33     -h         Show this help message
     34 
     35 =head1 SEE ALSO
     36 
     37     git-number(1), git-id(1)
     38 
     39 =cut
     40 
     41 if (defined $ARGV[0] && $ARGV[0] eq '-h') {
     42     system(qq[perldoc $0]);
     43     exit 0;
     44 }
     45 
     46 my $wanted_ids = explode_args(@ARGV);
     47 
     48 if (ref $wanted_ids eq 'ARRAY') {
     49     my $file_for = get_file_ids();
     50     foreach my $id (@$wanted_ids) {
     51         if (defined $file_for->{$id}) {
     52             print $file_for->{$id};
     53         } else {
     54             print $id;
     55         }
     56         print "\n";
     57     }
     58 } elsif ($wanted_ids eq 'all') {
     59     my @file_list = get_file_list();
     60     foreach my $entry (@file_list) {
     61         print  $entry->{filename} . "\n";
     62     }
     63 }
     64 exit 0;
     65 # Add subs below this line
     66 
     67 sub get_file_list {
     68     my $git_dir = `git rev-parse --git-dir`;
     69     chomp $git_dir;
     70 
     71     my $gitids = "$git_dir/gitids.txt";
     72     if (! -f $gitids) {
     73         print "Please run git-number first\n";
     74         exit 1;
     75     }
     76 
     77     open my $cache, "<$gitids" or die "Error: $!";
     78 
     79     my $headers = read_headers($cache);
     80     my $cwd = getcwd();
     81     my $needfixdir = 0;
     82     if ($headers->{cwd} ne $cwd) {
     83         $needfixdir = 1;
     84         $cwd = abs_path($cwd);
     85     }
     86     my @file_list;
     87     my $status_processor_for = {
     88         '' => sub {
     89             while (my $line = <$cache>) {
     90                 next if $line !~ /^#?[0-9]+\t/;
     91                 chomp $line;
     92                 if (my ($number, $status, $filename)
     93                         = $line =~ /^#?([0-9]+)\t([^:]+:\s+)?(.*)/) {
     94 
     95 
     96 
     97                     if ($filename =~ / \(.*\)$/ && ! -e $filename) {
     98                         # Looks like a submodule status, see if it really is a submodule
     99                         my ($dir) = $filename =~ /(.*) \(.*\)$/;
    100                         if (-d $dir && -e "$dir/.git") {
    101                                 $filename = $dir;
    102                         }
    103                     }
    104 
    105                     if ($needfixdir) {
    106                         $filename = fixdir($filename, $headers->{cwd}, $cwd);
    107                     }
    108                     push @file_list, {
    109                             number => $number,
    110                             status => $status,
    111                             filename => $filename,
    112                         };
    113                 }
    114             }
    115         },
    116         '--short' => sub {
    117             while (my $line = <$cache>) {
    118                 next if $line !~ /^[0-9]+\s/;
    119                 chomp $line;
    120                 if (my ($number, $status, $filename)
    121                         = $line =~ /^([0-9]+)\s+([^ ]+)\s+(.*)/) {
    122 
    123                     if ($needfixdir) {
    124                         $filename = fixdir($filename, $headers->{cwd}, $cwd);
    125                     }
    126                     push @file_list, {
    127                             number => $number,
    128                             status => $status,
    129                             filename => $filename,
    130                         };
    131                 }
    132             }
    133         },
    134     };
    135 
    136     my $status_format = $headers->{'status-format'};
    137     $status_processor_for->{$status_format}->();
    138     close $cache;
    139     return @file_list;
    140 }
    141 
    142 sub read_headers {
    143     my ($cache) = @_;
    144     my %headers;
    145     while (my $line = <$cache>) {
    146         chomp $line;
    147         last if length $line == 0;
    148         my ($field, $value) = split(/:\s*/, $line, 2);
    149         $headers{$field} = $value;
    150     }
    151     return \%headers;
    152 }
    153 
    154 sub get_file_ids {
    155     my @file_list = get_file_list();
    156 
    157     my %file_for;
    158     foreach my $entry (@file_list) {
    159         my $filename = $entry->{filename};
    160         # First we escape characters that need escaping
    161         if ($filename =~ /[`\$"]/) {
    162             $filename =~ s/([`\$"])/\\$1/g;
    163         }
    164         # Then we double-quote the name if necessary
    165         if ($filename =~ /[ '\[\]()&]/) {
    166             $filename = '"' . $filename . '"';
    167         }
    168         $file_for{$entry->{number}} = $filename;
    169     }
    170     return \%file_for;
    171 }
    172 
    173 sub explode_args {
    174     my (@ARGV) = @_;
    175     if (scalar @ARGV == 0) {
    176         return 'all';
    177     }
    178     my @wanted_ids;
    179     foreach my $arg (@ARGV) {
    180         if ($arg =~ m/^[0-9]+$/) {
    181             push @wanted_ids, $arg;
    182         } elsif ($arg =~ m/^([0-9]+)-([0-9]+)/) {
    183             my $a = $1;
    184             my $b = $2;
    185             if ($a > $b) {
    186                 $a = $b;
    187                 $b = $1;
    188             }
    189             push @wanted_ids, $a..$b;
    190         } else {
    191             push @wanted_ids, $arg;
    192         }
    193     }
    194     return \@wanted_ids;
    195 }
    196 
    197 sub fixdir {
    198     my ($filename, $orig_cwd, $cwd) = @_;
    199     my $abspath = File::Spec->catfile($orig_cwd, $filename);
    200     $abspath = abs_path($abspath);
    201     return File::Spec->abs2rel($abspath, $cwd);
    202 }