Як змінити кілька комісій у Git, щоб змінити автора


180

Я зробив серію комітетів у Git і тепер розумію, що забув правильно встановити своє ім’я користувача та властивості електронної пошти користувача (нова машина). Я ще не перемістив ці коміти до свого сховища, тож як я можу виправити ці зобов’язання, перш ніж це зробити (лише три останні коміти в гілці master)?

Я дивився git resetі git commit -C <id> --reset-author, але не думаю, що я на вірному шляху.


1
Ще одна причина, з якої ви можете змінити властивість електронної пошти - це помилка github: remote: error: GH007: Your push would publish a private email address.... `! [віддалено відхилено] master -> master (натиск відхилено через обмеження конфіденційності електронної пошти) `.
craq

Також дивіться stackoverflow.com/q/750172/1340631 .
scai

Відповіді:


232

Поновлення / поправка здається неефективною, коли у вас є сила філії філії під рукою:

git filter-branch --env-filter 'if [ "$GIT_AUTHOR_EMAIL" = "incorrect@email" ]; then
     GIT_AUTHOR_EMAIL=correct@email;
     GIT_AUTHOR_NAME="Correct Name";
     GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL;
     GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; fi' -- --all

(розділити на лінії для наочності, але не обов’язково)

Не забудьте перевірити результат, коли закінчите, щоб переконатися, що ви не змінили нічого, чого не хотіли!


розум, пояснюючи це трохи більше? не впевнений, що таке гілка фільтра
максимальний прибиральник

1
@maxpleaner git filter-branch --helpдосить простий :)
alediaferia

3
Дивіться також help.github.com/articles/changing-author-info , яка також додає --tag-name-filter catдо filter-branch, щоб перенести теги до нової історії. Він також використовує --branches --tagsзамість цього --all, який лише переписує історію гілок і тегів, а інших залишає в refsспокої (хоча це, мабуть, не має великої різниці, якщо, наприклад, ви не використовуєте git-notes)
Tobias Kienzler

12
щоб виконати це на тільки два останніх фіксації, я замінив -- --allзHEAD~1..HEAD
nmz787

1
@ nmz787 Скільки журналів відображається, якщо ви робите git log HEAD~2..HEAD?
Йона

148

Підхід до інтерактивної бази даних є дуже приємним, коли використовується разом із exec. Ви можете запустити будь-яку команду оболонки проти певного комітету або всіх комісій у ребазі.

Спочатку встановіть налаштування автора git

git config --global user.name "John Doe"
git config --global user.email johndoe@example.com

Потім для скидання автора для всіх комісій після даної SHA

git rebase -i YOUR_SHA -x "git commit --amend --reset-author -CHEAD"

Це відкриє ваш редактор, щоб підтвердити зміни. Все, що вам потрібно зробити тут, це зберегти та вийти, і він пройде через кожну команду та запустить команду, вказану у прапорці -x.

Коментуючи коментар Per @ Dave нижче, ви також можете змінити автора, зберігаючи початкові часові позначки:

git rebase -i YOUR_SHA -x "git commit --amend --author 'New Name <new_address@example.com>' -CHEAD"

3
Дякую, що ви познайомили мене з варіантом -x. Це досить приголомшливо! для параметра -i я використав HEAD ~ 4, щоб виправити свою електронну адресу на останніх 4 комітах. працював як шарм.
Бред Хайн

2
Це набагато простіше, ніж filter-branchякщо ви просто хочете виправити свої останні зобов’язання :). Зауважте, що це змінює часову позначку комітетів.
луатор

24
Щоб змінити автора, але зберегти оригінальні часові позначки, використовуйтеgit rebase -i YOUR_SHA -x "git commit --amend --author 'New Name <new_address@example.com>' -CHEAD"
Дейв

2
@Connor git logтакож показав для мене старе авторство, але статус git правильно визначив нові коміти, і після натиску вони були такими, як я мав намір.
Дан М.

6
Для відновлення всіх комісій, включаючи використання root: git rebase -i --root …замість передачі SHA.
gfullam

80

Щоб змінити автора лише для останнього комітету:

git commit --amend --author 'Author Name <author.name@mail.com>' --no-edit

Припустимо, ви хочете змінити автора лише для останніх N комісій:

git rebase -i HEAD~4 -x "git commit --amend --author 'Author Name <author.name@mail.com>' --no-edit"

ПРИМІТКИ

  • то --no-editпрапор переконується git commit --amendне вимагає додаткового підтвердження
  • коли ви використовуєте git rebase -i, ви можете вручну вибрати комісії, де змінити автора,

файл, який ви редагуєте, виглядатиме так:

pick 897fe9e simplify code a little
pick abb60f9 add new feature
exec git commit --amend --author 'Author Name <author.name@mail.com>' --no-edit
pick dc18f70 bugfix

1
для всіх комірок від root. git rebase -i --root UPTO_COMMIT_SHA -x "git commit --amend --author 'NEW_CHANGE' --no-edit"
Ashish Negi

1
Я рекомендую додати --rebase-merges(короткий -r) варіант, щоб зберегти недоторканою топологію вашої гілки, якщо вона містить деякі злиття.
donquixote

4

Цей метод був задокументований Github саме для цієї мети. Етапи:

  1. Відкрийте термінал і зробіть голий клон вашого репо
git clone --bare https://github.com/user/repo.git
cd repo
  1. Редагувати наступний скрипт (заміна OLD_EMAIL, CORRECT_EMAILі CORRECT_NAME)
#!/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
  1. Скопіюйте / вставте сценарій у свій термінал і натисніть клавішу Enter, щоб запустити його.
  2. Натисніть на свої зміни, git push --force --tags origin 'refs/heads/*'і ви закінчите!

Я дотримувався тих же вказівок на GitHub, на які ви посилалися, і GitHub виглядає зараз. Однак я новичок Git і не знаю, як синхронізувати місцеве резервне копіювання після цього. Коли я тягну, я отримую ту саму помилку "відмова від об'єднання пов'язаних історій", згадану в іншій відповіді. Я думаю, що мені потрібно відштовхуватися від нової історії вчинення, але я дуже вдячний за більш конкретні кроки.
загадка

@enigment якщо ви щасливі з репо , як це знаходиться на GitHub, ви можете видалити (або , можливо , перемістити в інше місце) папка у вас є локально і просто клон з GitHub
stevec

Дякую, я знаю, але це не схоже на ідіоматичний GitHub / Git спосіб.
загадка

2

Я вірю, що ви шукаєте git rebase --interactive

Це дозволяє перейти до скидання до певного комітету, а потім перекинути історію, змінюючи додавання або групування комітетів

Тут ви маєте пояснення https://web.archive.org/web/20100213104931/http://blog.madism.org/index.php/2007/09/09/138-git-awsome-ness-git-rebase -інтерактивна


0

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

git reset HEAD~ (скасувати останню фіксацію)

git config --global user.name "Your Name"

git config --global user.email you@example.com

git commit -m "message"

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