Создание git вывода полных (не сокращенных) хэшей для всех команд?

Обновление вопроса

(n.b. Я принял ответ Роланда, поскольку он действительно правильный (и простейшее) решение, начиная с git 1.7.4.4, но, пожалуйста, рассмотрите этот вопрос открываются относительно более ранних версий git до 1.7.0.4.)

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

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

Поскольку я сосредоточен на обратной совместимости, это должно охватывать более старые версии of git 1.7. В идеале решения будут работать для git 1.7.0.4 (который используется в поддерживаемый Ubuntu 10.04 LTS), но я был бы доволен как минимум 1.7.2.5 (для Debian 6/Squeeze LTS). Все, что требует версии позже, чем 1.7.9.5 (Ubuntu 12.04 LTS) определенно не идеальна, но я все равно люблю слышать о них.

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

Предложение Роланда Смита об использовании переопределения аргумента командной строки для core.abbrev выглядел идеально, но, к сожалению, работает только с v1.7.4.4 (как core.abbrev ранее не существовало). Я подозреваю, что это означает, что нам нужно определить наиболее полный набор аргументов, специфичных для команды (например, git blame -l) для получения эквивалентного эффекта.

Оригинальный вопрос с редактированием

Некоторые (большинство?) git команд по умолчанию выдают сокращенные хэши. Для например, git blame и git-annotate делают это, и этот факт срабатывает вверх по текущей поддержке Emacs, когда возникли столкновения (как они могут сделать до git 1.7.11.1 - см. Редактирование 1 ниже), поскольку неоднозначные хэши затем вызвали ошибки, когда пытаясь действовать на них).


Начать редактирование 1

Я отмечаю следующее в списке изменений, которое предполагает, что исходная проблема которые вызвали этот вопрос, не возникли бы в более поздних версиях git.

Fixes since v1.7.11.1
---------------------
 * "git blame" did not try to make sure that the abbreviated commit
   object names in its output are unique.

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

End Edit 1


Это можно исправить с помощью git blame -l и git annotate -l, но я не знаю являются ли эти две команды изолированными случаями или нет, и я хочу обеспечить, чтобы этот вопрос не может возникнуть в других ситуациях.

Единственное, что связано с конфигурациями, я вижу core.abbrev:

Установить имена объектов длины сокращены. Если не указано, многие команды сокращенно до 7 hexdigits, что может быть недостаточно для сокращенного объекта чтобы оставаться уникальными в течение достаточно длительного времени.

(но я не хочу удалять вариант просмотра сокращенного коммита) и log.abbrevCommit который:

Если true, делает git -log (1), git -show (1) и git -whatchanged (1) --abbrev-commit. Вы можете переопределить эту опцию с помощью --no-abbrev-commit.

Аргумент --no-abbrev-commit не является последовательным, хотя, я полагаю, что только команды, упомянутые в этой цитате, распознают его (но см. Редактировать 2 ниже).


Начать редактирование 2

В документе документе API параметров анализа указано:

Логические длинные опции могут быть сведены на нет (или отменены) путем добавления no-, например. --no-abbrev вместо --abbrev. И наоборот, параметры, начинающиеся с no-можно отменить, удалив его.

Таким образом, команды, принимающие --abbrev (которых их много), будут фактически все принимают --no-abbrev, а? Этот отрицательный вариант часто не упоминается; хотя --abbrev=40 в настоящее время будет эквивалентным, конечно, даже если нет отрицание было доступно).

Мне непонятно, когда опция опции по умолчанию для булевского отрицания была однако.

В моей версии 1.7.9.5 git-blame --no-abbrev получается односимвольный объект имена. На самом деле это то же самое, что и --abbrev=0, поскольку в вине используются символы n+1. И наоборот, я замечаю, что git branch -v --abbrev=0 дает полный 40 символы.

End Edit 2


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

Уродливый подход, который возник для меня, заключался в создании конфигурационного файла git, который импортирует исходный файл конфигурации (хотя я отмечаю, что импорт только доступный от 1.7.10), а затем устанавливает core.abbrev в 40; и использовать это через временная переменная среды GIT_CONFIG при вызове git, когда полная обязательные требования. Я думаю, это сработает, но я бы предпочел не делать этого.

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

Для чего это стоит, вот что я почерпнул из grepping руководства для версия 1.7.12.4:

Команды, принимающие --abbrev (и, следовательно, в теории также --no-abbrev):

  • порицание
  • филиал
  • кли
  • описывают
  • дифф
  • Diff-индекс
  • Diff-дерево
  • Журнал
  • LS файлы
  • LS-дерево
  • преподобного список
  • преподобным синтаксического анализа
  • Шоу-исх

Другие параметры:

  • git annotate -l
  • git винить -l
  • git diff --full-index
  • git log --no-abbrev-commit
  • git show --no-abbrev-commit
  • git whatchanged --no-abbrev-commit

Ответы

Ответ 1

Использование git -c core.abbrev=40 <command> должно работать для всех команд, потому что оно "переопределит все, что определено в конфигурационных файлах".

Кажется, что он был введен в 8b1fa778676ae94f7a6d4113fa90947b548154dd (приземлился в версии 1.7.2).

Edit2: Как заметил phils, параметр core.abbrev был добавлен в 1.7.4.4.

Изменить: W.r.t. hardcoded hash lengths, вы всегда можете найти длину хэша, просмотрев длину имени файла в .git/objects/* при инициализации вашей программы/библиотеки.

Ответ 2

Примечание: использование git -c core.abbrev=x rebase -i хорошо работает для редактора (который будет отображать сокращенную фиксацию SHA1)

НО: он также использовал тот же сокращенный SHA1 для начала самой rebase.

Это больше не понадобится (значение git -c core.abbrev=40 rebase -i вообще не требуется).

См. commit edb72d5 от Кирилла А. Шутёва, для Git 2.3.1+ (Q1/Q2 2015):

rebase -i: используйте полное имя объекта внутри script

В предыдущие дни имя сокращенного имени объекта, показанное конечным пользователям, было сгенерировано с помощью hardcoded --abbrev=7; commit 5689503 (rebase -i: respect core.abbrev, 2013-09-28, Git 1.8.5+) попытался сделать это честью пользователь указал core.abbrev, но он пропустил самый первоначальный вызов редактора.

В наши дни мы пытаемся использовать полные имена объектов с шестью шестью, чтобы избежать неоднозначности, которая может возникнуть после начала перезагрузки. Недавно созданные объекты во время rebase могут использовать один и тот же префикс с существующими фиксациями, указанными в insn sheet.
Эти имена объектов укорачиваются непосредственно перед вызовом редактора последовательности, чтобы отправить запрос insn sheet конечному пользователю, а затем снова вернуться к полному имени объекта при возврате редактора.

Но код все еще использовал сокращенные имена при подготовке листа insn в первый раз, в результате получив "7 hexdigits или больше" для пользователя.

Измените код, чтобы использовать полные имена объектов фиксации 40-hex с самого начала, чтобы сделать вещи более однородными.

Примечание. Для интерактивной перезагрузки "insn sheet" является инструкцией . См. фиксация 3322ad4 для иллюстрации.

Ответ 3

Обратите внимание, что с Git 2.12 (Q1 2017) вы можете добавить git diff --no-index в список команд с помощью --no-abbrev:

См. commit 43d1948 (06 декабря 2016 г.) Джек Бейтс (jablko).
(слияние Junio ​​C Hamano - gitster - в commit c89606f, 19 декабря 2016 года)

diff: handle --no-abbrev в no-index case

Существует два разных места, где параметр --no-abbrev анализируется, и два разных места, где SHA-1 сокращены.
Обычно мы разбираем --no-abbrev с помощью setup_revisions(), но в случае без индекса "git diff" вызывает diff_opt_parse() напрямую, а diff_opt_parse() не обрабатывает --no-abbrev до сих пор. (Однако он обрабатывал --abbrev.)
Обычно мы сокращаем SHA-1 с помощью find_unique_abbrev(), но совершаем 4f03666 (" diff: сокращать аббревиатуры sha1 за пределами репозитория, 2016-10-20) недавно появился специальный случай, когда вы запускаете "git diff" вне репозитория.

setup_revisions() также вызывает diff_opt_parse(), но не для --abbrev или --no-abbrev, который он обрабатывает сам.
setup_revisions() устанавливает rev_info->abbrev, а затем копирует его на diff_options->abbrev. Он обрабатывает --no-abbrev, устанавливая аббревиатуру на ноль. (Это изменение не затрагивает этого.)

Установка аббревиатуры на ноль была нарушена во внеочередном хранилище случай, который до сих пор приводил к действительно SHA-1 с нулевой длиной, а не принимая нуль в среднем, не сокращайте.
Однако единственный способ вызвать эту ошибку - запустить "git diff --raw" без параметров --abbrev или --no-abbrev, потому что

  • без --raw он не уважает аббревиатуру (что причудливо, но так было навсегда),
  • мы тихо зажимаем --abbrev=0 до MINIMUM_ABBREV и
  • --no-abbrev не обрабатывался до сих пор.

Случай с внешним хранилищем является одним из трех случаев без индекса. другие два, когда один из файлов, которые вы сравниваете, находится за пределами репозиторий, в котором вы находитесь, и параметр --no-index.