Имеет ли git что-нибудь вроде `svn propset svn: keywords` или pre-/post-commit hooks?

Просматривая документацию git, я не вижу ничего похожего на крючки фиксации SVN или функции "propset", которые могут, скажем, обновлять номер версии или уведомление об авторских правах в файле всякий раз, когда он привязан к репозиторию.

Ожидают ли пользователи git писать внешние скрипты для такого рода функций (что не похоже на вопрос), или я просто пропустил что-то очевидное?

Изменить: просто чтобы быть ясным, меня больше интересует, например,

svn propset svn:keywords "Author Date Id Revision" expl3.dtx

где строка вроде этого:

$Id: expl3.dtx 780 2008-08-30 12:32:34Z morten $

постоянно обновляется с соответствующей информацией всякий раз, когда происходит фиксация.

Ответ 1

Цитата из Git FAQ:

Имеет ли git расширение ключевого слова?

Не рекомендуется. Расширение ключевых слов вызывает всевозможные странные проблемы и на самом деле не очень полезен, особенно в контексте SCM. за пределами git вы можете выполнить расширение ключевых слов с помощью script. Экспорт ядра Linux script делает это, чтобы установить переменную EXTRA_VERSION в Makefile.

См. gitattributes (5), если вы действительно хотите это сделать. Если ваш перевод не (например, расширение ключевого слова SCCS), это может быть проблематичным.

Ответ 2

Я написал довольно полный ответ по этому поводу в другом месте с кодом, показывающим, как это сделать. Резюме:

  • Вы, вероятно, не хотите этого делать. Использование git describe является разумной альтернативой.
  • Если вам нужно это сделать, $Id$ и $Format$ достаточно просты.
  • Для чего-либо более продвинутого потребуется использовать gitattributes и настраиваемый фильтр. Я предоставляю пример реализации $Date$.

Решения, основанные на функциях hook, обычно не помогают, потому что они делают вашу рабочую копию грязной.

Ответ 3

Git имеет привязки pre-commit и post-commit, они расположены внутри каждого каталога .git/hooks. Просто измените файлы и chmod их, чтобы сделать их исполняемыми.

Ответ 4

Возможно, наиболее распространенное свойство SVN, 'svn: ignore' выполняется через файл .gitignore, а не метаданные. Боюсь, у меня нет ничего более полезного для других видов метаданных.

Ответ 5

Хотя вековой Q & A. Я думал, что брошу его, потому что это долгое время подтачивало меня.

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

Git испортит мои планы, потому что при переключении ветки локальное репо полностью перезапишет отслеживаемые файлы из копий (инкрементных... я знаю...), которые находятся в упакованном локальном репо.

Таким образом, все файлы, которые были извлечены, будут иметь отметку времени проверки и не будут отражать их последнее время модификации..... Как так раздражает.

Итак, я разработал однострочный слой в bash, который будет обновлять свойство $Date: $в любом файле С ВРЕМЕНИ ПОСЛЕДНИХ МОДИФИКАЦИЙ В СООТВЕТСТВИИ С ЧЕГО, ЧТО ЭТО В СИСТЕМЕ ФАЙЛОВ так что у меня будет немедленный статус, рассказывающий о последней модификации, без необходимости просматривать git log, git show или любой другой инструмент, который дает время фиксации в режиме вины.

Следующая процедура изменит ключевое слово $Date: $только в отслеживаемых файлах, которые будут привязаны к репо. Он использует git diff --name-only, в котором будут перечислены файлы, которые были изменены, и ничего больше...

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

Здесь вариант кода для Linux (вставленный как многострочный для чтения)

git diff --name-only | xargs stat -c "%n %Y" 2>/dev/null | \
perl -pe 's/[^[:ascii:]]//g;' | while read l; do \
   set -- $l; f=$1;  shift; d=$*; modif=`date -d "@$d"`; \
   perl -i.bak -pe 's/\$Date: [\w \d\/:,.)(+-]*\$/\$Date: '"$modif"'\$/i' $f; \
   git add $f; done

и OSX

git diff --name-only | xargs stat -f "%N %Sm" | while read l; do \
   set -- $l; f=$1; shift; d=$*; modif=`date -j -f "%b %d %T %Y" "$d"`; \
   perl -i.bak -pe 's/\$Date: [\w \d\/:,.)(+-]*\$/\$Date: '"$modif"'\$/i' $f; \
   git add $f; done