#!/bin/perl ############################################################################### # # Parse a stream of git status --porcelain -z lines and output the file # paths that have been modified/added/renamed in the work tree. # # Input is expected to be in the format defined for # git status --porcelain -z # # Usage: git status --porcelain -z | chaned-wt-files.pl # ################################################################################ use strict; my $verbose; foreach my $arg (@ARGV) { if ($arg eq '--verbose') { $verbose = 1; next; } print STDERR "$0: unknown option/argument [$arg]\n"; exit 1; } my $stdin = ''; my $buffer; while (read (STDIN, $buffer, 100000)) { $stdin .= $buffer; } print "Read ", length ($stdin), " bytes from STDIN\n" if $verbose; while (length ($stdin)) { # get the HEAD status, work tree status, and the to path my ($X, $Y, $pathto) = unpack ('A1A1xZ*', $stdin); substr ($stdin, 0, 4 + length ($pathto), ''); # handle cases that have a second path (renames, copies) my $pathfrom = ''; if ($X eq 'R' || $X eq 'C') { $pathfrom = unpack ('Z*', $stdin); substr ($stdin, 0, 1 + length ($pathfrom), ''); } # don't process untracked files next if $X eq '?'; # don't process files deleted from work tree next if $Y eq 'D'; if ($verbose) { print "X[",$X,"] Y[",$Y,"] pathto [",$pathto,"]\n"; print " pathfrom[",$pathfrom,"]\n" if length ($pathfrom); next; } print $pathto, "\n"; }