Как проверить, нет ли чего-либо в текущей ветке?

Цель состоит в том, чтобы получить однозначный статус, который можно оценить с помощью команды оболочки.

Я попробовал git status но он всегда возвращает 0, даже если есть элементы для фиксации.

git status
echo $?  #this is always 0

У меня есть идея, но я думаю, что это довольно плохая идея.

if [ git status | grep -i -c "[a-z]"> 2 ];
then
 code for change...
else
  code for nothing change...
fi

Любым другим путем?


обновить с последующим решением, см. сообщение Марка Лонгэйра

Я пробовал это, но это вызывает проблему.

if [ -z $(git status --porcelain) ];
then
    echo "IT IS CLEAN"
else
    echo "PLEASE COMMIT YOUR CHANGE FIRST!!!"
    echo git status
fi

Я получаю следующую ошибку [:??: binary operator expected

сейчас я смотрю на мужчину и пробую git diff.

=================== код для моей надежды, и надеюсь, что лучший ответ ======================

#if [ 'git status | grep -i -c "$"' -lt 3 ];
# change to below code,although the above code is simple, but I think it is not strict logical
if [ 'git diff --cached --exit-code HEAD^ > /dev/null && (git ls-files --other --exclude-standard --directory | grep -c -v '/$')' ];
then
        echo "PLEASE COMMIT YOUR CHANGE FIRST!!!"
    exit 1

else
    exit 0
fi

Ответ 1

Альтернативой проверке того, является ли вывод git status --porcelain пустым, является проверка каждого условия, о котором вы заботитесь отдельно. Возможно, не все равно, например, если на выходе git status есть файлы без следа.

Например, чтобы увидеть, есть ли какие-либо локальные неустановленные изменения, вы можете посмотреть код возврата:

git diff --exit-code

Чтобы проверить, есть ли какие-либо изменения, которые были поставлены, но не зафиксированы, вы можете использовать код возврата:

git diff --cached --exit-code

Наконец, если вы хотите узнать, есть ли какие-либо неископанные файлы в рабочем дереве, которые не игнорируются, вы можете проверить, является ли вывод следующей команды пустым:

git ls-files --other --exclude-standard --directory

Обновление. Ниже вы спрашиваете, можете ли вы изменить эту команду, чтобы исключить каталоги на выходе. Вы можете исключить пустые каталоги, добавив --no-empty-directory, но чтобы исключить все каталоги в этом выпуске, я думаю, вам придется фильтровать выходные данные, например:

git ls-files --other --exclude-standard --directory | egrep -v '/$'

-v to egrep означает только вывод строк, которые не соответствуют шаблону, и шаблон соответствует любой строке, которая заканчивается на /.

Ответ 2

Возвращаемое значение состояния git status просто сообщает вам код завершения состояния git status, если нет каких-либо изменений, которые нужно зафиксировать.

Если вам нужна более читаемая версия вывода git status, попробуйте

git status --porcelain

Смотрите описание git status для получения дополнительной информации об этом.

Пример использования (скрипт просто проверяет, выдает ли git status --porcelain какой-либо вывод, анализ не требуется):

if [ -n "$(git status --porcelain)" ]; then
  echo "there are changes";
else
  echo "no changes";
fi

Обратите внимание, что вы должны git status --porcelain в кавычки строку для проверки, то есть вывод состояния git status --porcelain. Для получения дополнительных советов о тестовых конструкциях см. Руководство по расширенному написанию сценариев Bash (Сравнение строк раздела).

Ответ 3

Если вы похожи на меня, вы хотите узнать, есть ли:

1) изменяется на существующие файлы 2) новые файлы 3) удаленные файлы

и, в частности, не хотят знать о 4) невоспроизводимых файлах.

Это должно сделать это:

git status --untracked-files=no --porcelain

Здесь мой код bash для выхода из script, если репо очищено. Он использует короткую версию опций untracked files:

[[ -z $(git status -uno --porcelain) ]] && echo "this branch is clean, no need to push..." && kill -SIGINT $$;

Ответ 4

Можно выполнить git status --porcelain с помощью простого grep для выполнения теста.

if git status --porcelain | grep .; then
    echo Repo is dirty
else
    echo Repo is clean
fi

Я использую это как простой однострочный слой:

# pull from origin if our repo is clean
git status --porcelain | grep . || git pull origin master

Добавьте -qs в команду grep, чтобы заставить его замолчать.

Ответ 5

Из исходного кода git находится sh script, который включает следующее.

require_clean_work_tree () {
    git rev-parse --verify HEAD >/dev/null || exit 1
    git update-index -q --ignore-submodules --refresh
    err=0

    if ! git diff-files --quiet --ignore-submodules
    then
        echo >&2 "Cannot $1: You have unstaged changes."
        err=1
    fi

    if ! git diff-index --cached --quiet --ignore-submodules HEAD --
    then
        if [ $err = 0 ]
        then
            echo >&2 "Cannot $1: Your index contains uncommitted changes."
        else
            echo >&2 "Additionally, your index contains uncommitted changes."
        fi
        err=1
    fi

    if [ $err = 1 ]
    then
        test -n "$2" && echo >&2 "$2"
        exit 1
    fi
}

Этот sniplet показывает, как можно использовать git diff-files и git diff-index, чтобы узнать, есть ли какие-либо изменения в ранее известных файлах. Однако он не позволяет вам узнать, добавлен ли новый файл неизвестного файла в рабочее дерево.

Ответ 6

я бы сделал тест на это:

git diff --quiet --cached

или это явно:

git diff --quiet --exit-code --cached

где:

- выход-код

Сделайте вывод программы с кодами, подобными diff (1). То есть, он выходит с 1, если существуют различия, а 0 означает отсутствие различий.

- тихий

Отключить все выходные данные программы. Implies --exit-code

Ответ 7

Я использую это в script, чтобы иметь:

  • 0, когда все чисто.
  • 1, когда есть файлы diff или untracked

    [-z "$ (git status --porcelain)" ]

Ответ 8

Я немного опоздал в обсуждении, но если вам нужен только код выхода 0, если git status --porcelain ничего не возвращает и еще! = 0, попробуйте это:

exit $( git status --porcelain | wc -l )

Это сделает количество строк кодом выхода…

Ответ 9

Не очень, но работает:

git status | grep -qF 'working directory clean' || echo "DIRTY"

Не уверен, зависит ли сообщение от языкового стандарта, поэтому, возможно, перед ним стоит LANG=C.