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

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

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

Комментарии к вопросу (9)

С Использованием Интерактивной Перебазирования

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

git rebase -i -p 

Затем Марк все свои плохие совершает как "редактировать" в перебазировать файл. Если вы также хотите изменить свой первый коммит, вы должны вручную добавить его в качестве первой линии в переместить файл (формат других линий). Потом, когда ГИТ просит вас внести изменения каждого коммита, сделать

 git commit --amend --author "New Author Name " 

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

git rebase --continue

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

Вы могли бы пропускать отверстия здесь редакторе, добавляя - нет-редактирование так что команда будет:

git commit --amend --author "New Author Name " --no-edit && \
git rebase --continue

Один Коммит

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

 git commit --amend --author "New Author Name "

Это позволит изменить автора на имя, указанное, но комиссия будет установлена на ваш настроенного пользователя в ГИТ конфигурации пользователя.имяиGit для пользователей конфигурации.электронной почты`. Если вы хотите установить коммиттер на что-то указать, это позволит установить автора и исполнителя:

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

Обратите внимание на слияния коммитов

Был небольшой изъян в мой оригинальный ответ. Если есть какие-то коммитов слияния между текущим голова и свой <некоторые головы, прежде чем все ваши плохие совершает>, затем Git для перебазирования будет расплющить (и кстати, если вы используете GitHub запросы тянуть, там будет куча коммитов слияния в вашей истории). Это может очень часто привести к очень разную историю (как повторяющиеся изменения могут быть "перебазированы из"), и в худшем случае, это может привести к Git для перебазирования прошу Вас разрешить сложные конфликты слияния (которые скорее всего уже решен в коммитов слияния). Решение: использовать флаг -п в Git для перебазирования, которая позволит сохранить структуру слияния вашей истории. На странице справочника Git для перебазирования предупреждает, что, используя -P и я может привести к проблемам, но в разделе баги он пишет "редактирования коммитов и переформулировать их сообщения должны нормально работать&.и"

Я'вэ добавил -п В приведенной выше команде. Для случая, когда вы're просто изменение самой последней фиксации, это не проблема.

Комментарии (25)
Решение

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

В частности, вы можете исправить все неправильные имена авторов и электронные адреса для всех веток и тегов с помощью этой команды (источник: GitHub help):

#!/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
Комментарии (18)

Вы также можете:

git filter-branch --commit-filter '
        if [ "$GIT_COMMITTER_NAME" = "" ];
        then
                GIT_COMMITTER_NAME="";
                GIT_AUTHOR_NAME="";
                GIT_COMMITTER_EMAIL="";
                GIT_AUTHOR_EMAIL="";
                git commit-tree "$@";
        else
                git commit-tree "$@";
        fi' HEAD

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

git filter-branch --commit-filter "
        if [ "$GIT_COMMITTER_NAME" = "" ];
        then
                GIT_COMMITTER_NAME="";
                GIT_AUTHOR_NAME="";
                GIT_COMMITTER_EMAIL="";
                GIT_AUTHOR_EMAIL="";
                git commit-tree "$@";
        else
                git commit-tree "$@";
        fi" HEAD
Комментарии (13)

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

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
Комментарии (9)

Это происходит, когда у вас нет $дома/.gitconfig хранит настройки инициализации. Вы можете исправить это:

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

протестировано с версий Git 1.7.5.4

Комментарии (3)

На один коммит:

git commit --amend --author="Author Name "

(извлечено из asmeurer'ы ответ)

Комментарии (5)

В том случае, когда только несколько топ совершает плохие авторы, Вы можете выполнить Git это все внутри перебазировать -я с помощью команды метод Exec и `--изменить-дерзайте, следующим образом:

git rebase -i HEAD~6 # as required

что представлена вам с редактируемый список коммитов:

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

Затем добавить метод exec ... --автор=" от..." в строках после всех строк с плохой авторов:

pick abcd Someone else's commit
pick defg my bad commit 1
exec git commit --amend --author="New Author Name " -C HEAD
pick 1234 my bad commit 2
exec git commit --amend --author="New Author Name " -C HEAD

сохраните и выйдите из редактора (для запуска).

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

Спасибо @asmeurer для вдохновения.

Комментарии (10)

GitHub есть простое решение, которое является следующий сценарий:

#!/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"
'
Комментарии (5)

Как docgnome отметил, переписывание истории-это опасно и будут ломать других людей'с репозиториев.

Но если вы действительно хотите сделать это, и вы находитесь в bash среды (никаких проблем в Linux, в Windows, вы можете использовать git Баш, который предоставляется при установке ЖКТ), использовать в Git фильтр-ветвь:

git filter-branch --env-filter '
  if [ $GIT_AUTHOR_EMAIL = bad@email ];
    then GIT_AUTHOR_EMAIL=correct@email;
  fi;
export GIT_AUTHOR_EMAIL'

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

git filter-branch --env-filter '
  if [ $GIT_AUTHOR_EMAIL = bad@email ];
    then GIT_AUTHOR_EMAIL=correct@email;
  fi;
export GIT_AUTHOR_EMAIL' HEAD~20..HEAD
Комментарии (3)

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

`коммитов --изменения --сброс автора

Комментарии (4)

Вы можете использовать это в качестве псевдоним так что вы можете сделать:

git change-commits GIT_AUTHOR_NAME "old name" "new name"

или за последние 10 коммитов:

git change-commits GIT_AUTHOR_EMAIL "old@email.com" "new@email.com" HEAD~10..HEAD

Добавить в ~/.gitconfig хранит настройки:

[alias]
    change-commits = "!f() { VAR=$1; OLD=$2; NEW=$3; shift 3; git filter-branch --env-filter \"if [[ \\\"$`echo $VAR`\\\" = '$OLD' ]]; then export $VAR='$NEW'; fi\" $@; }; f "

Источник: https://github.com/brauliobo/gitconfig/blob/master/configs/.gitconfig

Надеюсь, что это полезно.

Комментарии (4)

Это более разработанная версия @Брайан's версии:

Чтобы изменить автором и коммитером, вы можете сделать это (с разрывом строк в строки, которые можно в bash):

git filter-branch --env-filter '
    if [ "$GIT_COMMITTER_NAME" = "" ];
    then
        GIT_COMMITTER_NAME="";
        GIT_COMMITTER_EMAIL="";
        GIT_AUTHOR_NAME="";
        GIT_AUTHOR_EMAIL="";
    fi' -- --all

Вы можете сделать одну из этих ошибок:

  1. Временная директория уже существует
  2. Рефы начиная с рефов/уже оригинал существует (это значит еще один фильтр-ветвь была ранее выполнена на репозиторий и затем оригинальную ветку опирается на рефов/оригинальный)

Если вы хотите заставить работать несмотря на эти ошибки, добавить - сила флаг:

git filter-branch --force --env-filter '
    if [ "$GIT_COMMITTER_NAME" = "" ];
    then
        GIT_COMMITTER_NAME="";
        GIT_COMMITTER_EMAIL="";
        GIT_AUTHOR_NAME="";
        GIT_AUTHOR_EMAIL="";
    fi' -- --all

Небольшое пояснение `-- --все может быть нужно: это делает фильтр-филиала работать на всех редакций на все рефы (включая все филиалы). Это означает, например, что теги-это также переписан и видна на переписать филиалы.

В общем-то "ошибку" это использовать голова, что означает фильтрацию всех редакций на просто ветки. И тогда никакие теги (или другие ссылки) будет существовать в измененном филиала.

Комментарии (1)
  1. выполним git перебазирования -я <SHA1 или Реф отправная точка>
  2. Марк все коммиты, которые вы хотите изменить с "редактировать" (или "Е")
  3. петли, следующие две команды, пока не обработаны все совершает:

в Git коммит --изменения --повторное использование-сообщение=глава --автор="по-новому автор <new@author.email>"в ; `Git для перебазирования --продолжить

Это будет держать все другие фиксации информации (включая даты). В `--повторное использование-сообщения параметр=голова мешает редактора сообщений от запуска.

Комментарии (0)

Я использую следующие действия, чтобы переписать автора для всего репозитория, включая теги и все филиалы:

git filter-branch --tag-name-filter cat --env-filter "
  export GIT_AUTHOR_NAME='New name';
  export GIT_AUTHOR_EMAIL='New email'
" -- --all

Затем, как описано в man-страницы фильтра-филиала, Все ссылки подкрепленные фильтр-филиал (это губительный, сначала сделайте резервную копию):

git for-each-ref --format="%(refname)" refs/original/ | \
xargs -n 1 git update-ref -d
Комментарии (1)

Я адаптировал это решение, которая работает путем проглатывания простой автор-сопу-файл (формат тот же, что и для с Git-cvsimport). Она работает путем изменения всех пользователей, как определено в `автор-сопу-файл по всем отраслям.

Мы использовали это в сочетании с cvs2git чтобы перенести наш репозиторий с CVS на Git.

т. е. образец автор-сопу-файл

john=John Doe 
jill=Jill Doe 

Сценарий:

 #!/bin/bash

 export $authors_file=author-conv-file

 git filter-branch -f --env-filter '

 get_name () {
     grep "^$1=" "$authors_file" |
     sed "s/^.*=\(.*\) $/\1/"
 }

 get_email () {
     grep "^$1=" "$authors_file" |
     sed "s/^.*=.* $/\1/"
 }

 GIT_AUTHOR_NAME=$(get_name $GIT_COMMITTER_NAME) &&
     GIT_AUTHOR_EMAIL=$(get_email $GIT_COMMITTER_NAME) &&
     GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME &&
     GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL &&
     export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL &&
     export GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL
 ' -- --all
Комментарии (3)

А одна команда изменить автора за последние N коммитов:

git rebase -i HEAD~4 -x "git commit --amend --author 'Author Name ' --no-edit"

Примечания

  • флаг --no-изменить флаг гарантирует в Git коммит --изменить не'т задать дополнительные подтверждения
  • когда вы использовать `Git для перебазирования -я, вы можете вручную выбрать коммиты где поменять автора,

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

pick 897fe9e simplify code a little
exec git commit --amend --author 'Author Name ' --no-edit
pick abb60f9 add new feature
exec git commit --amend --author 'Author Name ' --no-edit
pick dc18f70 bugfix
exec git commit --amend --author 'Author Name ' --no-edit

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

Комментарии (1)

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

Ниже версия работает на все ветви и изменения, автор и comitter отдельно, чтобы предотвратить это.

Престижность leif81 для всех вариант.

#!/bin/bash

git filter-branch --env-filter '
if [ "$GIT_AUTHOR_NAME" = "" ];
then
    GIT_AUTHOR_NAME="";
    GIT_AUTHOR_EMAIL="";
fi
if [ "$GIT_COMMITTER_NAME" = "" ];
then
    GIT_COMMITTER_NAME="";
    GIT_COMMITTER_EMAIL="";
fi
' -- --all
Комментарии (0)
  1. Автор имя &amp изменения обязательства; по электронной почте по изменить, то замена старого фиксации с новыми-один`:

ГИТ кассе $ <фиксации хэш - > # извлечение для фиксации нужно изменить $ коммитов --изменения --автор "имя author@email.com" и # изменить имя автора и адрес электронной почты

$ git будет заменить на <старая фиксации-хэш> <новое фиксации-хэш> # заменить старый коммит новый фильтр-филиала $ ЖКТ -- --все # переписать все фьючерсы совершает на основе замены

$ Git на замену -д <старая фиксации-хэш> # снимите замена для чистоты $ Git с пуш-Ф происхождения глава # толчок силы

  1. Другой способ перебазировка:

$ Git для перебазирования -я <хорошей фиксации-хэш> # вернуться к последней удачной фиксации

Редактор откроет, заменить 'выбор' с 'редактировать' перед фиксацией хотите изменить автора

$ коммитов --изменить --автор="у автора имя author@email.com" и # изменить имя автора & электронная почта

Сохранить изменения и выйти из редактора

$ Git для перебазирования --продолжение # закончить перебазироваться

Комментарии (1)

Я должен отметить, что если проблема только в том, что автор/электронной почты отличается от обычного, это не проблема. Правильным решением является создание файл с названием `.mailmap на базе каталога с линиями как


Name you want  Name you don't want 
Комментарии (0)

Если вы являетесь единственным пользователем этого репозитория, вы можете переписать историю используя [в Git фильтр-ветвь][в Git фильтр-ветвь] (как svick писал), или ГИТ фаст-экспорт/ГИТ фаст-импорт плюс фильтр скрипт (как описано в статье, на которую ссылается в docgnome ответить), или интерактивные смещение. Но ни один из этих бы изменить ревизии из первых изменил совершить года; это означает, проблема для кого что на основе его/ее изменения на вашей ветке предварительно переписать.

Восстановление

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

В качестве альтернативы они могут попробовать ГИТ тянуть --перебазировать, которые бы вперед, если бы&#39;т-либо изменения в свой репозиторий, или перебазировать свои ветви поверх переписать совершает (мы хотим избежать слияния, так как он будет держать предварительно переписать comits навсегда). Все это при условии, что они не имеют не поручено работать; используйте заначка ГИТ, чтобы спрятать изменения в противном случае.

Если другие разработчики используют функцию филиалы, и/или ГИТ тянуть --перебазировать не'т работу, например, потому что против течения не установлено, что они [перебазировка][в git-rebase и] свою работу на пост-переписать совершает. Например, сразу после извлечения новых изменений (Git для выборки), на мастер-ветке основе / раздвоенной от происхождения/мастер, один должен работать

$ git rebase --onto origin/master origin/master@{1} master

Здесь происхождения/мастер@{1} предварительно переписать государства (до выборки), см. gitrevisions.


Альтернативным решением могло бы быть использование рефов/заменить/ механизм доступен в Git начиная с версии 1.6.5. В этом решении вам выдадут дубликат для коммиты, которые имеют неправильный электронный адрес; затем, кто выбирает 'заменить' ссылки (что-то вроде выборка = +рефы/заменить/*:рефы/заменить/* refspec в соответствующем месте в их .в git/config файл) будет сделать замены прозрачно, и те, кто не извлечет эти рефов увидеть старых коммитов.

Процедура проходит примерно так:

  1. Найти все коммиты с неправильным электронной почты, например, с помощью

$ ГИТ лог --author=user@wrong.email -все

  1. За каждый неправильный совершить, создать замена совершал, и добавить его к объекту базы данных

$ ЖКТ кота-файл -Р <идентификатор неверной фиксации> | СЭД -э 's/user@wrong.email/user@example.com/g' > tmp.txt $ Git с хэш-объект -Т совершить -з tmp.txt <код исправлены фиксации>

  1. Теперь, когда вы исправили фиксации в базе объектов, вы должны сказать Git, чтобы автоматически заменить неправильный коммит исправлены один с помощью заменить на Git команда:

ЖКТ $ заменить на <идентификатор неверной фиксации> <идентификатор исправлены фиксации>

  1. Наконец, перечислю все замены, чтобы проверить, если эта процедура успешно

$ Git на замену -л

и проверить, если замены происходят

$ ГИТ лог --author=user@wrong.email -все

Можно конечно автоматизировать эту процедуру... ну, все, кроме, используя ГИТ заменить, который не'т иметь (еще) пакетном режиме, так что вам придется использовать Shell петля Для то или замены "под рукой".

НЕ ПРОВЕРЯЛ! YMMV.

<суп>обратите внимание, что вы можете столкнуться с некоторыми грубых углов при использовании ссылок/заменить механизм/`: он новый, и еще не очень хорошо проверены на</SUP-серфинг>.

Комментарии (0)