Вопрос: Изменить автора фиксации при одном конкретном коммите


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

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

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


1331


источник


Ответы:


Интерактивная перезагрузка точки ранее в истории, чем фиксация, которую необходимо изменить ( 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. Перестановка будет завершена.

2239



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

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

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

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

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

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

    а затем проверить исходную ветку.

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

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

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

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

    git push --force-with-lease
    

297



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

117



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

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


60



  • Reset your email to the config globally:

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

  • Now reset the author of your commit without edit required:

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


47



The answers in the question to which you linked are good answers and cover your situation (the other question is more general since it involves rewriting multiple commits).

As an excuse to try out git filter-branch, I wrote a script to rewrite the Author Name and/or Author Email for a given commit:

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

45



When doing git rebase -i there is this interesting bit in the doc:

If you want to fold two or more commits into one, replace the command "pick" for the second and subsequent commits with "squash" or "fixup". If the commits had different authors, the folded commit will be attributed to the author of the first commit. The suggested commit message for the folded commit is the concatenation of the commit messages of the first commit and of those with the "squash" command, but omits the commit messages of commits with the "fixup" command.

  • If you have an history of A-B-C-D-E-F,
  • and you want to change commits B and D (= 2 commits),

then you can do:

  • git config user.name "Correct new name"
  • git config user.email "correct@new.email"
  • create empty commits (one for each commit):
    • you need a message for rebase purpose
    • git commit --allow-empty -m "empty"
  • start the rebase operation
    • git rebase -i B^
    • B^ selects the parent of B.
  • you will want to put one empty commit before each commit to modify
  • you will want to change pick to squash for those.

Example of what git rebase -i B^ will give you:

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 that to:

# 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

It will prompt you to edit the messages:

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

and you can just remove the first few lines.


12



There is one additional step to Amber's answer if you're using a centralized repository:

git push -f to force the update of the central repository.

Be careful that there are not a lot of people working on the same branch because it can ruin consistency.


12