Как программно (в оболочке script) определить, есть ли изменения?

Я пытаюсь создать Bash script, который знает, есть ли изменения в текущем рабочем каталоге. Я знаю, что

$ git status

возвращает сообщение типа "ничего не делать". Я пытаюсь определить переменную в true или false. Это логическое значение скажет мне, есть или нет изменения.

Очевидно, что я не эксперт сценариев Bash. Я пробовал что-то вроде этого,

there_are_changes=$(git status | grep nothin)
echo $there_are_changes

но он не работает должным образом. Что мне делать?

Ответ 1

git-diff справочная страница описывает два варианта релевантности здесь:

--quiet
Disable all output of the program. Implies --exit-code.

и

--exit-code
Make the program exit with codes similar to diff(1). That is, it
exits with 1 if there were differences and 0 means no differences.

Следовательно, надежным подходом было бы запустить

git diff --quiet; nochanges=$?

Переменная оболочки nochanges будет равна 0 (т.е. true), если изменений нет, а 1 (т.е. false) в противном случае.

Затем вы можете использовать значение nochanges в условных операторах следующим образом:

if [ $nochanges -eq 0 ]; then
    # there are no changes
else
    # there are changes
fi

В качестве альтернативы, если вам не нужно сохранять статус выхода в переменной, вы можете сделать:

if git diff --quiet; then
    # there are no changes
else
    # there are changes
fi

Изменить. Поскольку git diff - это фарфоровая команда Git, и вы хотите делать что-то программно, вы, вероятно, должны использовать вместо этого команду Git, которая называется git diff-index (которая также имеет a --quiet, но должен быть предоставлен аргумент tree-ish):

if git diff-index --quiet HEAD; then
    # there are no changes
else
    # there are changes
fi

Ответ 2

Вы можете проверить, установлена ​​ли переменная с помощью выражения -n.

#!/bin/bash
CHANGESTOCOMMIT=$(git status | grep 'Changes to be com')
UNSTAGEDCHANGES=$(git status | grep 'Changes not staged')

# If there are staged changes:
if [ -n "$CHANGESTOCOMMIT" ]; then
    echo "Changes need to be committed"
fi
if [ -n "$UNSTAGEDCHANGES" ]; then
    echo "Changes made but not staged."
fi

Git отслеживает измененные файлы, которые поставлены для фиксации, а также неустановленные файлы, поэтому ваш script может захотеть проверить обе опции (или нет). Оператор -n проверяет, была ли задана переменная - если она пуста, она вернет false.

Альтернативой является -z, которая возвращает True, если она пуста (логическая противоположность -n. Полный список условных выражений можно найти в справочное руководство Bash.