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


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

допустим, я делаю git РЕПО с папкой / foo/. В эту папку я положил /foo/program.py. я бегу program.py и программа.pyc создается. У меня есть.* pyc в the .gitignore файл, так что git не отслеживает его.

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

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

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

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

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

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

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

4 52

4 ответа:

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

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

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

просто копирование и обновление хорошего решения 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

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

мое решение-это более совместим с git: Git удаляет только каталоги enpty, где любой файл был удален при проверке. Он не ищет полное дерево workcopy. Это полезно для больших репозиториев или репозиториев с очень большим игнорируемым деревом, таких как виртуальные среды по 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=""
newrev=""
# ignored param: branchcheckout=""

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

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

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

мой полный короткий исходный код(Python) is in
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 может быть медленным.