Welches Commit hat dieser Blob?

148

Gibt es angesichts des Hash eines Blobs eine Möglichkeit, eine Liste der Commits zu erhalten, die diesen Blob in ihrem Baum haben?

Schreibgeschützt
quelle
2
"Hash eines Blobs" ist das, das von git hash-objectoder zurückgegeben wird sha1("blob " + filesize + "\0" + data), und nicht einfach die Summe des Blob-Inhalts.
Ivan Hamilton
1
Ich dachte ursprünglich, dass diese Frage zu meiner Frage passt, aber es scheint, dass dies nicht der Fall ist. Ich will das wissen , eine begehen , was zuerst eingeführt dieses Blob in das Repository.
Jesse Glick
Wenn Sie den Dateipfad kennen, können Sie ihn verwenden git log --follow filepath(und diesen verwenden, um die Lösung von Aristoteles zu beschleunigen, wenn Sie möchten).
Zaz
ProTip ™: Fügen Sie eines der folgenden Skripte ein ~/.binund benennen Sie es git-find-object. Sie können es dann mit verwenden git find-object.
Zaz
1
Hinweis: Mit Git 2.16 (Q1 2018) können Sie einfach Folgendes berücksichtigen git describe <hash>: Siehe meine Antwort unten .
VonC

Antworten:

107

In beiden folgenden Skripten wird SHA1 des Blobs als erstes Argument und danach optional alle Argumente verwendet, git logdie verstanden werden. ZB --allin allen Zweigen anstatt nur in dem aktuellen -gzu suchen oder im Reflog zu suchen oder was auch immer Sie möchten.

Hier ist es als Shell-Skript - kurz und bündig, aber langsam:

#!/bin/sh
obj_name="$1"
shift
git log "$@" --pretty=format:'%T %h %s' \
| while read tree commit subject ; do
    if git ls-tree -r $tree | grep -q "$obj_name" ; then
        echo $commit "$subject"
    fi
done

Und eine optimierte Version in Perl, immer noch ziemlich kurz, aber viel schneller:

#!/usr/bin/perl
use 5.008;
use strict;
use Memoize;

my $obj_name;

sub check_tree {
    my ( $tree ) = @_;
    my @subtree;

    {
        open my $ls_tree, '-|', git => 'ls-tree' => $tree
            or die "Couldn't open pipe to git-ls-tree: $!\n";

        while ( <$ls_tree> ) {
            /\A[0-7]{6} (\S+) (\S+)/
                or die "unexpected git-ls-tree output";
            return 1 if $2 eq $obj_name;
            push @subtree, $2 if $1 eq 'tree';
        }
    }

    check_tree( $_ ) && return 1 for @subtree;

    return;
}

memoize 'check_tree';

die "usage: git-find-blob <blob> [<git-log arguments ...>]\n"
    if not @ARGV;

my $obj_short = shift @ARGV;
$obj_name = do {
    local $ENV{'OBJ_NAME'} = $obj_short;
     `git rev-parse --verify \$OBJ_NAME`;
} or die "Couldn't parse $obj_short: $!\n";
chomp $obj_name;

open my $log, '-|', git => log => @ARGV, '--pretty=format:%T %h %s'
    or die "Couldn't open pipe to git-log: $!\n";

while ( <$log> ) {
    chomp;
    my ( $tree, $commit, $subject ) = split " ", $_, 3;
    print "$commit $subject\n" if check_tree( $tree );
}
Aristoteles Pagaltzis
quelle
8
Zu Ihrer Information müssen Sie die volle SHA des Blobs verwenden. Ein Präfix, auch wenn es eindeutig ist, funktioniert nicht. Um die vollständige SHA von einem Präfix zu erhalten, können Siegit rev-parse --verify $theprefix
John Douthat
1
Danke @JohnDouthat für diesen Kommentar. Hier ist, wie man das in das obige Skript my $blob_arg = shift; open my $rev_parse, '-|', git => 'rev-parse' => '--verify', $blob_arg or die "Couldn't open pipe to git-rev-parse: $!\n"; my $obj_name = <$rev_parse>; chomp $obj_name; close $rev_parse or die "Couldn't expand passed blob.\n"; $obj_name eq $blob_arg or print "(full blob is $obj_name)\n";
einbindet
Möglicherweise liegt ein Fehler im Skript der oberen Shell vor. Die while-Schleife wird nur ausgeführt, wenn mehr Zeilen zu lesen sind und aus irgendeinem Grund git log kein endgültiges crlf am Ende setzt. Ich musste einen Zeilenvorschub hinzufügen und leere Zeilen ignorieren. obj_name="$1" shift git log --all --pretty=format:'%T %h %s %n' -- "$@" | while read tree commit cdate subject ; do if [ -z $tree ] ; then continue fi if git ls-tree -r $tree | grep -q "$obj_name" ; then echo "$cdate $commit $@ $subject" fi done
Mixologic
7
Dies findet nur Commits im aktuellen Zweig, es sei denn, Sie übergeben --allals zusätzliches Argument. (In Fällen wie dem Löschen einer großen Datei aus dem Repo-Verlauf ist es wichtig, alle Commits repo-weit zu finden .)
Peterflynn
1
Tipp: Übergeben Sie das Flag -g an das Shell-Skript (nach der Objekt-ID), um das Reflog zu untersuchen.
Bram Schoenmakers
24

Leider waren die Skripte für mich etwas langsam, so dass ich etwas optimieren musste. Zum Glück hatte ich nicht nur den Hash, sondern auch den Pfad einer Datei.

git log --all --pretty=format:%H -- <path> | xargs -n1 -I% sh -c "git ls-tree % -- <path> | grep -q <hash> && echo %"
Aragaer
quelle
1
Ausgezeichnete Antwort, weil es so einfach ist. Nur durch die vernünftige Annahme, dass der Pfad bekannt ist. Man sollte jedoch wissen, dass es das Commit zurückgibt, bei dem der Pfad in den angegebenen Hash geändert wurde.
Unapiedra
1
Wenn man das neueste Commit mit dem <hash>angegebenen Wert haben möchte <path>, funktioniert das Entfernen des <path>Arguments aus dem git logTestament. Das erste zurückgegebene Ergebnis ist das gewünschte Commit.
Unapiedra
10

Gibt es angesichts des Hash eines Blobs eine Möglichkeit, eine Liste der Commits zu erhalten, die diesen Blob in ihrem Baum haben?

Mit Git 2.16 (Q1 2018) git describewäre dies eine gute Lösung, da gelernt wurde, Bäume tiefer zu graben, um ein <commit-ish>:<path>Objekt zu finden , das sich auf ein bestimmtes Blob-Objekt bezieht.

Siehe Commit 644eb60 , Commit 4dbc59a , Commit cdaed0c , Commit c87b653 , Commit ce5b6f9 (16. November 2017) und Commit 91904f5 , Commit 2deda00 (02. November 2017) von Stefan Beller ( stefanbeller) .
(Zusammengeführt von Junio ​​C Hamano - gitster- in Commit 556de1a , 28. Dezember 2017)

builtin/describe.c: Beschreibe einen Blob

Manchmal erhalten Benutzer einen Hash eines Objekts und möchten es weiter identifizieren (Beispiel: Verwenden verify-packSie diese Option, um die größten Blobs zu finden, aber was sind das? Oder genau diese SO-Frage " Welches Commit hat diesen Blob? ")

Bei der Beschreibung von Commits versuchen wir, sie an Tags oder Refs zu verankern, da diese konzeptionell auf einer höheren Ebene als das Commit liegen. Und wenn es keinen Ref oder Tag gibt, der genau passt, haben wir kein Glück.
Daher verwenden wir eine Heuristik, um einen Namen für das Commit zu erstellen. Diese Namen sind nicht eindeutig, es gibt möglicherweise unterschiedliche Tags oder Refs, an denen verankert werden kann, und es gibt möglicherweise unterschiedliche Pfade in der DAG, um genau zum Commit zu gelangen.

Wenn wir einen Blob beschreiben, möchten wir den Blob auch von einer höheren Ebene aus beschreiben, was ein Tupel ist, (commit, deep/path)da die beteiligten Baumobjekte eher uninteressant sind.
Auf denselben Blob kann durch mehrere Commits verwiesen werden. Wie entscheiden wir also, welches Commit verwendet werden soll?

Dieser Patch implementiert einen eher naiven Ansatz: Da es keine Rückzeiger von Blobs zu Commits gibt, in denen der Blob auftritt, gehen wir von den verfügbaren Tipps aus, listen die Blobs in der Reihenfolge des Commits auf und sobald wir die gefunden haben Blob, wir nehmen das erste Commit, das den Blob aufgelistet hat .

Beispielsweise:

git describe --tags v0.99:Makefile
conversion-901-g7672db20c2:Makefile

sagt uns, dass das, Makefilewie es v0.99war, in Commit 7672db2 eingeführt wurde .

Das Gehen wird in umgekehrter Reihenfolge durchgeführt, um die Einführung eines Blobs anstelle seines letzten Auftretens anzuzeigen.

Das heißt, die git describeManpage ergänzt die Zwecke dieses Befehls:

Anstatt ein Commit einfach mit dem neuesten Tag zu beschreiben, das von dort aus erreichbar ist, git describewird einem Objekt tatsächlich ein lesbarer Name gegeben, der auf einer verfügbaren Referenz basiert, wenn es als verwendet wird git describe <blob>.

Wenn sich das gegebene Objekt auf einen Blob bezieht, wird es so beschrieben <commit-ish>:<path>, dass der Blob <path>in der gefunden wird <commit-ish>, die selbst das erste Commit beschreibt, bei dem dieser Blob in einem Reverse-Revision-Walk von HEAD auftritt.

Aber:

BUGS

Baumobjekte sowie Tag-Objekte, die nicht auf Commits zeigen, können nicht beschrieben werden .
Bei der Beschreibung von Blobs werden die auf Blobs zeigenden Lightweight-Tags ignoriert, der Blob wird jedoch weiterhin als <committ-ish>:<path>günstig beschrieben, obwohl das Lightweight-Tag günstig ist.

VonC
quelle
1
Gut zu verwenden in Verbindung mit git rev-list --objects --all | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | awk '/^blob/ {print substr($0,6)}' | sort --numeric-sort --key=2 -r | head -n 20, was Ihnen die 20 größten Blobs zurückgibt. Dann können Sie die Blob-ID von der obigen Ausgabe an übergeben git describe. Arbeitete als Zauber! Vielen Dank!
Alexander Pogrebnyak
7

Ich dachte, dies wäre eine allgemein nützliche Sache, also schrieb ich ein kleines Perl-Skript, um es zu tun:

#!/usr/bin/perl -w

use strict;

my @commits;
my %trees;
my $blob;

sub blob_in_tree {
    my $tree = $_[0];
    if (defined $trees{$tree}) {
        return $trees{$tree};
    }
    my $r = 0;
    open(my $f, "git cat-file -p $tree|") or die $!;
    while (<$f>) {
        if (/^\d+ blob (\w+)/ && $1 eq $blob) {
            $r = 1;
        } elsif (/^\d+ tree (\w+)/) {
            $r = blob_in_tree($1);
        }
        last if $r;
    }
    close($f);
    $trees{$tree} = $r;
    return $r;
}

sub handle_commit {
    my $commit = $_[0];
    open(my $f, "git cat-file commit $commit|") or die $!;
    my $tree = <$f>;
    die unless $tree =~ /^tree (\w+)$/;
    if (blob_in_tree($1)) {
        print "$commit\n";
    }
    while (1) {
        my $parent = <$f>;
        last unless $parent =~ /^parent (\w+)$/;
        push @commits, $1;
    }
    close($f);
}

if (!@ARGV) {
    print STDERR "Usage: git-find-blob blob [head ...]\n";
    exit 1;
}

$blob = $ARGV[0];
if (@ARGV > 1) {
    foreach (@ARGV) {
        handle_commit($_);
    }
} else {
    handle_commit("HEAD");
}
while (@commits) {
    handle_commit(pop @commits);
}

Ich werde das auf Github stellen, wenn ich heute Abend nach Hause komme.

Update: Es sieht so aus, als hätte dies bereits jemand getan . Dieser verwendet die gleiche allgemeine Idee, aber die Details sind unterschiedlich und die Implementierung ist viel kürzer. Ich weiß nicht, was schneller wäre, aber die Leistung spielt hier wahrscheinlich keine Rolle!

Update 2: Für das, was es wert ist, ist meine Implementierung um Größenordnungen schneller, insbesondere für ein großes Repository. Das git ls-tree -rtut wirklich weh.

Update 3: Ich sollte beachten, dass meine obigen Leistungskommentare für die Implementierung gelten, die ich oben im ersten Update verlinkt habe. Die Implementierung von Aristoteles ist vergleichbar mit meiner. Weitere Details in den Kommentaren für diejenigen, die neugierig sind.

Greg Hewgill
quelle
Hmm, wie kann es sein , dass viel schneller? Du gehst trotzdem über den Baum, oder? Welche Arbeit macht git-ls-tree, die Sie vermeiden? (NB.: Grep wird beim ersten Spiel auf Kaution gehen und den Git-ls-Baum SIGPIPIEREN.) Als ich es versuchte, musste ich Ihr Skript nach 30 Sekunden mit Strg-C drücken. meins wurde in 4 gemacht.
Aristoteles Pagaltzis
1
Mein Skript speichert die Ergebnisse von Teilbäumen im% tree-Hash zwischen, sodass es nicht ständig nach Teilbäumen suchen muss, die sich nicht geändert haben.
Greg Hewgill
Eigentlich habe ich die Implementierung ausprobiert, die ich auf Github gefunden habe und mit der ich verlinkt habe. Ihre ist in einigen Fällen schneller, aber es hängt stark davon ab, ob sich die gesuchte Datei am Anfang oder Ende der ls-Baumliste befindet. Mein Repository enthält derzeit 9574 Dateien.
Greg Hewgill
Mir fällt auch ein, dass einige nichtlineare Projektverläufe dazu führen können, dass mein Skript viel mehr Arbeit leistet als nötig (dies kann behoben werden). Dies könnte der Grund sein, warum es lange gedauert hat, für Sie zu rennen. Mein Respository ist ein Git-SVN-Spiegel eines Subversion-Repositorys, daher ist es sehr linear.
Greg Hewgill
Anstatt die Katzendatei zu analysieren, um den Baum zu erhalten, tun git rev-parse $commit^{}
Sie
6

Während die ursprüngliche Frage nicht danach fragt, halte ich es für nützlich, auch den Staging-Bereich zu überprüfen, um festzustellen, ob auf einen Blob verwiesen wird. Ich habe das ursprüngliche Bash-Skript geändert, um dies zu tun, und in meinem Repository festgestellt, was auf einen beschädigten Blob verweist:

#!/bin/sh
obj_name="$1"
shift
git ls-files --stage \
| if grep -q "$obj_name"; then
    echo Found in staging area. Run git ls-files --stage to see.
fi

git log "$@" --pretty=format:'%T %h %s' \
| while read tree commit subject ; do
    if git ls-tree -r $tree | grep -q "$obj_name" ; then
        echo $commit "$subject"
    fi
done
Mario
quelle
3
Ich möchte nur Kredit geben, wo es fällig ist: Vielen Dank an die RAM-Beschädigung, dass Sie mir ein BSOD verursacht und mich gezwungen haben, mein Git-Repo von Hand zu reparieren.
Mario
4

Also ... ich musste alle Dateien über einem bestimmten Limit in einem Repo mit einer Größe von über 8 GB und über 108.000 Revisionen finden. Ich habe Aristoteles 'Perl-Skript zusammen mit einem Ruby-Skript angepasst, um diese vollständige Lösung zu erreichen.

Zuerst, git gc Führen Sie dies aus, um sicherzustellen, dass sich alle Objekte in Packdateien befinden. Wir scannen keine Objekte, die sich nicht in Packdateien befinden.

Weiter Führen Sie dieses Skript aus, um alle Blobs über CUTOFF_SIZE-Bytes zu suchen. Erfassen Sie die Ausgabe in einer Datei wie "large-blobs.log".

#!/usr/bin/env ruby

require 'log4r'

# The output of git verify-pack -v is:
# SHA1 type size size-in-packfile offset-in-packfile depth base-SHA1
#
#
GIT_PACKS_RELATIVE_PATH=File.join('.git', 'objects', 'pack', '*.pack')

# 10MB cutoff
CUTOFF_SIZE=1024*1024*10
#CUTOFF_SIZE=1024

begin

  include Log4r
  log = Logger.new 'git-find-large-objects'
  log.level = INFO
  log.outputters = Outputter.stdout

  git_dir = %x[ git rev-parse --show-toplevel ].chomp

  if git_dir.empty?
    log.fatal "ERROR: must be run in a git repository"
    exit 1
  end

  log.debug "Git Dir: '#{git_dir}'"

  pack_files = Dir[File.join(git_dir, GIT_PACKS_RELATIVE_PATH)]
  log.debug "Git Packs: #{pack_files.to_s}"

  # For details on this IO, see http://stackoverflow.com/questions/1154846/continuously-read-from-stdout-of-external-process-in-ruby
  #
  # Short version is, git verify-pack flushes buffers only on line endings, so
  # this works, if it didn't, then we could get partial lines and be sad.

  types = {
    :blob => 1,
    :tree => 1,
    :commit => 1,
  }


  total_count = 0
  counted_objects = 0
  large_objects = []

  IO.popen("git verify-pack -v -- #{pack_files.join(" ")}") do |pipe|
    pipe.each do |line|
      # The output of git verify-pack -v is:
      # SHA1 type size size-in-packfile offset-in-packfile depth base-SHA1
      data = line.chomp.split(' ')
      # types are blob, tree, or commit
      # we ignore other lines by looking for that
      next unless types[data[1].to_sym] == 1
      log.info "INPUT_THREAD: Processing object #{data[0]} type #{data[1]} size #{data[2]}"
      hash = {
        :sha1 => data[0],
        :type => data[1],
        :size => data[2].to_i,
      }
      total_count += hash[:size]
      counted_objects += 1
      if hash[:size] > CUTOFF_SIZE
        large_objects.push hash
      end
    end
  end

  log.info "Input complete"

  log.info "Counted #{counted_objects} totalling #{total_count} bytes."

  log.info "Sorting"

  large_objects.sort! { |a,b| b[:size] <=> a[:size] }

  log.info "Sorting complete"

  large_objects.each do |obj|
    log.info "#{obj[:sha1]} #{obj[:type]} #{obj[:size]}"
  end

  exit 0
end

Bearbeiten Sie als Nächstes die Datei, um alle Blobs zu entfernen, auf die Sie nicht warten, und die INPUT_THREAD-Bits oben. Wenn Sie nur noch Zeilen für die sha1s haben, die Sie suchen möchten, führen Sie das folgende Skript wie folgt aus:

cat edited-large-files.log | cut -d' ' -f4 | xargs git-find-blob | tee large-file-paths.log

Wo das git-find-blobSkript unten ist.

#!/usr/bin/perl

# taken from: http://stackoverflow.com/questions/223678/which-commit-has-this-blob
# and modified by Carl Myers <[email protected]> to scan multiple blobs at once
# Also, modified to keep the discovered filenames
# vi: ft=perl

use 5.008;
use strict;
use Memoize;
use Data::Dumper;


my $BLOBS = {};

MAIN: {

    memoize 'check_tree';

    die "usage: git-find-blob <blob1> <blob2> ... -- [<git-log arguments ...>]\n"
        if not @ARGV;


    while ( @ARGV && $ARGV[0] ne '--' ) {
        my $arg = $ARGV[0];
        #print "Processing argument $arg\n";
        open my $rev_parse, '-|', git => 'rev-parse' => '--verify', $arg or die "Couldn't open pipe to git-rev-parse: $!\n";
        my $obj_name = <$rev_parse>;
        close $rev_parse or die "Couldn't expand passed blob.\n";
        chomp $obj_name;
        #$obj_name eq $ARGV[0] or print "($ARGV[0] expands to $obj_name)\n";
        print "($arg expands to $obj_name)\n";
        $BLOBS->{$obj_name} = $arg;
        shift @ARGV;
    }
    shift @ARGV; # drop the -- if present

    #print "BLOBS: " . Dumper($BLOBS) . "\n";

    foreach my $blob ( keys %{$BLOBS} ) {
        #print "Printing results for blob $blob:\n";

        open my $log, '-|', git => log => @ARGV, '--pretty=format:%T %h %s'
            or die "Couldn't open pipe to git-log: $!\n";

        while ( <$log> ) {
            chomp;
            my ( $tree, $commit, $subject ) = split " ", $_, 3;
            #print "Checking tree $tree\n";
            my $results = check_tree( $tree );

            #print "RESULTS: " . Dumper($results);
            if (%{$results}) {
                print "$commit $subject\n";
                foreach my $blob ( keys %{$results} ) {
                    print "\t" . (join ", ", @{$results->{$blob}}) . "\n";
                }
            }
        }
    }

}


sub check_tree {
    my ( $tree ) = @_;
    #print "Calculating hits for tree $tree\n";

    my @subtree;

    # results = { BLOB => [ FILENAME1 ] }
    my $results = {};
    {
        open my $ls_tree, '-|', git => 'ls-tree' => $tree
            or die "Couldn't open pipe to git-ls-tree: $!\n";

        # example git ls-tree output:
        # 100644 blob 15d408e386400ee58e8695417fbe0f858f3ed424    filaname.txt
        while ( <$ls_tree> ) {
            /\A[0-7]{6} (\S+) (\S+)\s+(.*)/
                or die "unexpected git-ls-tree output";
            #print "Scanning line '$_' tree $2 file $3\n";
            foreach my $blob ( keys %{$BLOBS} ) {
                if ( $2 eq $blob ) {
                    print "Found $blob in $tree:$3\n";
                    push @{$results->{$blob}}, $3;
                }
            }
            push @subtree, [$2, $3] if $1 eq 'tree';
        }
    }

    foreach my $st ( @subtree ) {
        # $st->[0] is tree, $st->[1] is dirname
        my $st_result = check_tree( $st->[0] );
        foreach my $blob ( keys %{$st_result} ) {
            foreach my $filename ( @{$st_result->{$blob}} ) {
                my $path = $st->[1] . '/' . $filename;
                #print "Generating subdir path $path\n";
                push @{$results->{$blob}}, $path;
            }
        }
    }

    #print "Returning results for tree $tree: " . Dumper($results) . "\n\n";
    return $results;
}

Die Ausgabe sieht folgendermaßen aus:

<hash prefix> <oneline log message>
    path/to/file.txt
    path/to/file2.txt
    ...
<hash prefix2> <oneline log msg...>

Und so weiter. Jedes Commit, das eine große Datei in seinem Baum enthält, wird aufgelistet. Wenn Sie grepdie Zeilen uniqentfernen, die mit einer Registerkarte beginnen, und dies , haben Sie eine Liste aller Pfade, die Sie filtern und entfernen können, oder Sie können etwas Komplizierteres tun.

Lassen Sie mich noch einmal wiederholen: Dieser Prozess lief erfolgreich auf einem 10-GB-Repo mit 108.000 Commits. Es hat viel länger gedauert, als ich vorhergesagt hatte, als ich mit einer großen Anzahl von Blobs lief, obwohl ich über 10 Stunden sehen muss, ob das Memorize-Bit funktioniert ...

cmyers
quelle
1
Wie in der obigen Antwort von Aristoteles werden hier nur Commits für den aktuellen Zweig gefunden, es sei denn, Sie übergeben zusätzliche Argumente : -- --all. (Es ist wichtig, alle Commits repo-weit zu finden, wenn eine große Datei gründlich aus dem Repo-Verlauf gelöscht wird .)
Peterflynn
4

Neben dem git describe, dass ich in meiner vorherigen Antwort erwähnt , git logund git diffprofitiere jetzt auch von der „ --find-object=<object-id>“ Option , die Ergebnisse auf Änderungen zu beschränken , die das genannte Objekt beinhalten.
Das ist in Git 2.16.x / 2.17 (Q1 2018)

Siehe Commit 4d8c51a , Commit 5e50525 , Commit 15af58c , Commit cf63051 , Commit c1ddc46 , Commit 929ed70 (04. Januar 2018) von Stefan Beller ( stefanbeller) .
(Zusammengeführt von Junio ​​C Hamano - gitster- in Commit c0d75f0 , 23. Januar 2018)

diffcore: Fügen Sie eine Spitzhacke hinzu, um einen bestimmten Blob zu finden

Manchmal erhalten Benutzer einen Hash eines Objekts und möchten es weiter identifizieren (Beispiel: Verwenden Sie Verify-Pack, um die größten Blobs zu finden, aber was sind das? Oder diese Stapelüberlauf-Frage " Welches Commit hat diesen Blob? ")

Man könnte versucht sein, zu erweitern, git-describeum auch mit Blobs zu arbeiten, so dass git describe <blob-id>eine Beschreibung als ':' gegeben wird.
Dies wurde hier umgesetzt ; Wie die schiere Anzahl der Antworten (> 110) zeigt, ist es schwierig, das Richtige zu finden.
Der schwierige Teil, um das Richtige zu finden, ist die Auswahl des richtigen "Commit-ish", da dies das Commit sein kann, das den Blob (erneut) eingeführt hat, oder der Blob, der den Blob entfernt hat. Der Blob könnte in verschiedenen Zweigen existieren.

Junio ​​deutete auf einen anderen Ansatz zur Lösung dieses Problems hin, den dieser Patch implementiert.
Bringen Sie der diffMaschine ein weiteres Flag bei, um die Informationen auf das Angezeigte zu beschränken.
Beispielsweise:

$ ./git log --oneline --find-object=v2.0.0:Makefile
  b2feb64 Revert the whole "ask curl-config" topic for now
  47fbfde i18n: only extract comments marked with "TRANSLATORS:"

wir beobachten, dass das Makefilewie mit geliefert 2.0wurde in v1.9.2-471-g47fbfded53und in erschienen v2.0.0-rc1-5-gb2feb6430b.
Der Grund, warum diese Commits beide vor v2.0.0 auftreten, sind böse Zusammenführungen, die mit diesem neuen Mechanismus nicht gefunden werden.

VonC
quelle