Автоматически удалять * .pyc файлы и другие пустые каталоги, когда я проверяю новую ветку - PullRequest
53 голосов
/ 01 октября 2009

Итак, вот интересная ситуация при использовании git и python, и я уверен, что это происходит и в других ситуациях.

Допустим, я делаю git-репо с папкой / foo /. В эту папку я положил /foo/program.py. Я запускаю program.py и program.pyc создан. У меня есть * .pyc в файле .gitignore, поэтому git его не отслеживает.

Теперь, допустим, я делаю другую ветку, dev. В этой ветке dev я полностью удаляю папку / foo /.

Теперь я переключаюсь обратно на главную ветку, и / foo / появляется снова. Я запускаю program.py и файл program.pyc появляется снова. Все хорошо.

Я снова переключаюсь на свою ветку разработчика. Каталог / foo / должен исчезнуть. Он существует только в основной ветке, а не в ветке dev. Тем не менее, он все еще там. Зачем? Поскольку игнорируемый файл program.pyc предотвращает удаление папки при переключении ветвей.

Решением этой проблемы является рекурсивное удаление всех файлов * .pyc перед переключением веток. Я легко могу сделать это с помощью этой команды.

find . -name "*.pyc" -exec rm '{}' ';'

Проблема в том, что раздражает необходимость вспоминать об этом почти каждый раз, когда я меняю ветки. Я мог бы создать псевдоним для этой команды, но тогда мне все еще нужно помнить, чтобы вводить его каждый раз, когда я меняю ветви. Я также мог бы сделать псевдоним для git-branch, но это тоже не хорошо. Команда git branch делает и другие вещи, кроме изменения веток, и я не хочу удалять все файлы pyc каждый раз, когда использую его. Черт, я мог бы даже использовать его в репозитории без Python, тогда что?

Есть ли способ установить git hook, который выполняется только когда я меняю ветки? Или есть какой-то другой способ установить все * .pyc файлы, которые будут стираться всякий раз, когда я переключаю ветки?

Ответы [ 4 ]

41 голосов
/ 01 октября 2009

Есть крючок post-checkout, который нужно поместить в .git / hooks / post-checkout. Там, вероятно, есть образец, возможно, с именем .sample или, возможно, не исполняемый, в зависимости от вашей версии git. Краткое описание: он получает три параметра: предыдущий HEAD, новый HEAD и флаг, который равен 1, если ветвь изменилась, и 0, если это была просто проверка файла. Смотрите man githooks для получения дополнительной информации! Вы должны быть в состоянии написать сценарий оболочки, чтобы сделать то, что вам нужно, и поместить его туда.

Редактировать: Я понимаю, что вы хотите сделать эту предварительную проверку, чтобы проверка автоматически очищала каталоги, которые становились пустыми. Однако здесь нет ловушки предварительной проверки, поэтому вам придется использовать свой сценарий и для удаления каталогов.

Другое примечание: Псевдонимы являются частью gitconfig, который может быть локальным для репозитория (в .git / config, а не в ~ / .gitconfig). Если вы решите сделать это с псевдонимами (для git-checkout, а не git-branch), вы можете легко поместить их только в связанные с python репозитории. Также в этом случае я бы сделал псевдоним специально для этой цели (например, cc для checkout clean). Вы все еще можете использовать checkout (или другую его псевдоним), если не хотите очищать pyc-файлы.

36 голосов
/ 27 ноября 2009

Просто скопировав и обновив хорошее решение Apreche, которое было похоронено в комментариях:

Сохраните этот сценарий оболочки в файл /path/to/repo/.git/hooks/post-checkout и сделайте его исполняемым.

#! /bin/sh

# Start from the repository root.
cd ./$(git rev-parse --show-cdup)

# Delete .pyc files and empty directories.
find . -name "*.pyc" -delete
find . -type d -empty -delete
5 голосов
/ 12 октября 2014

Другим вариантом является не решение этой проблемы вообще, а проблема Python. Вы можете использовать переменную окружения PYTHONDONTWRITEBYTECODE, чтобы в первую очередь Python не мог писать файлы .pyc. Тогда вам нечего будет очищать при переключении веток.

3 голосов
/ 12 октября 2014

Мое решение более совместимо с git : Git удаляет только каталоги enpty, где любой файл был удален извлечением. Он не ищет полное дерево рабочей копии. Это полезно для больших репозиториев или репозиториев с очень большим игнорируемым деревом, таких как виртуальные среды с пакетом tox для тестирования множества различных версий Python и т. Д.

Моя первая реализация очень четко объясняет принцип: Удаляются только файлы pyc , относящиеся к файлам под управлением версиями . Это из соображений эффективности и нежелательных побочных эффектов.

#!/bin/bash
# A hook that removes orphan "*.pyc" files for "*.py" beeing deleted.
# It doesn not clean anything e.g. for .py files deleted manually.
oldrev="$1"
newrev="$2"
# ignored param: branchcheckout="$3"

for x in $(git diff --name-only --diff-filter=DR $oldrev..$newrev | grep "\.py$")
do
    if test -a ${x}c && ! test -a ${x}; then
        rm ${x}c
    fi
done

Хук post-checkout получает три полезных параметра, которые позволяют точно узнать, какие файлы были удалены git checkout, без поиска в полном дереве.

После прочтения вопроса я переписал свой код подключения к Python и расширил его в соответствии с вашими требованиями относительно пустых каталогов.

Мой полный короткий исходный код (Python) в
https://gist.github.com/hynekcer/476a593a3fc584278b87#file-post-checkout-py

Строка документа:

"""
A hook to git that removes orphan files "*.pyc" and "*.pyo" for "*.py"
beeing deleted or renamed by git checkout. It also removes their empty parent
directories.
Nothing is cleaned for .py files deleted manually or by "git rm" etc.
Place it to "my_local_repository/.git/hooks/post-checkout" and make it executable
"""
  • Проблема с * .pyc файлами не важна для Python 3 , потому что * .pyc файлы в __pycache__ не могут быть выполнены без связанного * .py * файла в его родительском файле каталог.

  • Каталог изменений не требуется, так как перехваты запускаются каждый раз в корне хранилища.

  • Каталоги кеша для скомпилированного кода __pycache__ полностью очищены, потому что они никогда не важны (не участвуют ни в каком бинарном распределении), а также для высокой эффективности, потому что удаление по частям __pycache__/some_name.*.pyc может быть медленным.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...