Ключом к надежному «написанию сценариев» Git является использование «сантехнических» команд.
При изменении сантехнических команд разработчики заботятся о том, чтобы они обеспечивали очень стабильные интерфейсы (т. Е. Заданная комбинация состояния репозитория, стандартного ввода, параметров командной строки, аргументов и т. Д. Будет производить одинаковый вывод во всех версиях Git, где команда / вариант существует). Новые варианты вывода в сантехнических командах могут быть введены с помощью новых параметров, но это не может создавать проблем для программ, которые уже были написаны для более старых версий (они не будут использовать новые параметры, поскольку их не было (или, по крайней мере, не используется) на момент написания сценария).
К сожалению, «каждодневные» команды Git - это «фарфоровые» команды, поэтому большинство пользователей Git могут быть не знакомы с сантехническими командами. Различия между командами фарфора и сантехники выполняются на главной странице руководства git (см. Подразделы « Команды высокого уровня (фарфор)» и « Команды низкого уровня (сантехника)» .
Чтобы узнать о несвязанных изменениях, вам, вероятно, понадобится git diff-index
(сравнить индекс (и, возможно, отслеживаемые биты рабочего дерева) с некоторыми другими древовидными (например HEAD
)), возможно git diff-files
(сравнить рабочее дерево с индексом) и, возможно, git ls-files
(список файлов; например, список без отслеживания , проигнорированные файлы).
(Обратите внимание, что в приведенных ниже командах HEAD --
используется вместо, HEAD
потому что в противном случае команда не выполняется, если существует файл с именем HEAD
.)
Чтобы проверить, что хранилище внесло изменения (еще не зафиксировано), используйте это:
git diff-index --quiet --cached HEAD --
- Если он выходит с,
0
то не было никаких различий ( 1
значит, были различия).
Чтобы проверить, есть ли в рабочем дереве изменения, которые можно поставить:
git diff-files --quiet
- Код выхода такой же, как и для
git diff-index
( 0
== без различий; 1
== отличий).
Чтобы проверить, изменяется ли комбинация индекса и отслеживаемых файлов в рабочем дереве по отношению к HEAD
:
git diff-index --quiet HEAD --
- Это как комбинация двух предыдущих. Одно из главных отличий состоит в том, что он по-прежнему будет сообщать об отсутствии различий, если у вас есть поэтапное изменение, которое вы «отменили» в рабочем дереве (возвращаясь к содержимому, которое находится в нем
HEAD
). В этой же ситуации обе отдельные команды будут возвращать отчеты о «существующих различиях».
Вы также упомянули неотслеживаемые файлы. Вы можете иметь в виду «неотслеживаемый и игнорируемый», или вы можете иметь в виду просто «неотслеживаемый» (включая игнорируемые файлы). В любом случае, git ls-files
инструмент для работы:
Для «неотслеживаемых» (включая игнорируемые файлы, если они есть):
git ls-files --others
Для «неотслеживаемых и неопознанных»:
git ls-files --exclude-standard --others
Моя первая мысль - просто проверить, есть ли у этих команд вывод:
test -z "$(git ls-files --others)"
- Если он завершается с,
0
то нет неотслеживаемых файлов. Если он завершается с, 1
то есть неотслеживаемые файлы.
Существует небольшая вероятность того, что это преобразует git ls-files
аварийные выходы из отчетов «без отслеживания файлов» (оба результата приводят к ненулевым выходам вышеуказанной команды). Более надежная версия может выглядеть так:
u="$(git ls-files --others)" && test -z "$u"
- Идея та же, что и в предыдущей команде, но она позволяет распространяться неожиданным ошибкам
git ls-files
. В этом случае ненулевой выход может означать «есть неотслеживаемые файлы» или это может означать, что произошла ошибка. Если вы хотите, чтобы результаты «ошибка» сочетались с результатом «нет неотслеживаемых файлов», используйте test -n "$u"
(где выход 0
означает «некоторые неотслеживаемые файлы», а ненулевое значение означает ошибку или «нет неотслеживаемых файлов»).
Другая идея заключается в использовании --error-unmatch
для ненулевого выхода, когда нет неотслеживаемых файлов. Это также рискует связать «нет неотслеживаемых файлов» (выход 1
) с «произошла ошибка» (выход ненулевой, но, вероятно, 128
). Но проверка « 0
против» и « 1
против нуля» кодов выхода, вероятно, достаточно надежна:
git ls-files --others --error-unmatch . >/dev/null 2>&1; ec=$?
if test "$ec" = 0; then
echo some untracked files
elif test "$ec" = 1; then
echo no untracked files
else
echo error from ls-files
fi
Любой из приведенных выше git ls-files
примеров можно взять, --exclude-standard
если вы хотите рассмотреть только неотслеживаемые и незарегистрированные файлы.