Вопрос: Как изменить имя автора и коммиттера и e-mail нескольких коммитов в Git?


Я писал простой скрипт в школьном компьютере и вносил изменения в Git (в репо, которое было в моем pendrive, клонированном с моего компьютера дома). После нескольких коммитов я понял, что делаю материал как пользователь root.

Есть ли способ изменить автора этих коммитов на мое имя?


1980


источник


Ответы:


Изменение автора (или коммиттера) потребует повторной записи всей истории. Если вы в порядке с этим и думаете, что это того стоит, то вы должны проверить git filter-branch , Страница руководства содержит несколько примеров, чтобы начать работу. Также обратите внимание, что вы можете использовать переменные среды для изменения имени автора, коммиттера, дат и т. Д. - см. Раздел «Переменные среды» раздела git man page ,

В частности, вы можете исправить все неправильные имена авторов и электронные письма для всех ветвей и тегов с этой командой (источник: Помощь 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

775



Использование интерактивной ребазы

Вы могли бы сделать

git rebase -i -p <some HEAD before all of your bad commits>

Затем отметьте все ваши плохие коммиты как «edit» в файле rebase. Если вы также хотите изменить свой первый коммит, вам нужно вручную добавить его в первую строку в файле rebase (следуйте формату других строк). Затем, когда git просит вас внести изменения в каждую фиксацию, сделайте

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

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

git rebase --continue

для продолжения rebase.

Вы можете пропустить открытие редактора здесь, добавив --no-editтак что команда будет:

git commit --amend --author "New Author Name <email@address.com>" --no-edit && \
git rebase --continue

Одиночный коммит

Как заметили некоторые из комментаторов, если вы просто хотите изменить самую последнюю фиксацию, команда rebase не нужна. Просто делать

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

Это изменит автора на указанное имя, но коммиттер будет настроен на вашего настроенного пользователя в git config user.nameа также git config user.email, Если вы хотите установить коммиттер на то, что вы укажете, это установит как автора, так и коммиттера:

 git -c user.name="New Author Name" -c user.email=email@address.com commit --amend --reset-author

Примечание о слиянии

В моем первоначальном ответе был небольшой недостаток. Если между текущими HEADи ваш <some HEAD before all your bad commits>, тогда git rebaseбудут сглаживать их (и, кстати, если вы будете использовать запросы GitHub pull, в вашей истории будет тонна слияния). Это может очень часто приводить к очень разной истории (поскольку повторяющиеся изменения могут быть «переустановлены»), а в худшем случае это может привести к git rebaseпопросив вас разрешить сложные конфликты слияния (которые, скорее всего, были решены в сделках слияния). Решение состоит в том, чтобы использовать -pпометить git rebase, который сохранит структуру слияния вашей истории. Манипуляция для git rebaseпредупреждает, что использование -pа также -iможет привести к проблемам, но в BUGSв разделе говорится: «Редактирование коммиттов и их переписывание сообщений фиксации должно работать нормально».

я добавил -pк указанной команде. Для случая, когда вы просто меняете последнее сообщение, это не проблема.


1405



Вы также можете сделать:

git filter-branch --commit-filter '
        if [ "$GIT_COMMITTER_NAME" = "<Old Name>" ];
        then
                GIT_COMMITTER_NAME="<New Name>";
                GIT_AUTHOR_NAME="<New Name>";
                GIT_COMMITTER_EMAIL="<New Email>";
                GIT_AUTHOR_EMAIL="<New Email>";
                git commit-tree "$@";
        else
                git commit-tree "$@";
        fi' HEAD

Обратите внимание: если вы используете эту команду в командной строке Windows, вам необходимо использовать "вместо ':

git filter-branch --commit-filter "
        if [ "$GIT_COMMITTER_NAME" = "<Old Name>" ];
        then
                GIT_COMMITTER_NAME="<New Name>";
                GIT_AUTHOR_NAME="<New Name>";
                GIT_COMMITTER_EMAIL="<New Email>";
                GIT_AUTHOR_EMAIL="<New Email>";
                git commit-tree "$@";
        else
                git commit-tree "$@";
        fi" HEAD

562



Один лайнер, но будьте осторожны, если у вас многопользовательский репозиторий - это изменится все обязуется иметь того же (нового) автора и коммиттера.

git filter-branch -f --env-filter "GIT_AUTHOR_NAME='Newname'; GIT_AUTHOR_EMAIL='new@email'; GIT_COMMITTER_NAME='Newname'; GIT_COMMITTER_EMAIL='new@email';" HEAD

С появлением строк в строке (что возможно в bash):

git filter-branch -f --env-filter "
    GIT_AUTHOR_NAME='Newname'
    GIT_AUTHOR_EMAIL='new@email'
    GIT_COMMITTER_NAME='Newname'
    GIT_COMMITTER_EMAIL='new@email'
  " HEAD

474



It happens when you do not have a $HOME/.gitconfig initialized. You may fix this as:

git config --global user.name "you name"
git config --global user.email you@domain.com
git commit --amend --reset-author

tested with git version 1.7.5.4


199



For a single commit:

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

(extracted from asmeurer's answer)


177



In the case where just the top few commits have bad authors, you can do this all inside git rebase -i using the exec command and the --amend commit, as follows:

git rebase -i HEAD~6 # as required

which presents you with the editable list of commits:

pick abcd Someone else's commit
pick defg my bad commit 1
pick 1234 my bad commit 2

Then add exec ... --author="..." lines after all lines with bad authors:

pick abcd Someone else's commit
pick defg my bad commit 1
exec git commit --amend --author="New Author Name <email@address.com>" -C HEAD
pick 1234 my bad commit 2
exec git commit --amend --author="New Author Name <email@address.com>" -C HEAD

save and exit editor (to run).

This solution may be longer to type than some others, but it's highly controllable - I know exactly what commits it hits.

Thanks to @asmeurer for the inspiration.


146



Github has a nice solution, which is the following shell script:

#!/bin/sh

git filter-branch --env-filter '

an="$GIT_AUTHOR_NAME"
am="$GIT_AUTHOR_EMAIL"
cn="$GIT_COMMITTER_NAME"
cm="$GIT_COMMITTER_EMAIL"

if [ "$GIT_COMMITTER_EMAIL" = "your@email.to.match" ]
then
    cn="Your New Committer Name"
    cm="Your New Committer Email"
fi
if [ "$GIT_AUTHOR_EMAIL" = "your@email.to.match" ]
then
    an="Your New Author Name"
    am="Your New Author Email"
fi

export GIT_AUTHOR_NAME="$an"
export GIT_AUTHOR_EMAIL="$am"
export GIT_COMMITTER_NAME="$cn"
export GIT_COMMITTER_EMAIL="$cm"
'

106