Найти все двоичные файлы в Git HEAD


У меня есть огромное РЕПО git, которое в конечном итоге нужно очистить с помощью bfg.
Но сначала я хочу отследить и удалить файлы в HEAD, которые git трактует как двоичные...

Итак, я ищу команду , чтобы найти все файлы в заголовке , который git обрабатывает как двоичный.

Это не помогло:

Заранее благодарю вас за помощь.

4   13  
2015-06-07 05:07:36

4 ответа:

diff <(git grep -Ic '') <(git grep -c '') | grep '^>' | cut -d : -f 1 | cut -d ' ' -f 2-

Разбивая его:

  • git grep -c '' выводит имена и количество строк каждого файла в репозитории. Добавление опции -I заставляет команду игнорировать двоичные файлы.
  • diff <(cmd1) <(cmd2) использует подстановку процессов для обеспечения diff именованными каналами, через которые передаются выходные данные cmd1 и cmd2.
  • команды grep и cut используются для извлечения имен файлов из выходных данных diff.

Упрощенное решение, основанное на ответе @jangler (https://stackoverflow.com/a/30690662/808101 )

comm -13 <(git grep -Il '' | sort -u) <(git grep -al '' | sort -u)

Пояснение:

  1. git grep

    • -l попросите вывести только имя файла, соответствующее шаблону '' (который должен совпадать с каждой строкой каждого файла)
    • -I Эта опция заставляет команду игнорировать двоичные файлы
    • -a Эта опция заставляет обрабатывать двоичные файлы так, как если бы они были текст
  2. sort -u Сортировать результат grep, так как comm обрабатывает только отсортированные файлы

  3. comm -13 перечислите файлы, уникальные для 2-го списка (Список git grep со всеми файлами, включая двоичные)

Вот такой же сценарий для Windows с помощью PowerShell:

$textFiles = git grep -Il .
$allFiles = git ls-files

foreach ($line in $allFiles){
    if ($textFiles -notcontains $line) {
        $line;
    }
}

Или в краткой форме:

$textFiles = git grep -Il .
git ls-files | where { $textFiles -notcontains $_ }

, что занимает O(n^2) для завершения, и это более быстрый подход с использованием хэш-таблиц:

$files = @{}
git ls-files | foreach { $files[$_] = 1 }
git grep -Il . | foreach { $files[$_] = 0 }
$files.GetEnumerator() | where Value -EQ 1 | sort Name | select -ExpandProperty Name

Для завершения требуется O(n).

grep -Fvxf <(git grep -Il '') <(git grep -al '')

Пояснение:

Чтобы также рассмотреть файлы, добавленные с помощью git add, но еще не зафиксированные:

grep -Fvxf <(git grep --cached -Il '') <(git grep --cached -al '')

Или вы могли бы сделать цикл for на git ls-files с Как определить, обрабатывает ли Git файл как двоичный или как текстовый?

Тестируется на Git 2.16.1 с помощью этого тестового РЕПО.