620 Stimmen

Wie findet/identifiziert man große Commits in der Git-History?

Ich habe ein 300 MB großes Git-Repo. Die Gesamtgröße meiner derzeit ausgecheckten Dateien beträgt 2 MB, und die Gesamtgröße des restlichen Git Repo beträgt 298 MB. Dies ist im Grunde eine reine Code-Repositorium, die nicht größer als ein paar MB sein sollte.

Ich vermute, dass jemand versehentlich einige große Dateien (Video, Bilder, etc.) übertragen und dann entfernt hat... aber nicht aus Git, so dass die Geschichte immer noch nutzlose große Dateien enthält. Wie kann ich die großen Dateien in der Git-Historie finden? Es gibt mehr als 400 Übertragungen, so dass es unpraktisch ist, eine nach der anderen zu suchen.

ANMERKUNG : meine Frage geht es nicht um wie man die Datei entfernt sondern wie man finden. es in erster Linie.

15voto

schmijos Punkte 7369

Wenn Sie nur eine Liste von großen Dateien haben möchten, dann möchte ich Ihnen den folgenden Einzeiler anbieten:

join -o "1.1 1.2 2.3" <(git rev-list --objects --all | sort) <(git verify-pack -v objects/pack/*.idx | sort -k3 -n | tail -5 | sort) | sort -k3 -n

Deren Ergebnis wird sein:

commit       file name                                  size in bytes

72e1e6d20... db/players.sql 818314
ea20b964a... app/assets/images/background_final2.png 6739212
f8344b9b5... data_test/pg_xlog/000000010000000000000001 1625545
1ecc2395c... data_development/pg_xlog/000000010000000000000001 16777216
bc83d216d... app/assets/images/background_1forfinal.psd 95533848

Der letzte Eintrag in der Liste verweist auf die größte Datei in Ihrem Git-Verlauf.

Sie können diese Ausgabe verwenden, um sicherzustellen, dass Sie keine Daten mit BFG die Sie in Ihrer Geschichte gebraucht hätten.

Seien Sie sich bewusst, dass Sie Ihr Repository klonen müssen mit --mirror damit dies funktioniert.

8voto

Julia Schwarz Punkte 2560

Wenn Sie unter Windows arbeiten, finden Sie hier ein PowerShell-Skript, das die 10 größten Dateien in Ihrem Repository ausgibt:

$revision_objects = git rev-list --objects --all;
$files = $revision_objects.Split() | Where-Object {$_.Length -gt 0 -and $(Test-Path -Path $_ -PathType Leaf) };
$files | Get-Item -Force | select fullname, length | sort -Descending -Property Length | select -First 10

7voto

SvenS Punkte 797

Für Windows habe ich eine Powershell-Version von 本答 :

function Get-BiggestBlobs {
  param ([Parameter(Mandatory)][String]$RepoFolder, [int]$Count = 10)
  Write-Host ("{0} biggest files:" -f $Count)
  git -C $RepoFolder rev-list --objects --all | git -C $RepoFolder cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | ForEach-Object {
    $Element = $_.Trim() -Split '\s+'
    $ItemType = $Element[0]
    if ($ItemType -eq 'blob') {
      New-Object -TypeName PSCustomObject -Property @{
          ObjectName = $Element[1]
          Size = [int]([int]$Element[2] / 1kB)
          Path = $Element[3]
      }
    }
  } | Sort-Object Size | Select-Object -last $Count | Format-Table ObjectName, @{L='Size [kB]';E={$_.Size}}, Path -AutoSize
}

Wahrscheinlich möchten Sie je nach Situation einstellen, ob kB, MB oder nur Bytes angezeigt werden sollen.

Es gibt wahrscheinlich Potenzial für eine Leistungsoptimierung, also experimentieren Sie ruhig, wenn Ihnen das ein Anliegen ist.

Um alle Änderungen zu erhalten, lassen Sie einfach | Select-Object -last $Count .
Um eine maschinenlesbare Version zu erhalten, lassen Sie einfach | Format-Table @{L='Size [kB]';E={$_.Size}}, Path -AutoSize .

5voto

Aaron Punkte 1300

Powershell-Lösung für Windows git, findet die größten Dateien:

git ls-tree -r -t -l --full-name HEAD | Where-Object {
 $_ -match '(.+)\s+(.+)\s+(.+)\s+(\d+)\s+(.*)'
 } | ForEach-Object {
 New-Object -Type PSObject -Property @{
     'col1'        = $matches[1]
     'col2'      = $matches[2]
     'col3' = $matches[3]
     'Size'      = [int]$matches[4]
     'path'     = $matches[5]
 }
 } | sort -Property Size -Top 10 -Descending

4voto

Vojtech Vitek Punkte 21769

Essayez git ls-files | xargs du -hs --threshold=1M .

Wir verwenden den folgenden Befehl in unserer CI-Pipeline, der anhält, wenn er große Dateien im Git-Repository findet:

test $(git ls-files | xargs du -hs --threshold=1M 2>/dev/null | tee /dev/stderr | wc -l) -gt 0 && { echo; echo "Aborting due to big files in the git repository."; exit 1; } || true

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X