Сделать так, чтобы индекс отражал файлы по указанным путям в рабочем дереве, включая их наличие

Сделать так, чтобы индекс отражал файлы по указанным путям в рабочем дереве, включая их наличие

У меня есть скрипт, который обновляет репозиторий и добавляет/удаляет файлы по некоторым заданным путям. Как я могу зафиксировать эти изменения, зная пути? Т.е.

  • Если указанный файл находится в рабочем дереве, скопировать его в индекс
  • Если указанный файл есть в индексе, но отсутствует в рабочем дереве, удалить его из индекса.
  • Если указанного файла нет ни в рабочем дереве, ни в индексе, ничего не делать.

git addпроисходит сбой в последнем граничном случае — если какой-либо из путей в командной строке не существует, он завершается с ошибкой и ничего не делает.

Я считал:

  • git add --ignore-errors, к сожалению, не считает отсутствие файла ошибкой, которую игнорирует.

  • git add --ignore-missingк сожалению существует, но работает только с --dry-run.

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

  • Один git add --allвызов не позволяет размещать только файлы по определенным путям.

решение1

Лучшее решение, которое я нашел на данный момент, — это создание списка путей для перехода git addпутем явного просмотра индекса git и рабочего дерева.

Учитывая репозиторий:

git init .
echo $RANDOM > ignore-edited
echo $RANDOM > ignore-deleted
echo $RANDOM > add-edited
echo $RANDOM > add-deleted
git add .
git commit -m 'Initial commit'

echo $RANDOM > ignore-new
echo $RANDOM > ignore-edited
rm             ignore-deleted
echo $RANDOM > add-new
echo $RANDOM > add-edited
rm             add-deleted

и список файлов для обновления:

printf '%s\n' add-new add-edited add-deleted add-nonexistent | sort \
    > /tmp/filelist.txt

Мы можем построить список файлов, получив объединение между пересечением наших файлов для добавления и индекса, а также пересечением наших файлов для добавления и файлов, существующих в рабочем дереве:

comm -12 /tmp/filelist.txt <(git ls-files) \
    > /tmp/files-in-index.txt
while read -r line ; do test -e "$line" && printf -- '%s\n' "$line" ; done < /tmp/filelist.txt \
    > /tmp/files-in-worktree.txt
sort -um /tmp/files-in-index.txt /tmp/files-in-worktree.txt \
    > /tmp/files-to-add.txt
< /tmp/files-to-add.txt xargs git add

Или, в одном призыве:

sort -um \
    <(comm -12 /tmp/filelist.txt <(git ls-files)) \
    <(while read -r line ; do test -e "$line" && printf -- '%s\n' "$line" ; done < /tmp/filelist.txt) |
    xargs git add

Связанный контент