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.