Skip to content

Instantly share code, notes, and snippets.

@rjbs
Created July 16, 2018 13:05
Show Gist options
  • Save rjbs/edb89a4e980a7d5205243d184c0ce208 to your computer and use it in GitHub Desktop.
Save rjbs/edb89a4e980a7d5205243d184c0ce208 to your computer and use it in GitHub Desktop.
#!/usr/bin/perl
#
# TODO: Still fails when files may contain spaces
#
# Should accept multiple commit names or commit ranges
#
# I think it fails when the WD is not the root of the repo
use strict;
use Getopt::Std;
my %opt = ( q => 0,
0 => $ENV{GIT_DIRTYFILES_NULSEP} ? 1 : 0,
);
getopts('q0', \%opt) or usage();
my $commit = shift;
my @changed;
sub cdup {
my $names = shift;
chomp(my ($cdup) = qx{git rev-parse --show-cdup 2> /dev/null});
exit 1 unless $? == 0;
s/^/$cdup/ for @$names;
}
if ($commit) {
chomp(@changed = grep /\S/, qx{git show --pretty="format:" --name-only $commit});
cdup(\@changed);
} else {
chomp(@changed = qx{git status --porcelain});
exit 1 unless $? == 0;
@changed = grep !/^\?\? /, @changed unless $opt{q};
s/^.. // or die "<$_>???\n" for @changed;
s/.* -> // for @changed;
die "Fucking shell, how does it work?\n"
if grep / /, @changed;
cdup(\@changed);
chomp(@changed = qx{find @changed -type f }) if @changed;
exit 1 unless $? == 0;
}
my $sep = $opt{0} ? "\0" : "\n";
print join $sep, @changed, "";
exit 0;
sub usage {
print STDERR "git dirtyfiles [-q] [-0] [commit]
list the names of files that have been changed since the last commit,
one per line (or separated by NUL if -0 is given)
With -q, include files that are unknown to Git
With a commit, list the names of the files that were changed in that commit
";
exit 2;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment