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

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

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

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

Ответ 1

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

git commit --amend --author="Author Name <[email protected]>"

Например, если ваша история коммитов ABCDE-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 protected]>"
  5. Затем git rebase --continue
  6. Это снова остановится на D
  7. Затем вы должны снова git commit --amend --author="Author Name <[email protected]>"
  8. git rebase --continue
  9. Перебазирование будет завершено.
  10. Используйте git push -f чтобы обновить ваш источник обновленными коммитами.

Ответ 2

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

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

Ответ 3

Документация 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

Ответ 4

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

    git config --global user.email [email protected]

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

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

Ответ 5

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

git commit --amend --author="Author Name <[email protected]>"

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

Запустите перезагрузку с помощью 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?.

Ответ 6

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

В качестве предлога для опроса 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' "[email protected]"
    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

Ответ 7

Передать до:

enter image description here

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

git commit --amend --author="Author Name <[email protected]>"

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

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 <[email protected]>\"" 4025621

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

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

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

git reauthor 4025621 Eugen

Ответ 8

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

git push -f, чтобы принудительно обновить центральный репозиторий.

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

Ответ 9

При выполнении git rebase -i есть этот интересный бит в документе:

Если вы хотите сбросить две или более коммитов в одну, замените команду "pick" на вторую и последующую фиксацию с помощью "squash" или "fixup". Если у коммитов были разные авторы, сложенный фиксаж будет приписан автору первого коммита. Предлагаемое сообщение фиксации для сложенного фиксации представляет собой конкатенацию сообщений фиксации первого фиксации и команд с командой "squash", но опускает сообщения фиксации коммитов с помощью команды "fixup".

  • Если у вас есть история A-B-C-D-E-F,
  • и вы хотите изменить commits 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.
  • вам нужно поместить один пустой commit до для каждой фиксации для изменения
  • вам нужно изменить 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...

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

Ответ 10

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

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

Ответ 11

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

git push -f origin last_commit_hash:branch_name 

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

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

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

git push

Ответ 12

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

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

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

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

Ответ 13

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

git checkout branch_name

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

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

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

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

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

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

git rebase --continue

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

Ответ 14

Действия по переименованию имени автора после нажатия коммита

  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 <[email protected]>' pick abb60f9 add new feature exec git commit --amend --author 'Author Name <[email protected]>' pick dc18f70 bugfix exec git commit --amend --author 'Author Name <[email protected]>'

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

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

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

Ответ 15

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

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

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