Как изменить автора коммита для одного конкретного коммита? - PullRequest
1762 голосов
/ 15 июня 2010

Я хочу сменить автора одного конкретного коммита в истории. Это не последний коммит.

Я знаю об этом вопросе - Как изменить автора коммита в git?

Но я думаю о чем-то, где я идентифицирую коммит по хешу или короткому хешу.

Ответы [ 13 ]

2988 голосов
/ 15 июня 2010

Интерактивная перебазировка с точки ранее в истории, чем коммит, который вам нужно изменить (git rebase -i <earliercommit>).В списке подтвержденных коммитов измените текст с pick на edit рядом с хэшем того, который вы хотите изменить.Затем, когда git предложит вам изменить коммит, используйте это:

git commit --amend --author="Author Name <email@address.com>"

Например, если ваша история коммитов A-B-C-D-E-F с F как HEAD, и вы хотите изменитьавтор C и D, тогда вы бы ...

  1. Укажите git rebase -i B ( вот пример того, что вы увидите после выполнения команды git rebase -i B)
    • , если вам нужно отредактировать A, используйте git rebase -i --root
  2. измените строки для C и D с pick до edit
  3. Как только начнется ребазинг, он сначала остановится на C
  4. Вы бы git commit --amend --author="Author Name <email@address.com>"
  5. Затем git rebase --continue
  6. Это снова остановится на D
  7. Затем вы снова git commit --amend --author="Author Name <email@address.com>"
  8. git rebase --continue
  9. Перебазирование будет завершено.
  10. Использование git push -f чтобы обновить ваш источник обновленными коммитами.
414 голосов
/ 04 марта 2015

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

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

Следующее проверено и работает, в отличие от связанного ответа. Предположим для ясности изложения, что 03f482d6 - это коммит, автора которого мы пытаемся заменить, а 42627abe - это коммит с новым автором.

  1. Оформить коммит, который мы пытаемся изменить.

    git checkout 03f482d6
    
  2. Внесите изменения в автора.

    git commit --amend --author "New Author Name <New Author Email>"
    

    Теперь у нас есть новый коммит с хешем, равным 42627abe.

  3. Оформить оригинальную ветку.

  4. Заменить старый коммит на новый локально.

    git replace 03f482d6 42627abe
    
  5. Переписать все будущие коммиты на основе замены.

    git filter-branch -- --all
    
  6. Снять замену на чистоту.

    git replace -d 03f482d6
    
  7. Нажмите новую историю (используйте --force, если приведенное ниже не выполнено, и только после проверки работоспособности с помощью git log и / или git diff).

    git push --force-with-lease
    

Вместо 4-6 вы можете просто перейти на новый коммит:

git rebase -i 42627abe
181 голосов
/ 09 июня 2015

Документация Github содержит скрипт, который заменяет информацию о коммитере для всех коммитов в ветке .

#!/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
114 голосов
/ 05 апреля 2017
  • Глобально сбросьте ваш адрес электронной почты для конфигурации:

    git config --global user.email example@email.com

  • Теперь сбросьте автора вашей фиксации без необходимости редактирования:

    git commit --amend --reset-author --no-edit

75 голосов
/ 29 августа 2015

Вы можете изменить автора последнего коммита, используя команду ниже.

git commit --amend --author="Author Name <email@address.com>"

Однако, если вы хотите изменить более одного коммита, имя автора немного сложнее. Вам нужно начать интерактивную перебазировку, затем пометить коммиты как правки, затем изменить их один за другим и закончить.

Начните ребазинг с git rebase -i. Это покажет вам что-то вроде этого.

https://monosnap.com/file/G7sdn66k7JWpT91uiOUAQWMhPrMQVT.png

Измените ключевое слово pick на edit для коммитов, для которых вы хотите изменить имя автора.

https://monosnap.com/file/dsq0AfopQMVskBNknz6GZZwlWGVwWU.png

Затем закройте редактор. Для начинающих нажмите Escape, затем введите :wq и нажмите Enter.

Тогда вы увидите свой терминал, как будто ничего не произошло. На самом деле вы находитесь в середине интерактивной перебазировки. Теперь пришло время изменить имя автора вашего коммита, используя команду выше. Он снова откроет редактор. Выйдите и продолжите ребаз с git rebase --continue. Повторите то же самое для количества коммитов, которое вы хотите отредактировать. Вы можете убедиться, что интерактивное восстановление завершено, когда вы получите сообщение No rebase in progress?.

50 голосов
/ 15 июня 2010

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

В качестве предлога для попытки git filter-branch,Я написал скрипт для перезаписи имени автора и / или автора сообщения для данного коммита:

#!/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
27 голосов
/ 30 июня 2018

Зафиксировать до:

enter image description here

Чтобы исправить автора для всех коммитов, вы можете применить команду из ответа @ Amber:

git commit --amend --author="Author Name <email@address.com>"

Или, чтобы повторно использовать свое имя и адрес электронной почты, вы можете просто написать:

git commit --amend --author=Eugen

Фиксация после команды:

enter image description here

Например, чтобы изменить все, начиная с 4025621:

enter image description here

Вы должны запустить:

git rebase --onto 4025621 --exec "git commit --amend --author=Eugen" 4025621

Примечание. Чтобы включить автора, содержащего пробелы, такие как имя и адрес электронной почты, автор должен быть заключен в кавычки. Например:

git rebase --onto 4025621 --exec "git commit --amend --author=\"Foo Bar <foo@bar.com>\"" 4025621

или добавьте этот псевдоним в ~/.gitconfig:

[alias]
    reauthor = !bash -c 'git rebase --onto $1 --exec \"git commit --amend --author=$2\" $1' --

А затем запустите:

git reauthor 4025621 Eugen
15 голосов
/ 20 декабря 2013

Существует один дополнительный шаг для ответа Амбер , если вы используете централизованное хранилище:

git push -f для принудительного обновления центрального хранилища.

Будьте осторожны, чтобы над одной веткой работало не так много людей, потому что это может нарушить последовательность.

13 голосов
/ 28 августа 2013

При выполнении 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 "correct@new.email"
  • создать пустые коммиты (по одному на каждый коммит):
    • вам нуженсообщение для цели перебазировки
    • 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's 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's 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

Это будетпредложит вам отредактировать сообщениеs:

# This is a combination of 2 commits.
# The first commit's message is:

empty

# This is the 2nd commit message:

...some useful commit message there...

и вы можете просто удалить первые несколько строк.

1 голос
/ 26 июня 2019

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

git checkout branch_name

Найдите коммит перед коммитом, который вы хотите изменить, и найдите его хеш. Затем выполните команду rebase.

git rebase -i -p хэш коммита

Затем откроется редактор и введите 'edit' для коммитов, которые вы хотите изменить. Оставьте других с опцией «выбрать» по умолчанию. После изменения введите клавишу «esc» и wq! выйти.

Затем введите команду git commit с опцией исправления.

git commit --amend --author = "Email пользователя" --no-edit

Затем введите следующую команду.

git rebase - продолжение

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

...