Я писал простой сценарий на школьном компьютере и вносил изменения в Git (в репозитории, который был в моем pendrive, клонирован с моего компьютера дома). После нескольких коммитов я понял, что коммитирую как пользователь root.
Есть ли способ изменить автора этих коммитов на мое имя?
git
version-control
git-filter-branch
git-rewrite-history
Flávio Amieiro
источник
источник
Ответы:
Смена автора (или коммиттера) потребует переписывания всей истории. Если вы согласны с этим и считаете, что оно того стоит, вам следует проверить git filter-branch . Страница man содержит несколько примеров, с которых можно начать. Также обратите внимание, что вы можете использовать переменные окружения, чтобы изменить имя автора, коммиттера, даты и т. Д. - см. Раздел «Переменные среды» на странице руководства git .
В частности, вы можете исправить все неправильные имена авторов и электронные адреса для всех веток и тегов с помощью этой команды (источник: GitHub help ):
источник
git push --force --tags origin HEAD:master
ПРИМЕЧАНИЕ. Этот ответ изменяет SHA1, поэтому позаботьтесь об его использовании в уже перемещенной ветви. Если вы хотите исправить только написание имени или обновить старую электронную почту, git позволяет вам делать это без переписывания истории с помощью
.mailmap
. Смотрите мой другой ответ .Использование интерактивной ребазы
Вы могли бы сделать
Затем пометьте все ваши плохие коммиты как "edit" в файле rebase. Если вы также хотите изменить свой первый коммит, вы должны вручную добавить его в качестве первой строки в файле rebase (следуйте формату других строк). Затем, когда git просит вас внести изменения в каждый коммит, выполните
отредактируйте или просто закройте открывшийся редактор, а затем выполните
продолжить ребаз.
Вы можете вообще пропустить открытие редактора, добавив
--no-edit
команду так:Single Commit
Как отмечают некоторые из комментаторов, если вы просто хотите изменить самый последний коммит, команда rebase не нужна. Просто делать
Это изменит автора на указанное имя, но для коммиттера будет настроен ваш настроенный пользователь в
git config user.name
иgit config user.email
. Если вы хотите установить для коммиттера что-то, что вы укажете, это установит и автора, и коммиттера:Примечание о слиянии коммитов
В моем первоначальном ответе был небольшой недостаток. Если есть какие-либо коммиты слияния между текущим
HEAD
и вашим<some HEAD before all your bad commits>
, тогда ониgit rebase
будут сглажены (и, между прочим, если вы используете GitHub pull-запросы, в вашей истории будет тонна коммитов слияния). Это может очень часто приводить к очень разной истории (поскольку повторяющиеся изменения могут быть «перебазированы»), и в худшем случае это может привести к тому, чтоgit rebase
вас попросят разрешить сложные конфликты слияния (которые, вероятно, уже были разрешены в коммитах слияния). Решением является использование-p
флага togit rebase
, который сохранит структуру слияния вашей истории. Страница man дляgit rebase
предупреждений о том, что использование-p
и-i
может привести к проблемам, но вBUGS
в разделе написано «Редактирование коммитов и переписывание их коммитов должны работать нормально».Я добавил
-p
к вышеупомянутой команде. Для случая, когда вы просто изменяете самый последний коммит, это не проблема.источник
git commit --amend --reset-author
также работает один разuser.name
иuser.email
настроен правильно.<commit>
использованияuser.name
иuser.email
из~/.gitconfig
: запуститьgit rebase -i <commit> --exec 'git commit --amend --reset-author --no-edit'
, сохранить, выйти. Не нужно редактировать!Вы также можете сделать:
Обратите внимание: если вы используете эту команду в командной строке Windows, вам необходимо использовать
"
вместо'
:источник
"A previous backup already exists in refs/original/ Force overwriting the backup with -f"
извините, но где-f
будет флаг, когда вы выполняете этот скрипт два раза. На самом деле это ответ Брайана, извините за беспокойство сразу после того, как ответвление фильтра является решением.Один вкладыш, но будьте осторожны, если у вас есть многопользовательский репозиторий - это изменит все коммиты на одного и того же (нового) автора и коммиттера.
С переносами строк в строке (что возможно в bash):
источник
HEAD
в конце команды?git push --force --tags origin 'refs/heads/*'
после рекомендованной команды$git push --force --tags origin 'refs/heads/master'
Это происходит, когда у вас нет инициализированного $ HOME / .gitconfig. Вы можете исправить это как:
протестировано с версией git 1.7.5.4
источник
--local
работ тожеgit commit --amend --reset-author --no-edit
команда особенно полезна, если вы создали коммиты с неверной информацией об авторе, а затем установите корректного автора через фактgit config
. Спасли мой $$ только сейчас, когда мне пришлось обновить свою электронную почту.Для одного коммита:
(извлечено из ответа asmeurer)
источник
git help commit
,git commit --amend
изменения фиксируются на «вершине текущей ветви» (то есть HEAD). Как правило , это самый последний коммит, но вы можете сделать это любой фиксации вы хотите, сначала проверяя , что совершаемgit checkout <branch-name>
илиgit checkout <commit-SHA>
.author
а неcommitter
В случае, если только у нескольких верхних коммитов есть плохие авторы, вы можете сделать все это внутри,
git rebase -i
используяexec
команду и--amend
коммит, следующим образом:который представляет вам редактируемый список коммитов:
Затем добавьте
exec ... --author="..."
строки после всех строк с плохими авторами:сохранить и выйти из редактора (для запуска).
Это решение может быть длиннее, чем некоторые другие, но оно очень управляемо - я точно знаю, что оно совершает.
Спасибо @asmeurer за вдохновение.
источник
exec git commit --amend --reset-author -C HEAD
?Someone else's commit
вместоmy bad commit 1
? Я просто попыталсяHEAD^^
изменить последние 2 коммита, и это сработало идеально.git rebase -i HEAD^^^^^^
вас также можно написатьgit rebase -i HEAD~6
У Github есть отличное решение : скрипт оболочки:
источник
git reset --hard HEAD^
пару раз в других локальных репозиториях перенести их в более раннюю версию,git pull
- исправленную версию, и здесь я без каких-либо строк, содержащихunknown <stupid-windows-user@.StupidWindowsDomain.local>
(получил любовь к дефолту git).git push -f
. Кроме того, местные репо должны быть перенесены после этого.Как уже упоминалось в docgnome, переписывание истории опасно и разрушит хранилища других людей.
Но если вы действительно хотите это сделать и находитесь в среде bash (без проблем в Linux, в Windows вы можете использовать git bash, который поставляется вместе с git), используйте git filter-branch :
Чтобы ускорить процесс, вы можете указать диапазон ревизий, которые вы хотите переписать:
источник
--tag-name-filter cat
это опция "заставь это работать".--tag-name-filter cat
. Это действительно должно было быть поведением по умолчанию.Принимая нефиксированный коммит от другого автора, есть простой способ справиться с этим.
git commit --amend --reset-author
источник
--no-edit
чтобы сделать это еще проще, так как обычно большинство людей хотят обновить только адрес электронной почты, а не сообщение оВы можете использовать это как псевдоним, так что вы можете сделать:
или за последние 10 коммитов:
Добавьте в ~ / .gitconfig:
Источник: https://github.com/brauliobo/gitconfig/blob/master/configs/.gitconfig
Надеюсь, это полезно.
источник
[[ ]]
на sh-совместимый тест[ ]
(одиночные скобки). Кроме того, это работает очень хорошо, спасибо!Это более сложная версия версии @ Brian:
Чтобы изменить автора и коммиттера, вы можете сделать это (с переносом строки в строке, что возможно в bash):
Вы можете получить одну из этих ошибок:
(это означает, что другая ветвь фильтра была запущена ранее в хранилище, а затем ссылка на оригинальную ветку резервируется в refs / original )
Если вы хотите форсировать запуск, несмотря на эти ошибки, добавьте
--force
флаг:Небольшое объяснение
-- --all
опции может потребоваться: она заставляет ветку фильтра работать на всех ревизиях на всех ссылках (которая включает в себя все ветки). Это означает, например, что теги также переписаны и видны в переписанных ветвях.Распространенной «ошибкой» является использование
HEAD
вместо этого, что означает фильтрацию всех ревизий только в текущей ветви . И тогда в переписанной ветке не будет никаких тегов (или других ссылок).источник
Одной команды , чтобы изменить автор за последние N фиксаций:
НОТЫ
--no-edit
флаг убеждаетсяgit commit --amend
не требует дополнительного подтвержденияgit rebase -i
, вы можете вручную выбрать коммиты, где сменить автора,файл, который вы редактируете, будет выглядеть так:
Затем вы можете изменить некоторые строки, чтобы увидеть, где вы хотите изменить автора. Это дает вам хорошее промежуточное звено между автоматизацией и управлением: вы видите шаги, которые будут выполняться, и после сохранения все будет применено сразу.
источник
git rebase -i master -x ...
git rebase -i <sha1 or ref of starting point>
edit
(илиe
)выполните следующие две команды, пока не обработаете все коммиты:
git commit --amend --reuse-message=HEAD --author="New Author <new@author.email>"
;git rebase --continue
Это сохранит всю остальную информацию о коммите (включая даты). Эта
--reuse-message=HEAD
опция запрещает запуск редактора сообщений.источник
Я использую следующее, чтобы переписать автора для всего хранилища, включая теги и все ветви:
Затем, как описано на странице MAN в ответвлении фильтра , удалите все исходные ссылки, скопированные с помощью
filter-branch
(это деструктивно, сначала сделайте резервную копию):источник
--tag-name-filter cat
. В противном случае ваши теги останутся в исходной цепочке коммитов. Другие ответы не упоминают об этом.Я адаптировал это решение, которое работает путем приема простого
author-conv-file
(формат такой же, как и для git-cvsimport ). Он работает путем изменения всех пользователей, как определено воauthor-conv-file
всех ветвях.Мы использовали это в сочетании с
cvs2git
миграцией нашего репозитория из cvs в git.т.е. образец
author-conv-file
Сценарий:
источник
Я должен отметить, что если единственная проблема заключается в том, что автор / электронная почта отличается от вашего обычного, это не проблема. Правильное исправление заключается в создании файла с именем
.mailmap
в основании каталога с такими строками, какИ с тех пор команды like
git shortlog
будут считать эти два имени одинаковыми (если вы специально не скажете им не делать этого). См. Http://schacon.github.com/git/git-shortlog.html. для получения дополнительной информации.Это дает преимущество перед всеми остальными решениями, заключающимися в том, что вам не нужно переписывать историю, что может вызвать проблемы, если у вас есть апстрим, и это всегда хороший способ случайно потерять данные.
Конечно, если вы передали что-то как себя, и это действительно должен быть кто-то другой, и вы не против переписать историю на этом этапе, изменение автора коммита, вероятно, является хорошей идеей для целей атрибуции (в этом случае я направляю вас к своему другой ответ тут).
источник
Я обнаружил, что представленные версии являются агрессивными, особенно если вы делаете патчи от других разработчиков, это по существу украдет их код.
Версия ниже работает на всех ветках и меняет автора и комитера отдельно, чтобы предотвратить это.
Престижность к leif81 для всего варианта.
источник
Изменение фиксации
author name & email
путемAmend
, то заменаold-commit with new-one
:Другой способ
Rebasing
:источник
Самый быстрый и простой способ сделать это - использовать аргумент --exec в git rebase:
Это создаст список задач, который выглядит следующим образом:
и это будет работать все автоматически, что работает, когда у вас есть сотни коммитов.
источник
Если вы являетесь единственным пользователем этого репозитория, вы можете переписать историю, используя
git filter-branch
(как писал svick ), илиgit fast-export
/ илиgit fast-import
сценарий фильтра (как описано в статье, на который есть ссылка в ответе docgnome ), или интерактивную перебазировку . Но любой из них изменил бы ревизии с первого измененного коммита и далее; это означает проблемы для любого, кто основывал свои изменения на предварительной ветке вашей ветки.ВОССТАНОВЛЕНИЕ
Если бы другие разработчики не основывали свою работу на версии перед перезаписью, самым простым решением было бы переклонировать (снова клонировать).
В качестве альтернативы они могут попытаться
git rebase --pull
выполнить ускоренную перемотку, если в их хранилище не было никаких изменений, или перебазировать свою ветку поверх переписанных коммитов (мы хотим избежать слияния, так как это сохранит пре-переписанные комиты навсегда). Все это при условии, что они не имеют работы; используйте,git stash
чтобы скрыть изменения в противном случае.Если другие разработчики используют ветви функций и / или
git pull --rebase
не работают, например, из-за того, что апстрим не настроен, они должны перебазировать свою работу поверх коммитов после перезаписи. Например, сразу после получения новых изменений (git fetch
), дляmaster
ветви, основанной на / разветвленнойorigin/master
, нужно запуститьВот состояние
origin/master@{1}
предварительной перезаписи (перед извлечением), см. Gitrevisions .Альтернативным решением было бы использовать refs / replace / механизм, доступный в Git начиная с версии 1.6.5. В этом решении вы предоставляете замену для коммитов, которые имеют неправильный адрес электронной почты; тогда любой, кто выбирает «заменить» ссылки (что-то вроде
fetch = +refs/replace/*:refs/replace/*
refspec в соответствующем месте в их.git/config
), получит замены прозрачно, а те, кто не получит эти ссылки, увидят старые коммиты.Процедура идет примерно так:
Найти все коммиты с неправильным адресом электронной почты, например, используя
Для каждого неправильного коммита создайте коммит замены и добавьте его в базу данных объектов.
Теперь, когда вы исправили коммит в объектной базе данных, вы должны указать git автоматически и прозрачно заменить неправильный коммит на исправленный с помощью
git replace
команды:Наконец, перечислите все замены, чтобы проверить, успешно ли прошла эта процедура.
и проверьте, есть ли замены
Конечно, вы можете автоматизировать эту процедуру ... ну, все, кроме использования,
git replace
которое не имеет (пока) пакетного режима, так что вам придется использовать цикл оболочки для этого или заменить «вручную».НЕ ПРОВЕРЕНО! YMMV.
Обратите внимание, что при использовании
refs/replace/
механизма вы можете столкнуться с некоторыми грубыми углами : он новый и еще не очень хорошо протестирован .источник
Если коммиты, которые вы хотите исправить, являются самыми последними, и только несколько из них, вы можете использовать комбинацию
git reset
и,git stash
чтобы вернуться к фиксации их снова после настройки правильного имени и адреса электронной почты.Последовательность будет примерно такой (для 2 неправильных коммитов, без ожидающих изменений):
источник
Если вы используете Eclipse с EGit, то есть довольно простое решение.
Предположение: у вас есть коммиты в локальной ветке 'local_master_user_x', которую нельзя отправить в удаленную ветку 'master' из-за недопустимого пользователя.
источник
Используя интерактивную перебазировку, вы можете поместить команду исправления после каждого коммита, который вы хотите изменить. Например:
источник
;-)
.Обратите внимание, что git хранит два разных адреса электронной почты: один для коммиттера (человека, который внес изменение), а другой для автора. (человека, который написал изменение).
Информация о коммитере не отображается в большинстве мест, но вы можете увидеть ее с помощью
git log -1 --format=%cn,%ce
(или использоватьshow
вместоlog
указания конкретного коммита).Менять автора вашего последнего коммита так же просто, как
git commit --amend --author "Author Name <email@example.com>"
и отсутствие единой строки или аргумента, чтобы сделать то же самое с информацией о коммитере.Решение состоит в том, чтобы (временно или нет) изменить вашу пользовательскую информацию, а затем изменить коммит, который обновит коммиттера до вашей текущей информации:
источник
path\to\repo\.git
. Я еще не уверен, что вам нужно сделать, чтобы полностью исключить это. К сожалению, исправления (?) Не стираются.Сегодня мы столкнулись с проблемой, когда символ UTF8 в имени автора вызывал проблемы на сервере сборки, поэтому нам пришлось переписать историю, чтобы исправить это. Предпринятые шаги:
Шаг 1: Измените свое имя пользователя в git для всех будущих коммитов, следуя инструкциям здесь: https://help.github.com/articles/setting-your-username-in-git/
Шаг 2: Запустите следующий скрипт bash:
Краткий обзор: извлеките свой репозиторий во временный файл, извлеките все удаленные ветви, запустите сценарий, который перезапишет историю, сделайте принудительное выдвижение нового состояния и попросите всех своих коллег выполнить перебазирование для получения изменений.
У нас были проблемы с запуском этого на OS X, потому что он как-то испортил окончания строк в сообщениях коммита, поэтому нам пришлось потом перезапускать его на машине Linux.
источник
Ваша проблема действительно распространена. Смотрите " Использование Mailmap для исправления списка авторов в Git "
Для простоты я создал скрипт для облегчения процесса: git-changemail
Поместив этот скрипт в свой путь, вы можете выполнить такие команды:
Изменить совпадения авторов в текущей ветке
Измените совпадения авторов и коммиттеров для <branch> и <branch2>. Перейдите
-f
в filter-branch, чтобы разрешить перезапись резервных копийПоказать существующих пользователей в репо
Кстати, после внесения изменений очистите резервную копию из ветви фильтра с помощью: git-backup-clean
источник
Попробуйте это. Это будет сделано так же, как указано выше, но в интерактивном режиме.
Ссылка: https://github.com/majdarbash/git-author-change-script
источник
Я тоже хочу добавить свой пример. Я хочу создать bash_function с заданным параметром.
это работает в Mint-Linux-17.3
источник
Если вы являетесь единственным пользователем этого репо или вас не волнует возможное нарушение репо для других пользователей, тогда да. Если вы выдвинули эти коммиты, и они существуют там, где кто-то другой может получить к ним доступ, то нет, если вы не заботитесь о нарушении репо других людей. Проблема заключается в том, что, изменяя эти коммиты, вы будете генерировать новые SHA, в результате чего они будут рассматриваться как разные коммиты. Когда кто-то еще пытается втянуть эти измененные коммиты, история становится другой и kaboom.
На этой странице http://inputvalidation.blogspot.com/2008/08/how-to-change-git-commit-author.html описано, как это сделать. (Я не пробовал это так, YMMV)
источник
refs/replace/
механизм.