Git pre-commit получить все файлы Python

Я хотел бы запустить черный цвет, чтобы отформатировать все поэтапные файлы .py при фиксации. К сожалению, из-за сети VPN работодателя и ограничений я не могу использовать предварительную фиксацию, потому что время ожидания истекает при попытке загрузить репо.

Поэтому я решил написать свой собственный хук перед фиксацией. В настоящее время у меня есть это

#!/bin/sh 

# Check if this is the initial commit 
if git rev-parse --verify HEAD >/dev/null 2>&1 
then 
    echo "pre-commit: About to create a new commit..." 
    against=HEAD 
else
    echo "pre-commit: About to create the first commit..."
    against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 
fi 

# Autoformat with black
echo "pre-commit: Autoformatting Python code with black"
black $(git diff-index --cached --name-only --diff-filter=d $against)

Первую часть я нашел в Atlassian. Во второй части нужен какой-то фильтр, чтобы брать только файлы .py из столбца, который возвращается с помощью diff-index. Как получить из списка только файлы .py?

Также: я новичок в git-хуках. Это надежный способ для меня и моих коллег убедиться, что весь код отформатирован черным?


person arjobsen    schedule 20.11.2020    source источник
comment
Я думаю, что было бы проблематично изменить содержимое файлов на хуке перед фиксацией. Обычно перехватчики предварительной фиксации используются для проверки определенных условий и, соответственно, разрешения или запрета выполнения фиксации. Возможно, вам стоит поискать другое решение.   -  person JoelFan    schedule 20.11.2020
comment
@JoelFan Нет проблем, просто не забывайте git add измененные файлы в конце хука.   -  person phd    schedule 21.11.2020
comment
git - это система контроля версий. Я бы не стал использовать его как средство форматирования кода. Тот факт, что вам нужно запомнить дополнительный шаг, является вашей подсказкой, что это неподходящий инструмент для работы.   -  person JoelFan    schedule 22.11.2020


Ответы (2)


Если вы ищете способ сделать это в bash, недостающим элементом головоломки является фильтр для git diff-index.

в вашем случае вы можете сравнить с HEAD, который ограничит его именами файлов:

$ git diff --staged --name-only --diff-filter=d -- '*.py'
t.py

выражение, как написано в исходном сообщении, также немного проблематично из-за файлов, потенциально содержащих пробелы в них - обычно исправление для этого заключается в использовании -z для вывода и xargs -0 для запуска инструмента (это приведет к тому, что имена файлов будут разделены '\0' ):

git diff --staged --name-only --diff-filter=d -z -- '*.py' |
    xargs -0 black

обратите внимание, что при этом потенциально будут пропущены некоторые файлы, которые найдет структура предварительной фиксации, например исполняемые файлы без расширений с python shebang или другие файлы, которые обычно являются файлами python, например .pdbrc

person Anthony Sottile    schedule 21.11.2020

чего бы это ни стоило, с помощью предварительной фиксации вы можете использовать _1 _ + _ 2_ аварийный люк, чтобы избежать загрузки инструментов (если они у вас уже установлены)

Например:

repos:
-   repo: local
    hooks:
    -   id: black-system
        name: black (system)
        entry: black
        types: [python]
        language: system
        require_serial: true

при этом это в значительной степени противоречит основным целям фреймворка, поскольку он больше не управляет установкой инструментов (поэтому вам придется настраивать их вручную самостоятельно)

в частности, если у вас не установлен черный, вы увидите что-то вроде:

$ pre-commit  run --all-files
black (system)...........................................................Failed
- hook id: black-system
- exit code: 1

Executable `black` not found

отказ от ответственности, я поддерживаю предварительную фиксацию

person Anthony Sottile    schedule 21.11.2020