Git - получить все коммиты и капли, которые они создали - PullRequest
16 голосов
/ 22 августа 2009

Есть ли команда git, которая может выводить для каждого коммита:

  1. ID
  2. предмет
  3. BLOB-объектов, созданных с использованием пути и размера (например, git ls-tree -l -r <commit>, но только для созданных BLOB-объектов)

Ответы [ 6 ]

26 голосов
/ 23 августа 2009

Чтобы получить коммиты (все и выводить одну строку на коммит):

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

Затем разделите коммиты по пробелу с лимитом 2 и получите каждый идентификатор коммита и сообщение

Чтобы получить BLOB-объекты, созданные коммитом (выполнить возврат к подкаталогам, показать коммиты слияния, обнаружить переименования и копии, не показывать идентификатор фиксации в первой строке):

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

Небольшой разбор каждой строки и исключение некоторых из них - и мы получаем список новых BLOB-объектов и пути для их фиксации

Последнее, чтобы получить размеры BLOB-объектов:

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

И в другой раз немного разбора

12 голосов
/ 21 апреля 2012

Полагаться на git rev-list не всегда достаточно, потому что это

Список [s] коммитов, которые доступны при переходе по родительским ссылкам из данный коммит (ы) [..]

(git help rev-list)

Таким образом, он не перечисляет коммиты, которые находятся в другой ветви, и не перечисляет коммиты, которые недоступны какой-либо ветви (возможно, они были созданы из-за некоторых действий rebase и / или отсоединенной головы).

Аналогично, git log просто следует за родительскими ссылками из текущего извлеченного коммита. Опять же, вы не видите коммиты, на которые ссылаются другие ветки или которые находятся в зависшем состоянии.

Вы действительно можете получить все коммиты с помощью команды, подобной этой:

for i in `(find .git/objects  -type f |
             sed 's@^.*objects/\(..\)/\(.\+\)$@\1\2@' ;
           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

Для простоты тело цикла печатает для каждого коммита одну строку, содержащую его хэш, родительский хэш (ы), дату и тему. Обратите внимание, что для итерации по всем коммитам необходимо учитывать упакованные и еще не упакованные объекты.

Вы можете напечатать ссылочные BLOB-объекты (и только созданные), вызвав git diff-tree $i (и greping для capitial A в пятом столбце) из тела цикла.

5 голосов
/ 22 августа 2009

Вы можете получить все, кроме размера из коробки. Этот довольно близко:

git log --name-status
3 голосов
/ 13 марта 2012

Одно решение, основанное на ответе Тиг:

#!/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
}

Может быть, не самый лучший код, но он поможет вам в этом.

2 голосов
/ 14 мая 2013

Еще одна полезная команда при поиске

git fsck --lost-found

покажет висячие коммиты. Мне нужно было использовать это, чтобы найти коммит, который я вытер с несвоевременным сбросом --hard

Но не верьте мне на слово:

https://www.kernel.org/pub/software/scm/git/docs/git-fsck.html

0 голосов
/ 08 ноября 2012

Вы также можете получить список всех коммитов (включая висячие) с:

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

Включите эту строку в настройки для нового представления в gitk (в последнем поле ввода - команда для создания дополнительных коммитов), и вы получите дерево, которое также показывает «забытую историю» проекта.

...