Как использовать git-filter-branch для проверки коммитов

У меня есть подозрение, что некоторые из последних 150 коммитов в моем репозитории не работают, то есть код не скомпилируется, если я проверю один из этих коммитов. Я думаю, что могу использовать git-filter-branch, чтобы проверить это, но меня смущают параметры. Я придумал это:

git filter-branch -f --commit-filter 'git commit-tree "$@"; компакт диск ../..; сделать дефконфиг; сделать' ГОЛОВУ^..

Но вместо этого я получаю этот вывод:

$ git filter-branch -f --commit-filter 'git commit-tree "$@"; cd ../..; make defconfig; make' HEAD^..
Rewrite 4c3b2950f53717ba22280a76c211c9eab3135348 (1/1)arch/arm64/kernel/setup.c: In function 'arm64_spcr_setup':
arch/arm64/kernel/setup.c:615:3: error: implicit declaration of function 'acpi_setup_spcr' [-Werror=implicit-function-declaration]
   acpi_setup_spcr();
   ^
cc1: some warnings being treated as errors
make[1]: *** [arch/arm64/kernel/setup.o] Error 1
make: *** [arch/arm64/kernel] Error 2
could not write rewritten commit

Это не имеет смысла для меня. Ошибка компиляции не соответствует двум последним фиксациям в моем репо, и что означает «не удалось записать переписанную фиксацию»? Я, очевидно, делаю что-то совершенно неправильно, но я понятия не имею, что.


person Richard Fallon    schedule 30.09.2015    source источник


Ответы (2)


Это не то, для чего предназначено git filter-branch.

Что делает filter-branch, если описать максимально просто, так это:

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

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

Короче говоря, filter-branch — это неправильный инструмент.

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


1Части извлечения и повторной регистрации в процессе фильтрации, как правило, самые медленные, поэтому всякий раз, когда filter-branch может избежать "настоящего" ввода-вывода, он это делает. Вот почему существует --index-filter и почему --commit-filter на самом деле не извлекает никаких деревьев. ( --tree-filter вызывает полную проверку, но, скорее всего, это будет плохо для вашего случая, если только ваш процесс компиляции не предназначен только для чтения.)

person torek    schedule 01.10.2015

Это кажется...грязным.

Все, что вам нужно сделать, это проверить коммиты, один за другим, скомпилировать их и запустить для них тесты, верно?

Вместо этого вы можете проверить эти коммиты, начиная с 1 и до того, сколько вы хотите вернуться, запустить тесты и сообщить результат теста в файл.

Это поможет вам начать:

for i in $(seq 1 150);
do
    git checkout HEAD~$i;
    make defconfig && make;
    git checkout master;
done

Вероятно, есть более элегантный способ сделать это, но принцип таков:

  • Вы просматриваете каждую фиксацию, одну за другой, в состоянии detached HEAD.
  • Вы выполняете все шаги, необходимые для создания ветки в данный момент времени.
  • Вы запускаете тесты (и записываете их; это я оставляю читателю в качестве упражнения).
  • Затем вы восстанавливаете состояние ветки, чтобы она указывала на исходную HEAD.

Немного более элегантным подходом было бы переместить ветку назад только после того, как вы закончите:

COUNT=0
while [ $COUNT -lt 150 ];
do
    git checkout HEAD~1;
    make defconfig && make;
    let $COUNT=$COUNT + 1;
done
git checkout master;
person Makoto    schedule 30.09.2015
comment
Спасибо. Я попробую. Я все еще хотел бы знать, как использовать git-filter-branch, чтобы делать то, что я хочу. Мне трудно понять, как работает эта функция. - person Richard Fallon; 01.10.2015
comment
@RichardFallon: ветка фильтра не предназначена для того, что вы пытаетесь сделать. Обычно вы использовали бы его для перезаписи огромных массивов истории, а не для запуска диагностики некоторого количества коммитов. - person Makoto; 01.10.2015