Как изменить автора коммита для одного конкретного коммита?


2109

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

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

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


Ответы:


3570

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

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

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

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

90
Хороший ответ, но для начинающих: сначала найдите коммит, предшествующий тому, который вы хотели бы изменить, а затем выполнитеgit rebase -i <commit>
Мэтью Бирн

47
Если вы не знаете, в каком редакторе вы находитесь, ответ скорее всего vim. Чтобы сохранить и выйти, введите Esc: wq Enter. С другой стороны, если это Nano, и вы видите такие вещи, как «WriteOut: ^ O» внизу, тогда вам следует использовать Ctrl + O, Enter, Ctrl + X.
Янтарь

30
Что делать, если вы хотите изменить самый первый коммит? Каков хэш предыдущего коммита?
Бренден

219
Используйте --no-editопцию. git commit --amend --reset-author --no-editне открывается редактор Доступно с git 1.7.9.
5lava

51
@Brenden, чтобы изменить самый первый коммит в проекте, используйтеgit rebase -i --root
Noah Passalacqua

488

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

Поскольку я опасаюсь запуска скриптов, которые зависят от установки и сброса переменных среды для перезаписи истории 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

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

42
Это выглядит очень четкой альтернативой ужасающему git rebase -i. Никогда не слышал об этом git replaceраньше. +1
FractalSpace

3
Для очистки refs / original / ... backup смотрите здесь
alexis

5
Я рекомендую использовать --force-with-leaseвместо -f. Это безопаснее.
Джей Базузи

11
ВНИМАНИЕ: помните, что git filter-branch -- --allво всех ветвях, в которых находился исходный коммит , происходит изменение коммитов. Если у вас недостаточно учетных данных (или вы просто не хотите изменять историю веток других пользователей), хорошо быть осторожным с этим ответом.
Рибамар

225

Документация 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
    
  • Нажмите исправленную историю на GitHub:

    git push --force --tags origin 'refs/heads/*'
    

    ИЛИ, если вы хотите нажать выбранные ссылки на ветви, используйте

    git push --force --tags origin 'refs/heads/develop'
    

12
Это меняет все коммиты, а не только один. Забавно, я сделал это менее 30 минут назад.
Artjom B.

Когда я нашел этот ответ после прочтения предыдущих, я подумал, что стоит попробовать и вуаля, он сделал свою работу. Однако в моем случае это изменило имя коммиттера только при начальной фиксации. Кстати, раньше я пробовал идеи из первого ответа. Может быть, это как-то повлияло на систему.
Руслан Герасимов

2
Обратите внимание, что если вы не будете использовать clone/ push, вы получите резервное пространство имен refs/original/. Я не мог найти способ интеллектуального удаления этого пространства имен, поэтому я в итоге удалил каталог .git/refs/original, который сработал.
Василий Новиков

Почему это приводит к изменениям в репо, если, например, OLD_EMAIL ничего не соответствует? По некоторым причинам некоторые (но не все!) Коммиты меняются.
mjs

1
Мой вариант использования этого ответа: у меня есть две учетные записи github, одну из которых я непреднамеренно использовал для коммитов. Этот скрипт помог исправить все мои коммиты, переименовав неверный адрес электронной почты / имена коммиттеров. Конечно, если я совершаю коммит с неправильным пользователем, скажем, с 50-го коммита на 500-й, то будет 450 дивертированных коммитов. В любом случае, после запуска скрипта, как указал @andrej, вам нужно git push -fбудет принудительно принудительно изменить репо.
LWY

168
  • Сбросьте ваш адрес электронной почты в конфигурации:

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

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

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


2
Нет, это не так. Посмотрите на OP: It's not last commit.Так как они amendэто сделали ?
underscore_d

2
Это здорово, обидно, но только последний коммит. К счастью, он мне понадобился на последних двух, поэтому просто выполнил git reset HEAD~предложенные строки, а затем снова сделал следующий коммит вручную. Сработало нормально!
Мэтт Флетчер

2
Спасибо! --Reset-author помог мне, так как без него автор меняется, но «коммиттер» остается со старыми подробностями автора.
Лукас П.

9
Чтобы исправить мои последние шесть коммитов: Сначала установите правильного автора для текущего репозитория Git, используя git config --local user.name FirstName LastName и git config --local user.email first.last@example.com. Затем примените к последним шести коммитам, используя git rebase --onto HEAD~6 --exec "git commit --amend --reset-author --no-edit" HEAD~6. Наконец, нажмите его для удаленного использования Git-репо git push --force-with-lease.
olibre

@olibre это работает как шарм, спасибо.
Бруно Гаспаротто

88

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

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?сообщение.


Можете ли вы обновить свои фотографии?
Shimmy Weitzhandler

1
Если у вас есть несколько коммитов для изменения, вместо того, чтобы редактировать их по отдельности, вы также можете разрешить pickдействие и добавлять после каждой строкиexec git commit --no-edit --amend --author="MyNewAuthor <my@new-auth.or>"
Пьер-Оливье Варес

60

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

В качестве предлога, чтобы попробовать 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

+1 спасибо. assemblymb git repo, по-видимому, не меняет все ссылки на авторов в веб-представлении репозитория, но результаты «git pull / clone», похоже, работают нормально.
Джонни, штат Юта,

Отличное решение, так как оно изменяет только то, что предназначено, а не другие поля, например дату принятия.
Гийом Леметр

12
Документация Github содержит похожий скрипт
olivieradam666

2
@ olivieradam666, который работает как шарм, и его легче читать
fregante

@ olivieradam666 Спасибо. Вы должны действительно добавить это как ответ, чтобы это привлекло больше внимания.
seane

44

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

введите описание изображения здесь

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

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

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

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 <foo@bar.com>\"" 4025621

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

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

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

git reauthor 4025621 Eugen

1
Чтобы убедиться, что команда работала должным образом, я проверил вывод git shortlog -e -s.
Тейлор Эдмистон

5
Это ответ, который лучше всего послужил моим целям, спасибо. И так как я просто хотел изменить свой адрес электронной почты, я мог запустить с --exec = "git commit --amend --reset-author" после обновления моего .git / config.
Дато

1
Эээ, не уверен, почему я забыл! Готово сейчас.
Дато

Отличный ответ и очень легко исправить. Люблю псевдоним!
J_A_X

это не помогло мне. теперь у меня ошибка Continue Rebase Failed
Алексей Ш.

17

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

git push -f форсировать обновление центрального репозитория.

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


16

При этом в документе 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

Он предложит вам отредактировать сообщения:

# 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...

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


16

В поддержку ответа Евгения Конкова , чтобы начать с корневого коммита, используйте --rootфлаг. --no-editФлаг полезно тоже

git rebase --root --exec "git commit --amend --author='name <email>' --no-edit"

Это сработало и изменилось на всех коммитах.
SagarKapasi099

1
Спасибо за ответ. Нужно было добавить --interactive, чтобы все заработало. git rebase --root --interactive --exec "git commit --amend --author = 'name <email>' --no-edit"
Sreeragh AR

8

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

Простой и понятный способ:

git config user.name "New User"
git config user.email "newuser@gmail.com"

git log
git rebase -i 1f1357
# change the word 'pick' to 'edit', save and exit

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

git push --force-with-lease

подробные операции

  • покажите журналы фиксации и узнайте идентификатор фиксации, который перед вашей фиксацией вы хотите изменить:
git log
  • git rebase начинается с выбранного идентификатора коммита до последнего в обратном порядке:
git config user.name "New User"
git config user.email "newuser@gmail.com"
git rebase -i 1f1357

# change word pick to edit, save and exit
edit 809b8f7 change code order 
pick 9baaae5 add prometheus monitor kubernetes
edit 5d726c3 fix liquid escape issue   
edit 3a5f98f update tags
pick 816e21c add prometheus monitor kubernetes
  • rebase будет остановлен при следующем идентификаторе коммита, вывод:
Stopped at 809b8f7...  change code order 
You can amend the commit now, with
  git commit --amend 

Once you are satisfied with your changes, run

  git rebase --continue
  • подтвердить и продолжить перебазирование до успешного refs/heads/master.
# each continue will show you an amend message
# use git commit --amend --reset-author --no-edit to comfirm
# use git rebase --skip to skip
git commit --amend --reset-author --no-edit
git rebase --continue
git commit --amend --reset-author --no-edit
...
git rebase --continue
Successfully rebased and updated refs/heads/master.
  • git push для обновления
git push --force-with-lease

5

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

git checkout branch_name

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

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

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

Затем выполните команду git commit с возможностью изменения.

git commit --amend --author = "Имя пользователя электронной почты" --no-edit

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

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

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


Я думаю, что это самый простой способ сделать это. Я использовал команду reword, и это не удалось. Я узнал, что мне нужно использовать команду редактирования. Может быть, «изменить» ключевое слово можно выделить. Спасибо за ответ @ChannaB 👍
Berk

действительно легко следовать шагам. Спасибо!
Хабиба

4

Существует также ленивый подход к этой проблеме, особенно если у вас есть несколько коммитов, которые вы хотите изменить. В моем случае у меня была новая ветка с несколькими коммитами с неправильным автором, так что мне помогло:

Перейдите в исходную ветку:

git checkout develop

Создайте из него новую ветку:

git checkout -b myFeature develop 

Объединить его без информации о коммите как один коммит:

git merge --no-commit --squash branchWrongAuthor

Вы также можете внести изменения:

git stage .

Измените имя автора и передайте изменения:

git commit --amend --author "New Author Name <New Author Email>" -m "new feature added"

И это все, вы можете подтолкнуть изменения.

git push

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


4

Шаги, чтобы переименовать имя автора после нажатия коммита

  1. Сначала введите «git log», чтобы получить идентификатор коммита и более подробную информацию.
  2. git rebase i HEAD ~ 10 (10 - общий коммит, отображаемый при rebase)

    If you Get anything like below

    fatal: It seems that there is already a rebase-merge directory, and I wonder if you are in the middle of another rebase. If that is the case, please try

    git rebase (--continue | --abort | --skip) If that is not the case, please rm -fr ".git/rebase-merge" and run me again. I am stopping in case you still have something valuable there.

  3. Затем введите «git rebase --continue» или «git rebase --abort» в соответствии с вашими потребностями

    • Теперь окно откроется, нажмите клавишу «i» на клавиатуре.
    • тогда вы получите список коммитов до 10 [потому что мы прошли 10 коммитов выше], как показано ниже

    pick 897fe9e simplify code a little

    pick abb60f9 add new feature

    pick dc18f70 bugfix

  4. Теперь вам нужно добавить команду ниже под коммитом, который вы хотите редактировать, как показано ниже

    pick 897fe9e simplify code a little exec git commit --amend --author 'Author Name <author.name@mail.com>' pick abb60f9 add new feature exec git commit --amend --author 'Author Name <author.name@mail.com>' pick dc18f70 bugfix exec git commit --amend --author 'Author Name <author.name@mail.com>'

    1. Вот и все, теперь просто нажмите ESC: wq и все готово

    2. Затем git push origin HEAD: ИМЯ ФИЛИАЛА -f [пожалуйста, позаботьтесь о -f Force push]

    как git push -fилиgit push origin HEAD: dev -f


отличный ответ, не могли бы вы обновить пункт 6 на примере git pushкоманды?
Лукаш 'Severiaan' Grela

1
@ Lukasz'Severiaan'Grela отредактировано, пожалуйста, проверьте сейчас, Спасибо
Kirtikumar A.

3

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

$ git config --global user.name "John Doe"
$ git config --global user.email "john@doe.org"

Изменение имени и адреса коммиттера для каждого репозитория:

$ git config user.name "John Doe"
$ git config user.email "john@doe.org"

Изменение информации об авторе только для следующего коммита:

$ git commit --author="John Doe <john@doe.org>"

Подсказка : для другой ситуации и получения дополнительной информации прочитайте ссылку на пост .


2

Если вам нужно изменить коммит AUTHOR OF THE LAST и никто другой не использует ваш репозиторий, вы можете отменить свой последний коммит с помощью:

git push -f origin last_commit_hash:branch_name 

измените имя автора вашего коммита с помощью:

git commit --amend --author "type new author here"

Выйдите из редактора, который открывается, и снова нажмите ваш код:

git push

2

Для сообщения коммита слияния я обнаружил, что не могу изменить его, используя rebase, по крайней мере, gitlab. Он показывает слияние как коммит, но я не могу переназначить его на #sha. Я нашел этот пост полезным.

git checkout <sha of merge>
git commit --amend # edit message
git rebase HEAD previous_branch

Эти три строки кода сделали работу по изменению сообщения фиксации слияния (как автор).


1

Вы можете использовать эти команды с официальной страницы GitHub

https://help.github.com/en/github/using-git/changing-author-info

вот команды

#!/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

Здесь вы можете изменить старую электронную почту на новое имя пользователя и адрес электронной почты.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.