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

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

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

Ответ 1

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

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

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

Ответ 2

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

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

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

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

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

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

git rebase --continue

чтобы продолжить rebase.

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

git commit --amend --author "New Author Name <[email protected]>" --no-edit && \
git rebase --continue

Одиночная фиксация

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

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

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

 git -c user.name="New Author Name" -c [email protected] commit --amend --reset-author

Примечание по обязательствам слияния

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

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

Ответ 3

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

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 "[email protected]";
        else
                git commit-tree "[email protected]";
        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 "[email protected]";
        else
                git commit-tree "[email protected]";
        fi" HEAD

Ответ 4

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

git filter-branch -f --env-filter "GIT_AUTHOR_NAME='Newname'; GIT_AUTHOR_EMAIL='[email protected]'; GIT_COMMITTER_NAME='Newname'; GIT_COMMITTER_EMAIL='[email protected]';" HEAD

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

git filter-branch -f --env-filter "
    GIT_AUTHOR_NAME='Newname'
    GIT_AUTHOR_EMAIL='[email protected]'
    GIT_COMMITTER_NAME='Newname'
    GIT_COMMITTER_EMAIL='[email protected]'
  " HEAD

Ответ 5

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

git config --global user.name "you name"
git config --global user.email [email protected]
git commit --amend --reset-author

с версией git версии 1.7.5.4

Ответ 6

Для одного фиксации:

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

(извлечено из ответа от ответчика)

Ответ 7

В случае, если только самые мелкие коммиты имеют плохих авторов, вы можете сделать это все внутри git rebase -i с помощью команды exec и фиксации --amend следующим образом:

git rebase -i HEAD~6 # as required

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

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

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

pick abcd Someone else commit
pick defg my bad commit 1
exec git commit --amend --author="New Author Name <[email protected]>" -C HEAD
pick 1234 my bad commit 2
exec git commit --amend --author="New Author Name <[email protected]>" -C HEAD

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

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

Благодаря @asmeurer для вдохновения.

Ответ 8

Github имеет приятное решение, которое представляет собой следующую оболочку 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" = "[email protected]" ]
then
    cn="Your New Committer Name"
    cm="Your New Committer Email"
fi
if [ "$GIT_AUTHOR_EMAIL" = "[email protected]" ]
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"
'

Ответ 9

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

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

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

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

git filter-branch --env-filter '
  if [ $GIT_AUTHOR_EMAIL = [email protected] ];
    then [email protected];
  fi;
export GIT_AUTHOR_EMAIL' HEAD~20..HEAD

Ответ 10

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

git commit --amend --reset-author

Ответ 11

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

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

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

git change-commits GIT_AUTHOR_EMAIL "[email protected]" "[email protected]" 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\" [email protected]; }; f "

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

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

Ответ 12

Это более продуманная версия версии @Brian:

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

git filter-branch --env-filter '
    if [ "$GIT_COMMITTER_NAME" = "<Old name>" ];
    then
        GIT_COMMITTER_NAME="<New name>";
        GIT_COMMITTER_EMAIL="<New email>";
        GIT_AUTHOR_NAME="<New name>";
        GIT_AUTHOR_EMAIL="<New email>";
    fi' -- --all

Вы можете получить одну из следующих ошибок:

  • Временная директория уже существует
  • Refs начиная с refs/original существует уже
    (это означает, что еще одна ветвь фильтра была запущена ранее в репозитории, а исходная ссылка на исходную запись резервируется в refs/original)

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

git filter-branch --force --env-filter '
    if [ "$GIT_COMMITTER_NAME" = "<Old name>" ];
    then
        GIT_COMMITTER_NAME="<New name>";
        GIT_COMMITTER_EMAIL="<New email>";
        GIT_AUTHOR_NAME="<New name>";
        GIT_AUTHOR_EMAIL="<New email>";
    fi' -- --all

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

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

Ответ 13

  • run git rebase -i <sha1 or ref of starting point>
  • отметьте все коммиты, которые вы хотите изменить, с помощью edit (или e)
  • выполните следующие две команды, пока вы не обработаете все коммиты:

    git commit --amend --reuse-message=HEAD --author="New Author <[email protected]hor.email>" ; git rebase --continue

Это сохранит всю другую информацию о фиксации (включая даты). Параметр --reuse-message=HEAD запрещает запуск редактора сообщений.

Ответ 14

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

Мы использовали это совместно с cvs2git, чтобы перенести наш репозиторий с cvs на git.

то есть. Пример author-conv-file

john=John Doe <[email protected]>
jill=Jill Doe <[email protected]>

script:

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

Ответ 15

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

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

Затем, как описано в странице MAN ветки фильтра, удалите все оригинальные refs, сделанные под резервными копиями filter-branch (это разрушительно, сначала резервное копирование):

git for-each-ref --format="%(refname)" refs/original/ | \
xargs -n 1 git update-ref -d

Ответ 16

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

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

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

#!/bin/bash

git filter-branch --env-filter '
if [ "$GIT_AUTHOR_NAME" = "<old author>" ];
then
    GIT_AUTHOR_NAME="<new author>";
    GIT_AUTHOR_EMAIL="<[email protected]>";
fi
if [ "$GIT_COMMITTER_NAME" = "<old committer>" ];
then
    GIT_COMMITTER_NAME="<new commiter>";
    GIT_COMMITTER_EMAIL="<[email protected]>";
fi
' -- --all

Ответ 17

  • Измените фиксацию author name & email на Amend, затем замените old-commit with new-one:

    $ git checkout <commit-hash>                            # checkout to the commit need to modify  
    $ git commit --amend --author "name <[email protected]>" # change the author name and email
    
    $ git replace <old-commit-hash> <new-commit-hash>      # replace the old commit by new one
    $ git filter-branch -- --all                           # rewrite all futures commits based on the replacement                   
    
    $ git replace -d <old-commit-hash>     # remove the replacement for cleanliness 
    $ git push -f origin HEAD              # force push 
    
  • Другой способ Rebasing:

    $ git rebase -i <good-commit-hash>      # back to last good commit
    
    # Editor would open, replace 'pick' with 'edit' before the commit want to change author
    
    $ git commit --amend --author="author name <[email protected]>"  # change the author name & email
    
    # Save changes and exit the editor
    
    $ git rebase --continue                # finish the rebase
    

Ответ 18

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

git rebase -i HEAD~4 -x "git commit --amend --author 'Author Name <[email protected]>' --no-edit"

ПРИМЕЧАНИЯ

  • флаг --no-edit гарантирует, что git commit --amend не запрашивает дополнительное подтверждение
  • когда вы используете git rebase -i, вы можете вручную выбрать коммиты, где сменить автора,

файл, который вы редактируете, будет выглядеть так:

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

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

Ответ 19

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

Name you want <email you want> Name you don't want <email you don't want>

И с этого момента команды типа git shortlog будут считать эти два имени одинаковыми (если вы специально не скажете им). Подробнее см. http://schacon.github.com/git/git-shortlog.html.

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

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

Ответ 20

Если вы являетесь единственным пользователем этого репозитория, вы можете переписать историю, используя git filter-branch ( как svick написал), или git fast-export/git fast-import плюс фильтр script (как описано в статье, на которую ссылается docgnome answer), или интерактивный rebase. Но любой из них изменил бы изменения с первого измененного обязательства; это означает трудность для любого, кто основывал свои изменения на своей ветке, предварительно переписывая.

ВОССТАНОВЛЕНИЕ

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

В качестве альтернативы они могут попробовать git rebase --pull, которые бы быстро перешлите, если в их репозитории не было никаких изменений, или пересоедините их ветку поверх переписанных коммитов (мы хотим избежать слияния, поскольку она будет сохранять pre -ревит приходит навсегда). Все это предполагает, что у них нет работы; используйте git stash, чтобы отменить изменения в противном случае.

Если другие разработчики используют ветки функций, и/или git pull --rebase не работает, например. потому что восходящий поток не настроен, они должны rebase их работа поверх записей после перезаписи. Например, после получения новых изменений (git fetch), для ветки master на основе /forked из origin/master необходимо запустить

$ git rebase --onto origin/master origin/[email protected]{1} master

Здесь origin/[email protected]{1} - состояние предварительной перезаписи (до извлечения), см. gitrevisions.


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

Процедура выглядит примерно так:

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

    $ git log [email protected] --all
    
  • Для каждого неправильного коммита создайте замену фиксации и добавьте его в базу данных объектов

    $ git cat-file -p <ID of wrong commit> | 
      sed -e 's/[email protected]\.email/[email protected]/g' > tmp.txt
    $ git hash-object -t commit -w tmp.txt
    <ID of corrected commit>
    
  • Теперь, когда вы скорректировали фиксацию в базе данных объектов, вы должны сообщить Git автоматически и прозрачно заменить неверный коммит, исправленный с помощью git replace:

    $ git replace <ID of wrong commit> <ID of corrected commit>
    
  • Наконец, перечислите всю замену, чтобы проверить, выполнена ли эта процедура

    $ git replace -l
    

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

    $ git log [email protected] --all
    

Вы можете, конечно, автоматизировать эту процедуру... ну, все, кроме использования git replace, который не имеет (пока) пакетного режима, поэтому вам придется использовать для этого цикл оболочки или заменить "вручную".

НЕ ИСПРАВЛЕНО! YMMV.

Обратите внимание, что при использовании механизма refs/replace/ вы можете столкнуться с некоторыми грубыми углами: он является новым и еще не очень хорошо протестированным.

Ответ 21

Самый быстрый и простой способ сделать это - использовать аргумент --exec git rebase:

git rebase -i -p --exec 'git commit --amend --reset-author --no-edit'

Это создаст список дел, который выглядит так:

pick ef11092 Blah blah blah
exec git commit --amend --reset-author --no-edit
pick 52d6391 Blah bloh bloo
exec git commit --amend --reset-author --no-edit
pick 30ebbfe Blah bluh bleh
exec git commit --amend --reset-author --no-edit
...

и это будет работать автоматически, что работает, когда у вас есть сотни коммитов.

Ответ 22

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

Последовательность будет что-то вроде этого (для 2 неправильных коммитов, без ожидающих изменений):

git config user.name <good name>
git config user.email <good email>
git reset HEAD^
git stash
git reset HEAD^
git commit -a
git stash pop
git commit -a

Ответ 23

Если вы используете Eclipse с EGit, то есть довольно простое решение.
Предположение: вы совершили ошибку в локальном ветки local_master_user_x, который не может быть перенесен на "ведущий" удаленной ветки из-за недопустимого пользователя.

  • Оформить проверку удаленной ветки "master"
  • Выберите проекты/папки/файлы, для которых "local_master_user_x" содержит изменения.
  • Щелкните правой кнопкой мыши - Заменить на - Ветвь - 'local_master_user_x'
  • Завершите эти изменения снова, на этот раз как правильный пользователь и в локальную ветвь "master"
  • Push to remote 'master'

Ответ 24

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

pick a07cb86 Project tile template with full details and styling
x git commit --amend --reset-author -Chead

Ответ 25

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

Информация об коммитерах не отображается в большинстве мест, но вы можете увидеть ее с помощью git log -1 --format=%cn,%ce (или использовать show вместо log, чтобы указать конкретную фиксацию).

При изменении автора вашего последнего коммита так же просто, как git commit --amend --author "Author Name <[email protected]>", нет однострочного или аргумента, чтобы сделать то же самое с информацией об участниках.

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

git config user.email [email protected] 
git commit --amend

Ответ 26

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

Шаг 1: измените свое имя пользователя в git для всех будущих коммитов в соответствии с инструкциями здесь: https://help.github.com/articles/setting-your-username-in-git/

Шаг 2. Запустите следующие bash script:

#!/bin/sh

REPO_URL=ssh://path/to/your.git
REPO_DIR=rewrite.tmp

# Clone the repository
git clone ${REPO_URL} ${REPO_DIR}

# Change to the cloned repository
cd ${REPO_DIR}

# Checkout all the remote branches as local tracking branches
git branch --list -r origin/* | cut -c10- | xargs -n1 git checkout

# Rewrite the history, use a system that will preseve the eol (or lack of in commit messages) - preferably Linux not OSX
git filter-branch --env-filter '
OLD_EMAIL="[email protected]"
CORRECT_NAME="New Me"

if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_COMMITTER_NAME="$CORRECT_NAME"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_AUTHOR_NAME="$CORRECT_NAME"
fi
' --tag-name-filter cat -- --branches --tags

# Force push the rewritten branches + tags to the remote
git push -f

# Remove all knowledge that we did something
rm -rf ${REPO_DIR}

# Tell your colleagues to `git pull --rebase` on all their local remote tracking branches

Краткий обзор. Оформить заказ в временном файле, проверить все удаленные ветки, запустить script, который будет переписывать историю, сделать силовое нажатие нового состояния и рассказать всем своим коллегам о том, чтобы получить изменения.

У нас возникли проблемы с запуском этого в OS X, поскольку он каким-то образом перепутал концы строк в сообщениях фиксации, поэтому нам пришлось повторно запустить его на машине Linux после этого.

Ответ 27

Ваша проблема очень распространена. См. " Использование Mailmap для исправления списка авторов в Git"

Для простоты я создал script, чтобы облегчить процесс: git-changemail

После размещения этого script на вашем пути вы можете выпустить команды вроде:

  • Изменение совпадений авторов в текущей ветке

    $ git changemail -a [email protected] -n newname -m [email protected]
    
  • Измените сопоставления автора и коммиттера на <branch> и < branch2 > . Передайте -f в ветвь фильтра, чтобы разрешить переписывание резервных копий

    $ git changemail -b [email protected] -n newname -m [email protected] -- -f &lt;branch> &lt;branch2>
    
  • Показывать существующих пользователей в режиме репо

    $ git changemail --show-both
    

Кстати, после внесения изменений очистите резервную копию из ветки фильтра с помощью git-backup-clean

Ответ 28

Если вы являетесь единственным пользователем этого репо, или вы не заботитесь о возможном нарушении репо для других пользователей, тогда да. Если вы подтолкнули эти коммиты, и они существуют там, где где-то еще можно получить к ним доступ, тогда нет, если только вы не заботитесь о том, чтобы нарушать репозиции других людей. Проблема заключается в изменении этих коммитов, вы будете генерировать новые SHA, которые заставят их рассматривать как разные коммиты. Когда кто-то пытается втянуть эти измененные коммиты, история отличается и kaboom.

Эта страница http://inputvalidation.blogspot.com/2008/08/how-to-change-git-commit-author.html описывает, как это сделать. (Я не пробовал это так YMMV)

Ответ 29

Я хочу добавить свой пример. Я хочу создать bash_function с заданным параметром.

это работает в mint-linux-17.3

# $1 => email to change, $2 => new_name, $3 => new E-Mail

function git_change_user_config_for_commit {

 # defaults
 WRONG_EMAIL=${1:-"[email protected]"}
 NEW_NAME=${2:-"your name"}
 NEW_EMAIL=${3:-"[email protected]"}

 git filter-branch -f --env-filter "
  if [ \$GIT_COMMITTER_EMAIL = '$WRONG_EMAIL' ]; then
    export GIT_COMMITTER_NAME='$NEW_NAME'
    export GIT_COMMITTER_EMAIL='$NEW_EMAIL'
  fi
  if [ \$GIT_AUTHOR_EMAIL = '$WRONG_EMAIL' ]; then
    export GIT_AUTHOR_NAME='$NEW_NAME'
    export GIT_AUTHOR_EMAIL='$NEW_EMAIL'
  fi
 " --tag-name-filter cat -- --branches --tags;
}

Ответ 30

Попробуйте это. Он будет делать то же, что и выше, но интерактивно.

bash <(curl -s  https://raw.githubusercontent.com/majdarbash/git-author-change-script/master/run.sh)

Ссылка: https://github.com/majdarbash/git-author-change-script