Как проверить, что в текущей ветке нечего зафиксировать? - PullRequest
154 голосов
/ 28 февраля 2011

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

Я пытался 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

Ответы [ 9 ]

193 голосов
/ 28 февраля 2011

Альтернативой проверке, является ли вывод 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 до egrep означает вывод только тех строк, которые не соответствуют шаблону, а шаблон соответствует любой строке, заканчивающейся /.

100 голосов
/ 28 февраля 2011

Возвращаемое значение 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. Дополнительные советы о тестовых конструкциях см. В Расширенное руководство по написанию сценариев Bash (Раздел Сравнение строк ).

29 голосов
/ 07 февраля 2013

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

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

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

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

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

Вот мой bash-код для выхода из скрипта, если репозиторий чист. Используется короткая версия опции неотслеживаемых файлов:

[[ -z $(git status -uno --porcelain) ]] && echo "this branch is clean, no need to push..." && kill -SIGINT $$;
8 голосов
/ 10 октября 2013

Для выполнения теста можно объединить 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 голосов
/ 01 марта 2011

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

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
}

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

4 голосов
/ 01 ноября 2016

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

git diff --quiet --cached

или это должно быть явно:

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

где:

- экзит-код

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

- тихий

Отключить все выходные данные программы. Подразумевает - Exit-код

2 голосов
/ 28 марта 2018

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

1 голос
/ 15 декабря 2017

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

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

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

0 голосов
/ 28 февраля 2011

Не красиво, но работает:

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

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

...