Исключить файлы, созданные как удаленные из `git ls-files` - PullRequest
0 голосов
/ 27 июня 2019

Я использую git ls-files в скрипте для сбора всех файлов, отслеживаемых git. К сожалению, если вы rm файл (а не git rm), он больше не существует в файловой системе, но все равно будет указан в списке git ls-files

Итак, вопрос: Существует ли простой и эффективный способ исключить файлы, которых больше нет в файловой системе, из либо самого git ls-files вывода, либо путем его фильтрации потом (используя, например, bash)? Что-то вроде

git ls-files --existing-only

Справочная информация: я хочу создать фиктивную цель CMake, которая содержит все файлы, которые являются частью каталога проекта (то есть отслеживаются git). И я использую что-то вроде

execute_process(
    COMMAND bash -c "cd ${CMAKE_SOURCE_DIR}; git ls-files"
    OUTPUT_VARIABLE ADDITIONAL_PROJECT_FILES
)

для генерации списка файлов. Но, к сожалению, rm, если файл еще не внесен, изменение приведет к ошибкам, поскольку CMake больше не может найти этот файл ..

Обновление : Перед моим редактированием я говорил о git rm использовании файла - который будет корректно обработан git ls-files. Но проблема сохраняется: если кто-то удалит файл (без использования git для него), git ls-files выведет его список (и у меня возникнут проблемы).

Ответы [ 2 ]

0 голосов
/ 27 июня 2019

Я не думаю, что вы можете сделать это с самим git ls-files (незначительный позор, так как в противном случае это довольно удобно для такого рода вещей).

В конечном счете, для Git тот факт, что файл не существует в рабочем дереве, не важен для следующего коммита. В коммите используется все, что находится в области индекса / промежуточной области. Основное внимание git ls-files уделяется содержанию индекса, поэтому такие параметры, как --stage и --debug. Однако наличие параметра --others доказывает, что git ls-files может сканировать рабочее дерево. После сканирования рабочего дерева он может показать вам, какие файлы находятся в рабочем дереве, но отсутствуют в индексе: --others. Этот список может быть вычтен еще дальше, используя --exclude-standard и т. П.

В вашем конкретном случае вместо взятия списка файлов work-tree и вычитания тех, которые являются в index , вы бы хотел бы взять список index файлов и вычесть те, которые не в рабочем дереве . То есть, если мы определим I как набор файлов индекса и W как набор файлов рабочего дерева, мы увидим, что git ls-files может легко вычислить W \ I . Нам бы хотелось, чтобы он вычислял I \ W , набор файлов, которые есть в индексе, но отсутствуют в рабочем дереве, чтобы мы могли удалить их из вывода git ls-files.

Увы, такой опции нет. Это оставляет вас с git diff-files, который может легко вычислить этот набор файлов: git diff-files --name-only --diff-filter=D HEAD возвращает вам файлы, которые есть в индексе, но отсутствуют в рабочем дереве. Используйте этот список, чтобы удалить имена файлов из вывода git ls-files, и вы получите то, что вам нужно.

Важная боковая панель

Часто файлы, которые отсутствуют в рабочем дереве, но присутствуют в индексе, находятся в этом состоянии по ошибке, и правильное решение состоит в том, чтобы извлечь их из индекса в рабочее дерево. Кроме того, каждый раз, когда вы планируете что-то сделать с набором файлов, которые сейчас находятся в индексе, вы должны учитывать тот факт, что копии этих файлов в рабочем дереве могут отличаться из копий в указателе. Например, ловушка Git pre-commit может быть предназначена для того, чтобы убедиться, что файлы правильно отформатированы для некоторого исходного языка: если их запуск через clang-format или black оставит их неизменными, например.

Проверка этого путем проверки файлов рабочего дерева в корне неверна, поскольку Git не собирается создавать коммит из рабочего дерева. Это означает, что эти инструменты должны извлекать весь индекс во временное (новое и пустое) рабочее дерево где-то еще в файловой системе , а затем запускать средство форматирования или любое другое инструмент, который будет использоваться, на этом временном рабочем дереве. Результат этого процесса говорит вам, следует ли продолжать коммит. Затем вы удаляете временное рабочее дерево (т. Е. Очищаете после себя) и предоставляете соответствующий статус выхода «можно совершить» / «нет, не совершать».

0 голосов
/ 27 июня 2019

git ls-files имеет немало опций отображения ... проверить git ls-files --help

Похоже, что в вашем случае вариант --killed будет тем, что вы хотите.

...