[PATCH] checkpatch.pl: add support for checking patch from git repository

From: changbin . du
Date: Sun Apr 24 2016 - 06:51:33 EST


From: "Du, Changbin" <changbin.du@xxxxxxxxx>

This patch add "-g, --git" option that tread FILE as git commits
expression. You can specify the git commit hash ID expressions,
then these commits from your git repository will be checked.

This feature allows you can check your patches but no need to
generate temporary patch files. The flow git expressions are
supported.
<rev>
<rev>^
<rev>~n
<rev1>..<rev2>
<rev1>...<rev2>
<rev>-n (This is a speical one. For example, 'HEAD-3' means we
need check commits 'HEAD', 'HEAD~1' and HEAD~2'.)

Here is a example output:

changbin@linux$ scripts/checkpatch.pl -g 2a50009-2
----------------------------------------------------------------------------
Commit 4bfd2e6 ("net/mlx4_core: Avoid repeated calls to pci enable/disable")
----------------------------------------------------------------------------
total: 0 errors, 0 warnings, 100 lines checked

Commit 4bfd2e6 ("net/mlx4_core: Avoid repeated calls to pci
enable/disable") has no obvious style problems and is ready for
submission.
--------------------------------------------------------------------------------
Commit 2a50009 ("net/mlx4_core: Don't allow to VF change global pause settings")
--------------------------------------------------------------------------------
total: 0 errors, 0 warnings, 0 checks, 27 lines checked

Commit 2a50009 ("net/mlx4_core: Don't allow to VF change global pause
settings") has no obvious style problems and is ready for
submission.

Signed-off-by: Du, Changbin <changbin.du@xxxxxxxxx>
---
scripts/checkpatch.pl | 42 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 41 insertions(+), 1 deletion(-)

diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index d574d13..9a8a340 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -27,6 +27,7 @@ my $emacs = 0;
my $terse = 0;
my $showfile = 0;
my $file = 0;
+my $git = 0;
my $check = 0;
my $check_orig = 0;
my $summary = 1;
@@ -68,6 +69,12 @@ Options:
--emacs emacs compile window format
--terse one line per report
--showfile emit diffed file position, not input file position
+ -g, --git tread FILE as git commits expression. You can
+ specify the git commit hash ID expressions, then
+ these commits from your git repository will be
+ checked. For example, when -g applied, [FILE]
+ 'HEAD-3' means we need check commits 'HEAD',
+ 'HEAD~1' and HEAD~2'.
-f, --file treat FILE as regular source file
--subjective, --strict enable more subjective tests
--types TYPE(,TYPE2...) show only these comma separated message types
@@ -141,6 +148,7 @@ GetOptions(
'terse!' => \$terse,
'showfile!' => \$showfile,
'f|file!' => \$file,
+ 'g|git!' => \$git,
'subjective!' => \$check,
'strict!' => \$check,
'ignore=s' => \@ignore,
@@ -752,10 +760,40 @@ my @fixed_inserted = ();
my @fixed_deleted = ();
my $fixlinenr = -1;

+# If input is git commits, extract all commits from the commit expressions.
+# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'.
+if ($git) {
+ my @commits = ();
+ for my $commit_expr (@ARGV) {
+ if ($commit_expr =~ m/-/) {
+ my @tmp = split(/-/, $commit_expr);
+ die "$P: incorrect git commits expression".
+ "$commit_expr$!\n" if @tmp != 2;
+ for (my $i = 0; $i < $tmp[1]; $i++) {
+ my $sha = `git log -1 $tmp[0]~$i --pretty=format:'%H'`;
+ unshift(@commits, $sha);
+ }
+ } elsif ($commit_expr =~ m/\.\./) {
+ my $lines = `git log --pretty=format:'%H' $commit_expr`;
+ my $line;
+ foreach $line (split(/\n/, $lines)) {
+ unshift(@commits, $line);
+ }
+ } else {
+ unshift(@commits, $commit_expr);
+ }
+ }
+ die "$P: no git commits after extraction!\n" if @commits == 0;
+ @ARGV = @commits
+}
+
my $vname;
for my $filename (@ARGV) {
my $FILE;
- if ($file) {
+ if ($git) {
+ open($FILE, '-|', "git format-patch --stdout -1 $filename") ||
+ die "$P: $filename: git format-patch failed - $!\n";
+ } elsif ($file) {
open($FILE, '-|', "diff -u /dev/null $filename") ||
die "$P: $filename: diff failed - $!\n";
} elsif ($filename eq '-') {
@@ -766,6 +804,8 @@ for my $filename (@ARGV) {
}
if ($filename eq '-') {
$vname = 'Your patch';
+ } elsif ($git) {
+ $vname = "Commit ". `git log -1 $filename --pretty=format:'%h("%s")'`;
} else {
$vname = $filename;
}
--
2.7.4