Почему `git description -dirty` добавляет суффикс`-dirty` при описании чистой проверки?

Я только что обнаружил --dirty возможность git describe и похоже, что он должен сделать что-то очень полезное, то есть добавить суффикс к выводу git describe когда рабочее дерево грязное, однако в некоторых моих репозиториях это не так:

$ git status
# On branch 8.30
nothing to commit (working directory clean)
$ git describe --dirty
8.30rel-8-g9c1cbdb-dirty

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

$ git status
# On branch 1.4
nothing to commit (working directory clean)
$ git describe --tags --dirty --long
1.4rel-0-gfedfe66-dirty

Я имел обыкновение широко использовать hg id когда я использовал Mercurial и мне понравилось то, что это поведение по умолчанию было добавить + суффикс к любому хешу коммитов, о котором сообщалось для грязного репозитория, так что ищите git с тех пор, но git describe --dirty кажется, не делает то, что я ожидал, учитывая документацию:

   --dirty[=<mark>]
       Describe the working tree. It means describe HEAD and appends
       <mark> (-dirty by default) if the working tree is dirty.

Я неправильно понимаю, что --dirty должен делать, или я не правильно его использую?

В случае, если это что-то меняет, все репозитории git развертываются через buckminster, поэтому не задействованы подмодули, а файловая система является nfs доля.


Обновление: я нашел обходной путь, но я абсолютно не представляю, как это может иметь значение.

Если я бегу git diff --quiet HEAD на репо, то вдруг git describe работает как я ожидаю:

$ git status
# On branch 8.30
nothing to commit (working directory clean)
$ git describe --dirty
8.30rel-8-g9c1cbdb-dirty
$ git diff --quiet HEAD
$ git describe --dirty
8.30rel-8-g9c1cbdb

Я также заметил, что когда git describe сообщал о хранилище как dirty затем gitk также показывал "Локальные незафиксированные изменения, не зарегистрированные в индексе", а затем перечислял каждый файл в рабочем каталоге, но без различий с ними, только ---- filename ---- линий.


Дальнейшее обновление: поскольку это продолжало быть проблемой, я в конечном итоге написал git-describe-dirty скрипт, который начинается с запуска git describe --dirty но если он находит хранилище грязным, запускается git update-index -q --refresh прежде чем пытаться снова и взять второй результат.

При переборе сотен репозиториев, используя git describe-dirty и только запуск обновления индекса для репозитория, который изначально указывает, что он грязный, экономит много времени по сравнению с запуском git update-index -q --refresh ; git describe --dirty каждый раз.

2 ответа

Решение

Если вы используете git 1.7.6 или более раннюю версию, вам нужно запустить git update-index --refresh Перед использованием git describe --dirtyпотому что индекс может быть устаревшим. Ваш обходной путь использования git diff --quiet HEAD работает, потому что "git diff" является командой фарфора и, вероятно, обновляет сам индекс.

Git commit, который исправляет это для git 1.7.7, описывает проблему:

При запуске git description --dirty необходимо обновить индекс. Ранее кешированный индекс заставлял описывать думать, что индекс был грязным, хотя на самом деле он был просто устаревшим.

Обратите внимание, что точная последовательность шагов, которые вы описываете, не должна иметь этой проблемы, потому что git status обновляет индекс. Но я все еще думаю, что вы видите ту же самую проблему, потому что обходной путь, который вы описываете, соответствует. Вот как я демонстрирую проблему:

% git describe --tags --dirty
v1.0.0
% touch pom.xml
% git describe --tags --dirty
v1.0.0-dirty
% git status
# On branch dev
nothing to commit (working directory clean)
% git describe --tags --dirty
v1.0.0

Здесь запуск "git status" обновляет индекс как побочный эффект и исправляет вывод "git description", как и в случае с вашим обходным решением. Правильное исправление для git 1.7.6 и более ранних версий:

% touch pom.xml
% git describe --tags --dirty
v1.0.0-dirty
% git update-index --refresh
% git describe --tags --dirty
v1.0.0

Помните, что было еще одно исправление ошибки, касающееся git describe --dirty, около года назад: https://github.com/git/git/commit/a1e19004e11dcbc0ceebd92c425ceb1770e52d0b

"git --work-tree=$there --git-dir=$here describe --dirty" работал некорректно, поскольку не обращал внимания на расположение рабочего дерева, указанное пользователем.

В случае этой ошибки описанные здесь обходные пути не работали, поэтому нам пришлось обновить нашу установку. Похоже, на сегодняшний день (2020-02-20) нет готового исправления для Debian buster, но основные пакеты Git Debian bullseye совместимы с buster прямо сейчас.

Git 2.13 (Q2 2017) немного улучшается --dirty флаг с --broken один, так как git describe --dirty "умирает, когда невозможно определить, соответствует ли состояние в рабочем дереве состоянию HEAD (например, поврежденный репозиторий или сломанный субмодуль).

Смотрите коммит b0176ce (21 марта 2017 г.) Stefan Beller ( stefanbeller )
(Объединено Юнио С Хамано - gitster - в коммите 844768a, 27 марта 2017 г.)

builtin/describe: вводить --broken флаг

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

Чтобы сохранить это свойство только для ошибок, когда в репозитории нет, серьезные (субмодульные) ошибки должны быть понижены до аккуратного сообщения о них вместо того, чтобы git-describe ошибка полностью.

Чтобы достичь этого флага " --broken "вводится, что в том же духе, что и" --dirty но использует фактический дочерний процесс для проверки на грязь. Когда этот ребенок неожиданно умрет, мы добавим -broken ' вместо ' -dirty',

Другие вопросы по тегам