2009-08-22 12 views

risposta

26

Per ottenere commit (tutti e uscita una riga per commettere):

git rev-list --all --pretty=oneline 

Poi diviso impegna da spazio con limite di 2 e ottenere ogni Commit ID e il messaggio

per ottenere macchie create da commit (ricorsione a sottocartelle, spettacolo si fondono impegna, rilevare rinomina e copie, non mostrano commettere id sulla prima riga):

git diff-tree -r -c -M -C --no-commit-id <commit-sha> 

Un po 'di analisi di ogni linea ed escludendo alcuni di loro - e si ottiene la lista dei nuovi blobs e percorso per commettere

Ultimo è quello di ottenere dimensioni blob:

git cat-file --batch-check < <list-of-blob-shas> 

e un'altra volta un po' di parsing

+1

si può fare questo molto più veloce utilizzando l'opzione '--stdin' a' diff-tree'. Ad esempio, 'git rev-list --all | git diff-tree -r --root --diff-filter = AMC --pretty = oneline --stdin'. – Jed

+0

La risposta di maxschlepzig qui sotto è importante: se stai provando a fare qualcosa come [eliminare un file di grandi dimensioni dalla cronologia dei repository] (http://git-scm.com/book/en/Git-Internals-Maintenance-and-Data -Recupero # Rimozione-Oggetti), è necessario assicurarsi di trovare ogni commit, anche se alcuni sono su rami non raggruppati! – peterflynn

5

È possibile ottenere tutto tranne la dimensione fuori dalla scatola. Questo è abbastanza vicino:

git log --name-status 
3

una soluzione basata sulla risposta di TIG:

#!/usr/bin/perl 

foreach my $rev (`git rev-list --all --pretty=oneline`) { 
    my $tot = 0; 
    ($sha = $rev) =~ s/\s.*$//; 
    foreach my $blob (`git diff-tree -r -c -M -C --no-commit-id $sha`) { 
    $blob = (split /\s/, $blob)[3]; 
    next if $blob == "0000000000000000000000000000000000000000"; # Deleted 
    my $size = `echo $blob | git cat-file --batch-check`; 
    $size = (split /\s/, $size)[2]; 
    $tot += int($size); 
    } 
    print "$tot $rev" if $tot > 1000000; # Show only if > 1MiB 
} 

Forse non il codice migliore, ma dovrebbe ottenere maggior parte della strada.

11

Basandosi sulla git rev-list non è sempre sufficiente perché

Lista [s] si impegna che sono raggiungibili seguendo i link genitore dalla data commit (s) [..]

(git help rev-list)

Pertanto non elenca i commit che si trovano su un altro ramo e non elenca i commit che non sono raggiungibili da alcun ramo (forse sono stati creati perché o f alcuni rebase e/o azioni testa staccata).

Analogamente, git log segue semplicemente i collegamenti padre dal commit estratto in uscita. Ancora una volta non si vedono i commit referenziati da altri rami o che sono in uno stato penzolante.

Si può davvero ottenere tutte impegna con un comando come questo:

for i in `(find .git/objects -type f | 
      sed '[email protected]^.*objects/\(..\)/\(.\+\)[email protected]\1\[email protected]' ; 
      git verify-pack -v .git/objects/pack/*.idx | 
      grep commit | 
      cut -f1 -d' ';) | sort -u` 
    do 
    git log -1 --pretty=format:'%H %P %ai %s%n' $i 
done 

Per farla semplice, le stampe corpo del loop per ogni commit di una riga che contiene il suo hash, l'hash genitore (es), data e soggetto. Nota, per iterare su tutti gli si impegna a prendere in considerazione oggetti imballati e non ancora imballati.

È possibile stampare i BLOB referenziati (e solo quelli creati) chiamando git diff-tree $i (e grepping per capitial A nella quinta colonna) dal corpo del loop.

+0

Che ne dici di usare 'git log --all'? I documenti sembrano implicare che includerà ogni commit (raggiungibile) ... – peterflynn

+0

@ytpete, ho menzionato esplicitamente commit non raggiungibili nella mia risposta. – maxschlepzig

0

È inoltre possibile ottenere un elenco di tutti commit (compresi quelli pendenti) con:

git log --walk-reflogs | grep -E -o '[0-9a-f]{40}'

Includere questa linea nelle impostazioni per una nuova vista a gitk (nell'ultimo campo di input , il comando per generare ulteriori commit) e otterrai un albero che mostra anche la 'storia dimenticata' del progetto.

+1

Non funziona per me: 'git log --walk-reflogs' fornisce una lista _shorter_ che non fa semplicemente' git log'. A giudicare dalla [pagina man] (http://gitmanual.org/git-reflog.html), il reflog non è in alcun modo garantito come un elenco esaustivo di tutti i commit o di tutti i rami ... – peterflynn

Problemi correlati