| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- #!/usr/bin/perl
- # vim: sts=4 sw=4 ts=4 expandtab:
- =pod
- =head1 NAME
- git-id
- =head1 SYNOPSIS
- git-id
- =head1 DESCRIPTION
- Runs git-status and prepends numeric ids to filenames.
- =head1 OPTIONS
- =over 4
- =item -h
- Show this help message
- =item -s
- =item --column
- =item -u(no|normal|all)
- =item --color=(always|auto|never)
- These options are similar to git-status'.
- =back
- =head1 SEE ALSO
- git-number(1), git-list(1)
- =cut
- use strict;
- use warnings;
- use Cwd;
- my $red = "\e[31m";
- my $normal = "\e[0m";
- my $git_dir = `git rev-parse --git-dir`;
- chomp $git_dir;
- my $gitids = "$git_dir/gitids.txt";
- my $color = 'always';
- my $STATUS_DEFAULT = 0;
- my $STATUS_SHORT = 1;
- my $status_style = $STATUS_DEFAULT;
- my $status_opt = '';
- my $untracked_in_columns = 0;
- while (scalar @ARGV && $ARGV[0] =~ /^-/) {
- my $option = shift @ARGV;
- last if $option eq '--';
- if ($option =~ /--color=(always|auto|never)/) {
- $color = $1;
- if ($color =~ /never/) {
- $red = $normal = '';
- }
- } elsif ($option eq '--short') {
- $status_style = $STATUS_SHORT;
- } elsif ($option =~ m{^-u(no|normal|all)$}) {
- $status_opt .= " $option";
- } elsif ($option =~ /^--column/) {
- if ($option eq '--column=never' || ($option =~ /--column(=auto)?$/ && ! -t STDOUT)) {
- $untracked_in_columns = 0;
- } else {
- $untracked_in_columns = 1;
- }
- $status_opt .= " $option";
- } else {
- print "Unknown option: $option\n";
- exit 1;
- }
- }
- if (! $untracked_in_columns) {
- $status_opt .= " --column=never";
- }
- my @status_option_for = ( '', '--short' );
- my $status_format = $status_option_for[$status_style];
- my $git_cmd = "git -c color.status=$color status $status_opt $status_format "
- . join(' ', @ARGV);
- open my $git_status, "$git_cmd|"
- or die "Error: $!";
- open my $cache, ">$gitids"
- or die "Error: $!";
- # Headers
- print $cache "cwd: " . getcwd . "\n";
- print $cache "status-format: $status_format\n";
- print $cache "\n";
- my $seen_untracked = 0;
- my @untracked;
- my $c = 1;
- while (my $line = <$git_status>) {
- if ($line =~ /Untracked files:/) {
- $seen_untracked = 1;
- }
- if ($status_style == $STATUS_DEFAULT) {
- if ($seen_untracked && $line =~ /\t/ && $untracked_in_columns) {
- push @untracked, $line;
- last;
- }
- if ($line =~ /#\t/) {
- $line =~ s/#\t/#$c\t/;
- $c += 1;
- } elsif ($line =~ /\t/) {
- $line =~ s/\t/$c\t/;
- $c += 1;
- }
- } elsif ($status_style == $STATUS_SHORT) {
- if ($line !~ /^#/) {
- $line =~ s/^/$c /;
- $c += 1;
- }
- }
- show_and_cache($line);
- }
- if ($untracked_in_columns) {
- my $seen_files = 0;
- my @the_rest;
- while (my $line = <$git_status>) {
- if ($line =~ /\t/) {
- $seen_files = 1;
- push @untracked, $line;
- } else {
- push @the_rest, $line;
- }
- }
- my $rows = @untracked;
- foreach my $line (@untracked) {
- my $id = $c;
- $line =~ s/([\t ])(\S)/add_number(\$id, $1, $2, $rows)/ge;
- $line =~ s/^ +//;
- show_and_cache($line);
- $c += 1;
- }
- print join "", @the_rest;
- }
- close $git_status;
- close $cache;
- exit 0;
- sub show_and_cache {
- my ($line) = @_;
- my $tocache = $line;
- $tocache =~ s/{(\d+)}[\t ]{1,2}/\n$1\t/g;
- $line =~ s/{(\d+)}/$1/g;
- print $line;
- $tocache =~ s/\e\[(\d*(;\d*)*)m//g;
- if ($untracked_in_columns) {
- $tocache =~ s/\s*\n/\n/gms; # Trailing spaces from columnar formatting
- }
- print $cache $tocache;
- }
- sub add_number {
- my ($nref, $space, $first_char, $incr) = @_;
- my $num = $$nref;
- if ($num < 10 && $space eq ' ') {
- $num = "{$num} ";
- } else {
- $num = "{$num}";
- }
- my $str = "$normal$num$space$red$first_char";
- $$nref += $incr;
- return $str;
- }
|