如何获取提交中更改的所有文件的哈希?

时间:2019-10-14 19:17:40

标签: git

我需要获取提交中所有已更改文件的列表-及其哈希值,以便与我们的核心审核服务提供的文件列表进行比较。我看到了lots of ways to get the list of files,但也没有列出任何哈希值。

除了解析index行的实际diff输出之外,有没有办法获得这些信息?

2 个答案:

答案 0 :(得分:2)

事实证明,git-show--raw标志以比diff输出更易于解析的格式提供此信息。这些行还包括移动和复制的文件。

将其与--no-abbrev标志结合以显示完整的哈希值,并使用--format标志以隐藏提交信息,我们得到:

$ git show --raw --no-abbrev --format=
:100755 100755 0a88c4d759ce6b4f934812c85d616ff017f6caf4 633cf0a7281c549580e713edc4a0f4d0b91b3beb M      bin/quarterly-baseline
:100755 100755 e5a5a1f9437656ada68faf147393d887924bd6a7 3006514dad95f9a0249b97d984f0167c0837b61b M      bin/weekly-report
:100644 100644 82df0c621dc4f3fc98d6d4da518444d0ef3cdd9d 536eb5ad49a407660298dcf5204e3dc7ecb9aab8 M      docs/pages/api.rst
:100644 100644 267b4e017c77928e6f165095ee40043df8689da5 1d27b3084ec760870f79f434347cd2cb004dafe4 M      index.js
:100644 100644 03555ccf3978be14462b8c06a1790c9094ebbe42 846a85a5bbcf36c694d1ec244a56acd30f4494b2 R057   test/get-web-build-times-test.js        test/get-build-times-test.js
:100644 100644 d3f203c3e6d9c25df73e37ab0f3843f4c7687b1d e3c7eee94bbe379979c0c355cba86764a3f6caa9 R075   test/request-web-dev-box-stats-test.js  test/request-dev-box-stats-test.js

每行代表一个更改后的输出文件,并且可以使用简单的正则表达式/:\d+ \d+ \w+ (\w+) .+ (\S+)/提取散列和文件名。

答案 1 :(得分:1)

下面的代码解析git diff-tree的非合并提交的输出,以显示提交中修改的每个文件的哈希,状态(修改,添加,删除等)。

例如,在git的历史记录中,运行show-hashes 08da6496b6134输出

Documentation/RelNotes/2.24.0.txt M bda29d224a4f75b7497be901bd269f69d99de508

扩展它的方向包括支持合并提交以及移动或重命名检测。

#! /usr/bin/env perl

use strict;
use warnings;
no  warnings 'exec';

my $treeish = @ARGV ? shift : "HEAD";

my $sha1 = qr/[0-9a-f]{40}/;
my $mode = qr/[0-9]{6}/;
my $file_change = qr/
  ^ :
  $mode    # mode for src; 000000 if creation or unmerged
  [ ]
  $mode    # mode for dst; 000000 if deletion or unmerged
  [ ]
  ($sha1)  # sha1 for src; 0{40} if creation or unmerged
  [ ]
  ($sha1)  # sha1 for dst; 0{40} if creation, unmerged, or "look at work tree"
  [ ]
  ([ACDMRTUX])([0-9]*)
  $
/x;

my @cmd = (qw/ git diff-tree --raw -r -z /, $treeish);
open my $fh, "-|", @cmd
  or die "$0: failed to start @cmd";

$/ = "\0";

my $commit = <$fh>;
die "$0: merge commits not supported" unless defined $commit;
chomp $commit;
die "$0: expected commit SHA1"        unless $commit =~ /^$sha1$/;

while (<$fh>) {
  chomp;

  die "$0: unexpected [$_]"
    unless my($src,$dst,$status,$score) = /$file_change/;

  chomp(my $srcpath = <$fh> || "");
  die "$0: commit=$commit, dst=$dst: missing path" if $srcpath eq "";

  print "$srcpath $status $dst\n";
}

close $fh or die "$0: @cmd failed";