Как я могу проверить, есть ли у меня какие-либо незафиксированные изменения в моем git-репозитории:
- Изменения добавлены в индекс, но не зафиксированы
- Неотслеживаемые файлы
из скрипта?
git-status
кажется, всегда возвращает ноль с версией git 1.6.4.2.
diff
указать наличие или отсутствие различий, а не успешное выполнение команды, вам нужно использовать--exit-code
или--quiet
. Команды git, как правило, очень согласуются с возвратом нулевого или ненулевого кода завершения, чтобы указать успешность команды.Ответы:
Отличное время! Я написал пост в блоге именно об этом несколько дней назад, когда выяснил, как добавить информацию о состоянии git в мою подсказку.
Вот что я делаю:
Для грязного статуса:
Для неотслеживаемых файлов (обратите внимание на
--porcelain
флаг, сgit status
которым вы можете получить хороший анализируемый вывод):Хотя
git diff --shortstat
это более удобно, вы также можете использоватьgit status --porcelain
для получения грязных файлов:Примечание:
2>/dev/null
Фильтрует сообщения об ошибках, чтобы вы могли использовать эти команды в не-git каталогах. (Они просто вернутся0
для подсчета файлов.)Редактировать :
Вот посты:
Добавление информации о состоянии Git в подсказку терминала
Улучшенная подсказка оболочки с поддержкой Git
источник
__git_ps1
. Он показывает имена веток, включая особый режим, если вы находитесь в процессе ребазирования, am-apply, merge или bisect. И вы можете установить переменную среды,GIT_PS1_SHOWDIRTYSTATE
чтобы получить звездочку для не поэтапных изменений и плюс для поэтапных изменений. (Я думаю, что вы также можете получить его, чтобы указать неотслеживаемые файлы и дать вам некоторыйgit-describe
вывод)git diff --shortstat
даст ложный отрицательный результат, если изменения уже внесены в индекс.git status --porcelain
является предпочтительным, потомуgit diff --shortstat
что не будет ловить вновь созданные пустые файлы. Вы можете попробовать это в любом чистом рабочем дереве:touch foo && git diff --shortstat
Ключом к надежному «написанию сценариев» Git является использование «сантехнических» команд.
При изменении сантехнических команд разработчики заботятся о том, чтобы они обеспечивали очень стабильные интерфейсы (т. Е. Заданная комбинация состояния репозитория, стандартного ввода, параметров командной строки, аргументов и т. Д. Будет производить одинаковый вывод во всех версиях Git, где команда / вариант существует). Новые варианты вывода в сантехнических командах могут быть введены с помощью новых параметров, но это не может создавать проблем для программ, которые уже были написаны для более старых версий (они не будут использовать новые параметры, поскольку их не было (или, по крайней мере, не используется) на момент написания сценария).
К сожалению, «каждодневные» команды Git - это «фарфоровые» команды, поэтому большинство пользователей Git могут быть не знакомы с сантехническими командами. Различия между командами фарфора и сантехники выполняются на главной странице руководства git (см. Подразделы « Команды высокого уровня (фарфор)» и « Команды низкого уровня (сантехника)» .
Чтобы узнать о несвязанных изменениях, вам, вероятно, понадобится
git diff-index
(сравнить индекс (и, возможно, отслеживаемые биты рабочего дерева) с некоторыми другими древовидными (напримерHEAD
)), возможноgit diff-files
(сравнить рабочее дерево с индексом) и, возможно,git ls-files
(список файлов; например, список без отслеживания , проигнорированные файлы).(Обратите внимание, что в приведенных ниже командах
HEAD --
используется вместо,HEAD
потому что в противном случае команда не выполняется, если существует файл с именемHEAD
.)Чтобы проверить, что хранилище внесло изменения (еще не зафиксировано), используйте это:
0
то не было никаких различий (1
значит, были различия).Чтобы проверить, есть ли в рабочем дереве изменения, которые можно поставить:
git diff-index
(0
== без различий;1
== отличий).Чтобы проверить, изменяется ли комбинация индекса и отслеживаемых файлов в рабочем дереве по отношению к
HEAD
:HEAD
). В этой же ситуации обе отдельные команды будут возвращать отчеты о «существующих различиях».Вы также упомянули неотслеживаемые файлы. Вы можете иметь в виду «неотслеживаемый и игнорируемый», или вы можете иметь в виду просто «неотслеживаемый» (включая игнорируемые файлы). В любом случае,
git ls-files
инструмент для работы:Для «неотслеживаемых» (включая игнорируемые файлы, если они есть):
Для «неотслеживаемых и неопознанных»:
Моя первая мысль - просто проверить, есть ли у этих команд вывод:
0
то нет неотслеживаемых файлов. Если он завершается с,1
то есть неотслеживаемые файлы.Существует небольшая вероятность того, что это преобразует
git ls-files
аварийные выходы из отчетов «без отслеживания файлов» (оба результата приводят к ненулевым выходам вышеуказанной команды). Более надежная версия может выглядеть так:git ls-files
. В этом случае ненулевой выход может означать «есть неотслеживаемые файлы» или это может означать, что произошла ошибка. Если вы хотите, чтобы результаты «ошибка» сочетались с результатом «нет неотслеживаемых файлов», используйтеtest -n "$u"
(где выход0
означает «некоторые неотслеживаемые файлы», а ненулевое значение означает ошибку или «нет неотслеживаемых файлов»).Другая идея заключается в использовании
--error-unmatch
для ненулевого выхода, когда нет неотслеживаемых файлов. Это также рискует связать «нет неотслеживаемых файлов» (выход1
) с «произошла ошибка» (выход ненулевой, но, вероятно,128
). Но проверка «0
против» и «1
против нуля» кодов выхода, вероятно, достаточно надежна:Любой из приведенных выше
git ls-files
примеров можно взять,--exclude-standard
если вы хотите рассмотреть только неотслеживаемые и незарегистрированные файлы.источник
git ls-files --others
выдает локальные неотслеживаемые файлы, аgit status --porcelain
из принятого ответа - все неотслеживаемые файлы, которые находятся в репозитории git. Я не тот, который хотел оригинальный плакат, но разница между ними интересна.--error-unmatch
. Попробуйте (например)git ls-files --other --error-unmatch --exclude-standard .
(обратите внимание на конечный период, он относится к cwd; запустите его из каталога верхнего уровня рабочего дерева).git update-index -q --refresh
перед тем,diff-index
чтобы избежать «ложных срабатываний», вызванных несовпадением информации stat (2).git update-index
необходимостью! Это важно, если что-то касается файлов без внесения изменений.--porcelain
списках решений все неотслеживаемые файлов , найденных в целом репозиторий (минус ГИТ-игнорируемые файлы), даже если вы находитесь в одном из его подкаталогов.Предполагая, что вы находитесь на Git 1.7.0 или более поздней версии ...
Прочитав все ответы на этой странице и немного поэкспериментировав, я думаю, что метод, который находит правильное сочетание правильности и краткости:
Хотя git учитывает много нюансов между тем, что отслеживается, игнорируется, не отслеживается, но игнорируется и т. Д., Я полагаю, что типичный вариант использования - для автоматизации сценариев сборки, где вы хотите остановить все, если ваша проверка не чистая.
В этом случае имеет смысл смоделировать действия программиста: наберите
git status
и посмотрите на результат. Но мы не хотим полагаться на показ определенных слов, поэтому мы используем--porcelain
режим, введенный в 1.7.0; при включении чистый каталог не приводит к выводу.Затем мы используем,
test -n
чтобы увидеть, был ли какой-либо вывод или нет.Эта команда вернет 1, если рабочий каталог чистый, и 0, если есть изменения, которые нужно зафиксировать. Вы можете изменить
-n
к ,-z
если вы хотите наоборот. Это полезно для связывания этого с командой в сценарии. Например:Это фактически говорит: «либо нет никаких изменений, которые нужно сделать, либо выведите сигнал тревоги»; эта однострочная строка может быть предпочтительнее оператора if в зависимости от сценария, который вы пишете.
источник
test -n "$(git diff origin/$branch)"
, чтобы помочь предотвратить локальные коммиты в развертыванииРеализация из ответа VonC :
источник
Посмотрел несколько из этих ответов ... (и имел различные проблемы с * nix и windows, что было моим требованием) ... нашел, что следующее работает хорошо ...
Чтобы проверить код выхода в * nix
Проверить код выхода в окне $
Получено с https://github.com/sindresorhus/pure/issues/115 Благодаря @paulirish на этом посту, для обмена
источник
Почему бы не инкапсулировать
git status
сценарий, который:Таким образом, вы можете использовать этот «расширенный» статус в вашем скрипте.
Как 0xfe упоминает в своем превосходном ответе , он
git status --porcelain
играет важную роль в любом решении на основе сценариевисточник
Возможность "Сделай сам", обновлена в соответствии с предложением 0xfe
Как отметил Крис Джонсен , это работает только на Git 1.7.0 или новее.
источник
--porcelain
был добавлен флаг? Не работает с 1.6.4.2.git status --short
тогда.git status --porcelain
иgit status --short
оба были введены в 1.7.0.--porcelain
Он был введен специально, чтобы позволитьgit status --short
изменить его формат в будущем. Таким образом,git status --short
пострадает та же проблема, что иgit status
(выход может измениться в любое время, так как это не команда «слесарного дела»).Мне часто требовался простой способ завершить сборку, если в конце выполнения есть какие-либо измененные отслеживаемые файлы или неотслеживаемые файлы, которые не игнорируются.
Это очень важно для избежания случая, когда сборки производят остатки.
Пока что лучшая команда, которую я использовал в итоге, выглядит так:
Это может выглядеть немного сложным, и я был бы признателен, если бы кто-нибудь нашел укороченный вариант, который поддерживает желаемое поведение:
источник
Ответ @ eduard-wirch был довольно полным, но, поскольку я хотел проверить оба варианта одновременно, вот мой последний вариант.
Когда не выполняется с использованием set -e или эквивалентного, мы вместо этого можем сделать
u="$(git ls-files --others)" || exit 1
(или вернуть, если это работает для используемой функции)Таким образом, untracked_files устанавливается только в том случае, если команда выполнена успешно.
после чего мы можем проверить оба свойства и установить переменную (или любую другую).
источник
Это более скорлупа дружественный вариант для выяснения , если какие - либо неотслеживаемые файлы существуют в хранилище:
Это не является вторым процессом
grep
и не требует проверки, находитесь ли вы в git-репозитории или нет. Что удобно для подсказок оболочки и т. Д.источник
Вы также можете сделать
, В конце он добавит слово «-dirty», если обнаружит грязное рабочее дерево. По словам
git-describe(1)
:, Предостережение: неотслеживаемые файлы не считаются «грязными», потому что, как говорится на man-странице, он заботится только о рабочем дереве.
источник
Там может быть лучшей комбинацией ответов из этой темы .. но это работает для меня ... для вашего
.gitconfig
«s[alias]
раздела ...источник
Простейший автоматический тест, который я использую для обнаружения грязного состояния = любые изменения, включая неотслеживаемые файлы :
НОТА:
add --all
diff-index
не замечает неотслеживаемых файлов.git reset
после проверки кода ошибки, чтобы вернуть все обратно.источник
Вот лучший, самый чистый способ. Выбранный ответ по какой-то причине у меня не сработал, он не собирал инсценированные изменения, которые были новыми файлами, которые не были зафиксированы.
источник