Я хочу сменить автора одного конкретного коммита в истории. Это не последний коммит.
Я знаю об этом вопросе - как мне изменить автора коммита в git?
Но я думаю о чем-то, где я идентифицирую коммит по хешу или короткому хешу.
Интерактивная перебазировка с точки ранее в истории, чем коммит, который вам нужно изменить (git rebase -i <earliercommit>
). В списке коммитов, которые были перебазированы, измените текст с pick
на edit
рядом с хэшем того, который вы хотите изменить. Затем, когда git предложит вам изменить коммит, используйте это:
git commit --amend --author="Author Name <[email protected]>"
Например, если ваша история коммитов ABCDE-f
с F
качестве HEAD
, и вы хотите сменить автора C
и D
, то вы бы...
git rebase -i B
(вот пример того, что вы увидите после выполнения команды git rebase -i B
) A
, используйте git rebase -i --root
C
и D
от pick
до edit
C
git commit --amend --author="Author Name <[email protected]>"
git rebase --continue
D
git commit --amend --author="Author Name <[email protected]>"
git rebase --continue
git push -f
чтобы обновить ваш источник обновленными коммитами.git rebase -i <commit>
Принятым ответом на этот вопрос является удивительно умное использование интерактивного перебазирования, но, к сожалению, оно вызывает конфликты, если коммит, который мы пытаемся изменить, автор использовал для ветки, которая впоследствии была объединена. В более общем случае, это не работает при обработке грязных историй.
Поскольку я опасаюсь запуска скриптов, которые зависят от установки и сброса переменных среды для перезаписи истории git, я пишу новый ответ на основе этого поста, который похож на этот ответ, но является более полным.
Следующее проверено и работает, в отличие от связанного ответа. Предположим для ясности изложения, что 03f482d6
- это коммит, автора которого мы пытаемся заменить, а 42627abe
- это коммит с новым автором.
Оформите коммит, который мы пытаемся изменить.
git checkout 03f482d6
Заставьте автора изменить.
git commit --amend --author "New Author Name <New Author Email>"
Теперь у нас есть новый коммит с хешем, равным 42627abe
.
Оформить заказ оригинальной ветке.
Замените старый коммит на новый локально.
git replace 03f482d6 42627abe
Переписать все будущие коммиты на основе замены.
git filter-branch -- --all
Удалите замену для чистоты.
git replace -d 03f482d6
Нажмите на новую историю (используйте только --force, если приведенное ниже не удается, и только после проверки работоспособности с помощью git log
и/или git diff
).
git push --force-with-lease
Вместо 4-6 вы можете просто перейти на новый коммит:
git rebase -i 42627abe
Документация Github содержит a script, который заменяет информацию коммиттера для всех коммитов в ветке.
#!/bin/sh
git filter-branch --env-filter '
OLD_EMAIL="[email protected]"
CORRECT_NAME="Your Correct Name"
CORRECT_EMAIL="[email protected]"
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 config --global user.email [email protected]
Теперь сбросьте автора вашего коммита без необходимости редактирования:
git commit --amend --reset-author --no-edit
It's not last commit.
Так как бы они amend
это?
git reset HEAD~
, запустил предложенные строки, а затем снова сделал следующий коммит вручную. Сработало нормально!
Вы можете изменить автора последней фиксации, используя приведенную ниже команду.
git commit --amend --author="Author Name <[email protected]>"
Однако, если вы хотите изменить более одного имени автора, это немного сложно. Вам нужно начать интерактивную переустановку, затем пометить коммиты как править, а затем поменять их один за другим и закончить.
Запустите перезагрузку с помощью git rebase -i
. Он покажет вам что-то вроде этого.
Измените ключевое слово pick
на edit
для коммитов, которые вы хотите изменить имя автора.
Затем закройте редактор. Для новичков нажмите Escape
, затем введите :wq
и нажмите Enter
.
Тогда вы увидите свой терминал, как будто ничего не произошло. На самом деле вы находитесь в середине интерактивной перестановки. Теперь пришло время изменить ваше имя автора фиксации, используя команду выше. Он снова откроет редактор. Закройте и продолжите перезагрузку с помощью git rebase --continue
. Повторите то же самое для количества фиксации, которое вы хотите отредактировать. Вы можете убедиться, что интерактивная сводка закончилась, когда вы получили сообщение No rebase in progress?
.
Ответы на вопрос, на который вы связаны, являются хорошими ответами и охватывают вашу ситуацию (другой вопрос более общий, поскольку он включает в себя переписывание нескольких коммитов).
В качестве предлога для опроса git filter-branch
я написал script, чтобы переписать имя автора и/или авторскую электронную почту для данной фиксации:
#!/bin/sh
#
# Change the author name and/or email of a single commit.
#
# change-author [-f] commit-to-change [branch-to-rewrite [new-name [new-email]]]
#
# If -f is supplied it is passed to "git filter-branch".
#
# If <branch-to-rewrite> is not provided or is empty HEAD will be used.
# Use "--all" or a space separated list (e.g. "master next") to rewrite
# multiple branches.
#
# If <new-name> (or <new-email>) is not provided or is empty, the normal
# user.name (user.email) Git configuration value will be used.
#
force=''
if test "x$1" = "x-f"; then
force='-f'
shift
fi
die() {
printf '%s\n' "$@"
exit 128
}
targ="$(git rev-parse --verify "$1" 2>/dev/null)" || die "$1 is not a commit"
br="${2:-HEAD}"
TARG_COMMIT="$targ"
TARG_NAME="${3-}"
TARG_EMAIL="${4-}"
export TARG_COMMIT TARG_NAME TARG_EMAIL
filt='
if test "$GIT_COMMIT" = "$TARG_COMMIT"; then
if test -n "$TARG_EMAIL"; then
GIT_AUTHOR_EMAIL="$TARG_EMAIL"
export GIT_AUTHOR_EMAIL
else
unset GIT_AUTHOR_EMAIL
fi
if test -n "$TARG_NAME"; then
GIT_AUTHOR_NAME="$TARG_NAME"
export GIT_AUTHOR_NAME
else
unset GIT_AUTHOR_NAME
fi
fi
'
git filter-branch $force --env-filter "$filt" -- $br
При выполнении git rebase -i
есть этот интересный бит в документе:
Если вы хотите сбросить две или более коммитов в одну, замените команду
"pick"
на вторую и последующую фиксацию с помощью"squash"
или"fixup"
. Если у коммитов были разные авторы, сложенный фиксаж будет приписан автору первого коммита. Предлагаемое сообщение фиксации для сложенного фиксации представляет собой конкатенацию сообщений фиксации первого фиксации и команд с командой"squash"
, но опускает сообщения фиксации коммитов с помощью команды"fixup"
.
A-B-C-D-E-F
,B
и D
(= 2 коммиты),то вы можете сделать:
git config user.name "Correct new name"
git config user.email "[email protected]"
git commit --allow-empty -m "empty"
git rebase -i B^
B^
выбирает родительский элемент B
.pick
на squash
для них.Пример того, что git rebase -i B^
даст вам:
pick sha-commit-B some message
pick sha-commit-C some message
pick sha-commit-D some message
pick sha-commit-E some message
pick sha-commit-F some message
# pick sha-commit-empty1 empty
# pick sha-commit-empty2 empty
измените это на:
# change commit B author
pick sha-commit-empty1 empty
squash sha-commit-B some message
# leave commit C alone
pick sha-commit-C some message
# change commit D author
pick sha-commit-empty2 empty
squash sha-commit-D some message
# leave commit E-F alone
pick sha-commit-E some message
pick sha-commit-F some message
Он предложит вам отредактировать сообщения:
# This is a combination of 2 commits.
# The first commit message is:
empty
# This is the 2nd commit message:
...some useful commit message there...
и вы можете просто удалить первые несколько строк.
Есть еще один шаг к Янтарный ответ, если вы используете централизованный репозиторий:
git push -f
, чтобы принудительно обновить центральный репозиторий.
Будьте осторожны, чтобы в одной ветки не было много людей, потому что это может привести к потере последовательности.
Зафиксировать перед:
Чтобы исправить автора для всех коммитов, вы можете применить команду из @Amber answer:
git commit --amend --author="Author Name <[email protected]>"
Или, чтобы повторно использовать свое имя и адрес электронной почты, вы можете просто написать:
git commit --amend --author=Eugen
Фиксация после команды:
Например, чтобы изменить все, начиная с 4025621
:
Ты должен бежать:
git rebase --onto 4025621 --exec "git commit --amend --author=Eugen" 4025621
Примечание. Чтобы включить автора с пробелами, такими как имя и адрес электронной почты, автор должен быть заключен в кавычки. Например:
git rebase --onto 4025621 --exec "git commit --amend --author=\"Foo Bar <[email protected]>\"" 4025621
или добавьте этот псевдоним в ~/.gitconfig
:
[alias]
reauthor = !bash -c 'git rebase --onto $1 --exec \"git commit --amend --author=$2\" $1' --
А затем запустите:
git reauthor 4025621 Eugen
git shortlog -e -s
, я просмотрел вывод git shortlog -e -s
.