Почему `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'
,