Git, перезаписуйте попередні імена користувачів фіксації та електронні листи


170

Я здійснив купу зобов’язань щодо проекту в Github, проте зрозумів, що не створив належного електронного листа та повного імені виконавця на комп’ютері, яким я зараз користуюся, щоб зробити свої зобов’язання, а тому аватар та електронна адреса користувачів не там.

Як я можу переписати всі попередні записи електронної пошти та імена користувачів?



Я відчув це після зміни електронної адреси в моєму акаунті GitHub. Окрім натискання змін коду з локального git repo за допомогою командного рядка git (а не робочого столу GitHub), я також редагував текст та керував файлами безпосередньо з віддаленого git repo за допомогою веб-інтерфейсу GitHub. Нова адреса електронної пошти поширюється лише на комісії, що є результатом останніх дій, а не першої.
— Роберт Джон

Відповіді:


243

Ви можете додати цей псевдонім:

git config 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 "

Щоб змінити ім'я автора:

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

Псевдонім:

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


13
Також, git change-commits GIT_COMMITTER_EMAIL "old@example.com" "new@example.com"щоб змінити електронну пошту виконавця.
— Ларан

19
виправлено "eval: [[: не знайдено" на ubuntu та додамо підтвердженняchange-commits = "!f() { VAR1=$1; VAR='$'$1; OLD=$2; NEW=$3; echo \"Are you sure for replace $VAR $OLD => $NEW ?(Y/N)\";read OK;if [ \"$OK\" = 'Y' ] ; then shift 3; git filter-branch --env-filter \"if [ \\\"${VAR}\\\" = '$OLD' ]; then export $VAR1='$NEW';echo 'to $NEW'; fi\" $@; fi;}; f "
— qxo

9
git: 'change-commits' не є командою git. Див. "Git --help". Значить, ви не додали псевдонім у свій git config. наприклад, git config -e
— Wayne

2
Це лише зробило дублікати всіх комісій електронною поштою, яку я хотів змінити. Не видається, щоб переписати історію. Рішення @Olivier Verdier працювало на мене.
— Джейк Вілсон

6
Це два рази поспіль із різними входами призводить до:Cannot create a new backup. A previous backup already exists in refs/original/
— theonlygusti

97

Рішення вже існує: Змініть ім'я автора та виконавця та електронну пошту декількох комітетів у Git

А саме,

git filter-branch -f --env-filter \
"GIT_AUTHOR_NAME='Newname'; GIT_AUTHOR_EMAIL='newemail'; \
GIT_COMMITTER_NAME='committed-name'; GIT_COMMITTER_EMAIL='committed-email';" HEAD

4
Чи не змінило б це ім’я автора для всіх комісій (усієї історії) філії?
— hasen

2
Так, це змінило б усі зобов'язання щодо нової інформації про автора.
— ewall

9
Будь ласка, позначте питання як дублікати, а не копіюючи відповідь.
— givanse

2
що робити, якщо я не вказав старе ім’я чи старий електронний лист? git говорить "порожній ідентифікатор <> заборонено"
— Гриффан

Я запустив цю команду, і тепер моє репо не буде натискати на сервер git і не витягувати його.
— Ісус Н

46

Якщо ви вже перенесли деякі ваші зобов’язання у загальнодоступний сховище, ви цього не хочете робити, інакше це зробить альтернативну версію історії майстра, якою могли скористатися інші. "Не перетинайте потоки ... Було б погано ..."

Однак, якщо це лише ті зобов’язання, які ви внесли до свого локального сховища, то це обов'язково виправте перед тим, як натиснути на сервер. Ви можете використовувати git filter-branchкоманду з --commit-filterопцією, тому вона редагує лише ті коміти, які відповідають вашій неправильній інформації, наприклад:

git filter-branch --commit-filter '
      if [ "$GIT_AUTHOR_EMAIL" = "wrong_email@wrong_host.local" ];
      then
              GIT_AUTHOR_NAME="Your Name Here (In Lights)";
              GIT_AUTHOR_EMAIL="correct_email@correct_host.com";
              git commit-tree "$@";
      else
              git commit-tree "$@";
      fi' HEAD

5
Це працює ідеально, тоді як відповідь, позначена зеленим кольором, не
— jmary

Згодом, можливо, захочете очистити резервну копію git update-ref -d refs/original/refs/heads/master, див. < Stackoverflow.com/a/7654880/333403 >.
— cknoll

FYI: Якщо у вас є кілька невірних імен / електронних листів, можливо, вам доведеться запустити це кілька разів. Якщо це трапиться, він буде стогнати над вами з цією помилкою: A previous backup already exists in refs/original/у такому випадку перезапустіть його новою електронною поштою та додайте -fдо --commit-filter. Використовуйте на власний розсуд. Зазвичай -fце небезпечно робити без знання того, що він робить.
— Чак

19

Після застосування відповіді Олів'є Верді:

git filter-branch -f --env-filter \
"GIT_AUTHOR_NAME='Newname'; GIT_AUTHOR_EMAIL='newemail'; \
GIT_COMMITTER_NAME='committed-name'; GIT_COMMITTER_EMAIL='committed-email';" HEAD

... щоб натиснути змінену історію на використання оригінального сховища:

git push origin +yourbranch

Наведена вище команда (зверніть увагу на плюс) змушує переписувати історію і на оригінальному репо. Використовуйте обережно!


Працював для мене, також правильно переписав історію походження.
— Xeverous

10
Це збирається переписати ВСІ документи, незалежно від того, хто це автор. Використовуйте обережно.
— Бхавін Доші

14

https://help.github.com/articles/changing-author-info/

#!/bin/sh

git filter-branch --env-filter '

OLD_EMAIL="oldEmail@xxx-MacBook-Pro.local"
CORRECT_NAME="yourName"
CORRECT_EMAIL="yourEmail"

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

це повністю працювало для мене. Після git push обов’язково перегляньте оновлення на веб-порталі git. Якщо комісія все ще не пов’язана з моїм обліковим записом, поруч із фіксом відображається мініатюрне зображення за замовчуванням, і воно не відображається на графіку моїх часових вкладів, перейдіть до URL-адреси фіксації та додайте .patch в кінці URL-адреси та підтвердіть ім'я та електронна адреса правильні.


Хоча це теоретично може відповісти на питання, бажано було б сюди включити істотні частини відповіді та надати посилання для довідки.
— jhpratt

1
Це єдине переписування всіх гілок.
— Бруно Зелл

6

Для тих, хто просто хоче просту версію вставити копію (окрім оновлення електронних листів та імен):

git config 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 "
git change-commits GIT_AUTHOR_NAME "<Old Name>" "<New Name>" -f
git change-commits GIT_AUTHOR_EMAIL <old@email.com> <new@email.com> -f
git change-commits GIT_COMMITTER_NAME "<Old Name>" "<New Name>" -f
git change-commits GIT_COMMITTER_EMAIL <old@email.com> <new@email.com> -f

5

Швидше за все, проблема з терміналом автоматично втече з речей
— Андрій Савін

3

З огляду на використання git-filter-branchє не потрібно , щоб зробити те ж саме в GIT-фільтр-репо (можливо , буде потрібно встановити його перший з pip install git-filter-repo):

git-filter-repo --name-callback 'return name.replace(b"OldName", b"NewName")' --email-callback 'return email.replace(b"old@email.com", b"new@email.com")'

Якщо сховище оригінальне, без віддаленого, вам доведеться додати --force щоб примусити переписати. (Ви можете створити резервну копію репо, перш ніж робити це.)

Якщо ви не хочете зберігати рефлекси (вони будуть відображатися в історії філій Git GUI), вам доведеться додати --replace-refs delete-no-add .

Для отримання додаткових функцій див. "Фільтрування імен та електронних листів" .

PS Викрадено та покращено з https://stackoverflow.com/a/59591928/714907 .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.