Независимо от того, что еще произойдет, если вы что-то измените - даже один символ в имени пользователя и / или электронной почте - в каком-то коммите, вы получите новый, другой коммит. (Это потому, что идентификатор фиксации состоит из крипографической контрольной суммы содержимого фиксации. Итак, если вы можете сломать криптографию, вы можете создать две разные фиксации, которые будут иметь один и тот же идентификатор. Но тогда вы полностью разбитый мерзавец, и, вероятно, также выиграл премию Тьюринга или Нобелевскую премию. :-))
Лучше всего подойдет "рабочая ловушка", с которой вы связались в комментариях к другому ответу. Эта проблема сводится к одному: вы не можете вносить какие-либо изменения в опубликованный коммит (не вызывая проблем для пользователей этой публикации), но вы можете внести любые изменения в приват совершайте, пока вы «знаете, что делаете». Использование git commit --amend --author "$user <$email>" -C HEAD
для каждого отдельного коммита, поскольку они входят в вашу копию репо, гарантирует, что вы замените неопубликованный коммит новым, немного другим неопубликованным коммитом. (Я предполагаю, что вы поместили это в хук после фиксации.)
Я не уверен, какой частью вы недовольны, может быть, [ -n "$richo_git_rewrite" ] && exit 0
? Это достаточно умный метод обнаружения рекурсии. Альтернатива - пропустить обнаружение рекурсии и вместо этого сравнить существующего пользователя и адрес электронной почты в коммите с желаемыми.
Вот скрипт, который делает это (за исключением того, что я использовал переменную env SWITCHY = true для моего тестирования):
#! /bin/sh
# first, pick which git config variables to get
if ${SWITCHY-false}; then
config=user.work
else
config=user
fi
# next, find out if they're set
can_rewrite=false
target_author=$(git config --get $config.name) &&
target_email=$(git config --get $config.email) &&
can_rewrite=true
# If they ARE set, we can "rewrite" (replace) the commit;
# if not, we can't. Just because we can, though, does not
# mean we should. Find out if the current author and email
# differ from the desired ones.
if $can_rewrite; then
current_author=$(git log --pretty=format:%an HEAD -n 1)
current_email=$(git log --pretty=format:%ae HEAD -n 1)
if [ "$current_author" != "$target_author" -o \
"$current_email" != "$target_email" ]; then
# may want --allow-empty here, if you're allowing empty commits
# at all, otherwise empty ones don't get the rewrite done
git commit --amend --author "$target_author <$target_email>" -C HEAD
fi
fi
Примечание: вам нужно установить этот же хук в hooks/post-merge
, чтобы получить исправленные слияния с обновленным именем и адресом электронной почты. И, конечно, вы можете немного упростить ловушку (вам не нужна фактическая переменная can_rewrite, просто выполните две операции git config с &&
s и продолжайте работу с другой &&
). Также имеет смысл иметь больше, чем просто пользователь против пользователя. Работа, может быть, пользователь против пользователя. Режим А против пользователя. Режим Б и т. Д., И вы можете прогнать его из любых тестов, которые вам нравятся (переменные env, наличие или отсутствие команд, и т. д.).
ОК, согласно комментариям, есть хук перед фиксацией. К сожалению, он не работает с
git merge
(ловушка предварительной фиксации запускается и выдает сообщение, а затем включается фиксация слияния).
#! /bin/sh
fatal()
{
echo "$@" 1>&2
exit 1
}
# pick which git config variables to get
if ${SWITCHY-false}; then
config=user.work
else
config=user
fi
# tn, te = target author name/email
# an, ae = what git will use for author name/email
tn=$(git config --get $config.name) || exit 0
te=$(git config --get $config.email) || exit 0
an=${GIT_AUTHOR_NAME-$(git config --get user.name)} ||
fatal "no author name set"
ae=${GIT_AUTHOR_EMAIL-$(git config --get user.email)} ||
fatal "no author email set"
[ "$an" = "$tn" -a "$ae" = "$te" ] ||
fatal "git will use author $an <$ae>
but you want them as $tn <$te>
fix your environment variables and try again"
Вы могли бы объединить эту ловушку перед фиксацией с ловушкой перезаписи-фиксации после слияния ( eww :-)). Я не пробовал конфликтующий коммит, но, вероятно, хук перед фиксацией поймал конфликтующие слияния, которые требуют от вас сделать свой собственный коммит.
(Стоит также отметить, что этот хук перед фиксацией не смотрит на рабочее дерево или индекс, поэтому у него нет обычной ошибки "проверка рабочего дерева, но фиксация индекса".)