Здесь есть отличный пост: Список онлайн-пользователей .
Вы можете создать прослушиватель, который прослушивает событие kernel.controller
и обновляет поле пользователя lastActivity каждый раз, когда пользователь активен. Вы можете проверить lastActivity < now()- 2 minutes
и обновить временную метку lastActivity.
Также: Реализация активности пользователя в symfony 2
Примечание. Если вы не используете FOSUserBundle, см. раздел «Редактировать» ниже.
1 Добавьте это в свой пользовательский объект
/**
* Date/Time of the last activity
*
* @var \Datetime
* @ORM\Column(name="last_activity_at", type="datetime")
*/
protected $lastActivityAt;
/**
* @param \Datetime $lastActivityAt
*/
public function setLastActivityAt($lastActivityAt)
{
$this->lastActivityAt = $lastActivityAt;
}
/**
* @return \Datetime
*/
public function getLastActivityAt()
{
return $this->lastActivityAt;
}
/**
* @return Bool Whether the user is active or not
*/
public function isActiveNow()
{
// Delay during wich the user will be considered as still active
$delay = new \DateTime('2 minutes ago');
return ( $this->getLastActivityAt() > $delay );
}
2 Create Слушатель событий
securityContext = $securityContext;
$this->userManager = $userManager;
}
/**
* Update the user "lastActivity" on each request
* @param FilterControllerEvent $event
*/
public function onCoreController(FilterControllerEvent $event)
{
// Check that the current request is a "MASTER_REQUEST"
// Ignore any sub-request
if ($event->getRequestType() !== HttpKernel::MASTER_REQUEST) {
return;
}
// Check token authentication availability
if ($this->securityContext->getToken()) {
$user = $this->securityContext->getToken()->getUser();
if ( ($user instanceof UserInterface) && !($user->isActiveNow()) ) {
$user->setLastActivityAt(new \DateTime());
$this->userManager->updateUser($user);
}
}
}
}
3 Объявить событие Слушатель как услуга
parameters:
acme_user.activity_listener.class: Acme\UserBundle\EventListener\ActivityListener
services:
acme_user.activity_listener:
class: %acme_user.activity_listener.class%
arguments: [@security.context, @fos_user.user_manager]
tags:
- { name: kernel.event_listener, event: kernel.controller, method: onCoreController }
И вы готовы идти!
1 Добавьте это в свой пользовательский объект
Same as Step 1 Above
2 Создайте прослушиватель событий
securityContext = $securityContext;
$this->entityManager = $entityManager;
}
/**
* Update the user "lastActivity" on each request
* @param FilterControllerEvent $event
*/
public function onCoreController(FilterControllerEvent $event)
{
// Check that the current request is a "MASTER_REQUEST"
// Ignore any sub-request
if ($event->getRequestType() !== HttpKernel::MASTER_REQUEST) {
return;
}
// Check token authentication availability
if ($this->securityContext->getToken()) {
$user = $this->securityContext->getToken()->getUser();
if ( ($user instanceof User) && !($user->isActiveNow()) ) {
$user->setLastActivityAt(new \DateTime());
$this->entityManager->flush($user);
}
}
}
}
3 Объявите событие Слушателем как услугой
parameters:
acme_user.activity_listener.class: Acme\UserBundle\EventListener\ActivityListener
services:
acme_user.activity_listener:
class: %acme_user.activity_listener.class%
arguments: [@security.context, @doctrine.orm.entity_manager]
tags:
- { name: kernel.event_listener, event: kernel.controller, method: onCoreController }
И ты в порядке!
Смена автора (или коммиттера) потребовала бы переписывания всей истории. Если вы согласны с этим и считаете, что оно того стоит, вам следует проверить git filter-branch . Страница man содержит несколько примеров, с которых можно начать. Также обратите внимание, что вы можете использовать переменные окружения для изменения имени автора, коммиттера, дат и т. Д. - см. Раздел «Переменные среды» на справочной странице git .
В частности, вы можете С помощью этой команды исправьте все неправильные имена и адреса электронной почты для всех веток и тегов (источник: GitHub help ):
#!/bin/sh
git filter-branch --env-filter '
OLD_EMAIL="your-old-email@example.com"
CORRECT_NAME="Your Correct Name"
CORRECT_EMAIL="your-correct-email@example.com"
if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
then
export GIT_COMMITTER_NAME="$CORRECT_NAME"
export GIT_COMMITTER_EMAIL="$CORRECT_EMAIL"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
then
export GIT_AUTHOR_NAME="$CORRECT_NAME"
export GIT_AUTHOR_EMAIL="$CORRECT_EMAIL"
fi
' --tag-name-filter cat -- --branches --tags
Один вкладыш, но будьте осторожны, если у вас есть многопользовательский репозиторий - это изменит все коммиты , чтобы иметь одинакового (нового) автора и коммиттера ,
git filter-branch -f --env-filter "GIT_AUTHOR_NAME='Newname'; GIT_AUTHOR_EMAIL='new@email'; GIT_COMMITTER_NAME='Newname'; GIT_COMMITTER_EMAIL='new@email';" HEAD
С разрывами строк в строке (что возможно в bash):
git filter-branch -f --env-filter "
GIT_AUTHOR_NAME='Newname'
GIT_AUTHOR_EMAIL='new@email'
GIT_COMMITTER_NAME='Newname'
GIT_COMMITTER_EMAIL='new@email'
" HEAD
Вы также можете:
git filter-branch --commit-filter '
if [ "$GIT_COMMITTER_NAME" = "<Old Name>" ];
then
GIT_COMMITTER_NAME="<New Name>";
GIT_AUTHOR_NAME="<New Name>";
GIT_COMMITTER_EMAIL="<New Email>";
GIT_AUTHOR_EMAIL="<New Email>";
git commit-tree "$@";
else
git commit-tree "$@";
fi' HEAD
Обратите внимание: если вы используете эту команду в командной строке Windows, вам необходимо использовать "
вместо '
:
git filter-branch --commit-filter "
if [ "$GIT_COMMITTER_NAME" = "<Old Name>" ];
then
GIT_COMMITTER_NAME="<New Name>";
GIT_AUTHOR_NAME="<New Name>";
GIT_COMMITTER_EMAIL="<New Email>";
GIT_AUTHOR_EMAIL="<New Email>";
git commit-tree "$@";
else
git commit-tree "$@";
fi" HEAD
Вы могли бы сделать
git rebase -i -p <some HEAD before all of your bad commits>
Затем пометить все свои плохие коммиты как «редактировать» в файле перебазирования. Если вы также хотите изменить свою первую фиксацию, вам нужно вручную добавить ее в качестве первой строки в файл перебазирования (следуйте формату других строк). Затем, когда git просит вас изменить каждую фиксацию, выполните
git commit --amend --author "New Author Name <email@address.com>"
отредактируйте или просто закройте открывшийся редактор, а затем выполните
git rebase --continue
, чтобы продолжить перебазирование.
Вы можете вообще не открывать редактор, добавив ] - без редактирования
так что команда будет:
git commit --amend --author "New Author Name <email@address.com>" --no-edit && \
git rebase --continue
Как отметили некоторые из комментаторов, если вы просто хотите изменить самую последнюю фиксацию, команда rebase не нужна. Просто выполните
git commit --amend --author "New Author Name <email@address.com>"
. Это изменит автора на указанное имя, но в качестве коммиттера будет указан ваш настроенный пользователь в git config user.name
и git config user.email
. Если вы хотите установить для коммиттера то, что вы укажете, это установит и автора, и коммиттера:
git -c user.name="New Author Name" -c user.email=email@address.com commit --amend --reset-author
В моем исходном ответе был небольшой изъян. Если есть какие-либо коммиты слияния между текущим HEAD
и вашим
, то git rebase
сгладит их (и Кстати, если вы используете запросы на вытягивание GitHub, в вашей истории будет масса коммитов слияния). Это очень часто может привести к очень разной истории (поскольку повторяющиеся изменения могут быть «перебазированы»), а в худшем случае это может привести к git rebase
с просьбой разрешить сложные конфликты слияния (которые, вероятно, были уже разрешено в коммитах слияния). Решение состоит в том, чтобы использовать флаг -p
для git rebase
, который сохранит структуру слияния вашей истории. Страница руководства для git rebase
предупреждает, что использование -p
и -i
может привести к проблемам, но в разделе ОШИБКИ
говорится: « Редактирование коммитов и изменение их сообщений о коммитах должно работать нормально. "
Я добавил -p
в приведенную выше команду. Для случая, когда вы
Для одной фиксации:
git commit --amend --author="Author Name <email@address.com>"
(извлечено из ответа Асмерера)
Если вы единственный пользователь этого репозитория, вы можете перезаписать историю , используя либо git filter-branch
(как svick написал ), или git fast-export
/ git fast-import
плюс скрипт фильтра (как описано в статье, указанной в docgnome answer ), или интерактивном перебазировать . Но любой из них изменит ревизии, начиная с первого измененного коммита; это означает проблемы для любого, кто основывал свои изменения на предварительной перезаписи вашей ветки.
ВОССТАНОВЛЕНИЕ
Если бы другие разработчики не основывали свою работу на предварительной версии, самым простым решением было бы повторное клонирование (повторное клонирование).
В качестве альтернативы они могут попробовать git rebase --pull
, который будет перематывать вперед, если в их репозитории не было никаких изменений, или перенастроить свою ветку поверх перезаписанных коммитов (мы хотим, чтобы избегайте слияния, так как это навсегда сохранит коммиты до перезаписи). Все это при условии, что они не завершили работу; в противном случае используйте git stash
, чтобы спрятать изменения.
Если другие разработчики используют ветки функций и / или git pull --rebase
не работает, напримерпоскольку восходящий поток не настроен, они должны перебазировать свою работу поверх коммитов после перезаписи. Например, сразу после получения новых изменений ( git fetch
) для ветки master
, основанной на / разветвленной от origin / master
, необходимо запустить
$ git rebase --onto origin/master origin/master@{1} master
Здесь origin / master @ {1}
- состояние предварительной перезаписи (до выборки), см. gitrevisions .
Альтернативным решением было бы использование механизма refs / replace / , доступного в Git начиная с версии 1.6.5. В этом решении вы предоставляете замену коммитам с неправильным адресом электронной почты; затем любой, кто получает «заменить» ссылки (что-то вроде fetch = + refs / replace / *: refs / replace / *
refspec в соответствующем месте в их .git / config
) будут заменены прозрачно, и те, кто не получит эти ссылки, увидят старые коммиты.
Процедура выглядит примерно так:
Найти все коммиты с неправильным адресом электронной почты, например, с помощью
$ git log (скрыто) --all
Для каждой неправильной фиксации создайте заменяющую фиксацию и добавьте ее в базу данных объектов
$ git cat-file -p |
sed -e (скрытый)> tmp.txt
$ git hash-object -t commit -w tmp.текст
Теперь, когда вы исправили фиксацию в базе данных объектов, вы должны указать git автоматически и прозрачно заменить неправильную фиксацию исправленной с помощью команды git replace
:
$ git replace
Наконец, перечислите все замены, чтобы проверить, завершилась ли эта процедура
$ git replace -l
и проверьте, происходят ли замены
$ git log (скрыто) --all
Вы, конечно, можете автоматизировать эту процедуру ... ну, все, кроме использования git replace
, в котором (пока) нет пакетного режима, поэтому вам придется использовать для этого цикл оболочки или заменить "рукой".
НЕ ПРОВЕРЯЛСЯ! YMMV.
Обратите внимание, что вы можете столкнуться с трудностями при использовании механизма refs / replace /
: он новый и еще не очень хорошо протестирован .
Как упоминал docgnome, переписывать историю опасно и может сломать чужие репозитории.
Но если вы действительно хотите это сделать и находитесь в среде bash (в Linux это не проблема, в Windows вы можете использовать git bash, который поставляется с установкой git), используйте git filter-branch:
git filter-branch --env-filter '
if [ $GIT_AUTHOR_EMAIL = bad@email ];
then GIT_AUTHOR_EMAIL=correct@email;
fi;
export GIT_AUTHOR_EMAIL'
Чтобы ускорить процесс, вы можете указать диапазон ревизий, которые вы хотите переписать:
git filter-branch --env-filter '
if [ $GIT_AUTHOR_EMAIL = bad@email ];
then GIT_AUTHOR_EMAIL=correct@email;
fi;
export GIT_AUTHOR_EMAIL' HEAD~20..HEAD
Если вы единственный пользователь этого репо или не заботитесь о возможном нарушении репо для других пользователей, тогда да. Если вы разместили эти коммиты, и они существуют там, где к ним есть доступ, тогда нет, если вы не заботитесь о взломе репозиториев других людей. Проблема в том, что, изменяя эти коммиты, вы будете генерировать новые SHA, которые будут обрабатывать их как разные коммиты. Когда кто-то другой пытается втянуть эти измененные коммиты, история становится другой и бестолковой.
На этой странице http://inputvalidation.blogspot.com/2008/08/how-to-change-git-commit-author.html описано, как это сделать. (Я не пробовал, так что YMMV)
Все ответы выше переписывают историю репозитория. Пока имя к изменению не использовалось несколькими авторами и особенно если бы репозиторий был совместно использован, и фиксация стара, я предпочел бы использовать .mailmap
, зарегистрированный в https://git-scm.com/docs/git-shortlog. Это позволяет отображать неправильные имена/электронные письма к корректному, не изменяя repo историю. Можно использовать строки как:
Proper Name <proper@email.xx> <root@localhost>
Для тех, которые под окнами, Вы могли также использовать фильтр ракеты мерзавца инструмент.
От документация :
имя автора фиксации Изменения и электронная почта:
git-rocket-filter --branch TestBranch --commit-filter '
if (commit.AuthorName.Contains("Jim")) {
commit.AuthorName = "Paul";
commit.AuthorEmail = "paul@company.com";
}