Изменить первую фиксацию проекта с помощью Git?

Я хочу что-то изменить в первом коммите моего проекта без потери всех последующих коммитов. Есть какой-либо способ сделать это?

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


person Michael    schedule 11.02.2010    source источник


Ответы (4)


Как упоминалось ecdpalma ниже, git 1.7.12+ (Август 2012 г.) улучшил параметр --root для git rebase:

«git rebase [-i] --root $tip» теперь можно использовать для перезаписи всей истории, ведущей к «$tip», вплоть до корневого коммита.

Это новое поведение изначально обсуждалось здесь:

Я лично считаю, что "git rebase -i --root" нужно сделать так, чтобы он просто работал, не требуя "--onto", и позволял вам "редактировать" даже первый в истории.
Понятно, что никто не беспокоился, так как люди намного реже переписывают рядом самое начало истории, чем иначе.

За этим последовал патч.


(исходный ответ, февраль 2010 г.)

Как упоминалось в FAQ по Git (и это ТАК вопрос), идея такова:

  1. Создать новую временную ветку
  2. Перемотайте его к фиксации, которую вы хотите изменить, используя git reset --hard
  3. Измените эту фиксацию (это будет верхняя часть текущей HEAD, и вы можете изменить содержимое любого файла)
  4. Перебазируйте ветку поверх измененной фиксации, используя:

    git rebase --onto <tmp branch> <commit after changed> <branch>`
    

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

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

person VonC    schedule 22.02.2010
comment
В OS X Mountain Lion с установленным системой git 1.7.9.6 (Apple Git-31.1) я установил <commit after changed> на тот же хэш, который я использовал в команде git reset --hard. Помимо этого одного незначительного изменения, это прекрасно работает для обновления информации об авторе для всех коммитов в репо. - person berto; 30.12.2012
comment
Можете ли вы привести пример того, что должно быть чаевым. git rebase -i --root работал у меня. - person Rémi Benoit; 04.06.2015
comment
@ RémiBenoit: да, $tip может быть любой коммит, какой захотите. master (что означает master HEAD фиксация) в порядке. - person VonC; 04.06.2015
comment
@VonC, на шаге 3 необходимо отредактировать содержимое коммита. Я пытаюсь сделать это с помощью git reser --soft HEAD~1, но это невозможно, потому что это неоднозначный аргумент HEAD~1 или путь не в рабочем дереве. - person Francis Rodrigues; 26.08.2018
comment
@FrancisRodrigues Я считаю, что шаг 3 касался изменения файлов, добавления и фиксации - person VonC; 26.08.2018
comment
Я думаю Change first commit of project with git это возможно, но мы не упоминали об этом здесь. - person Francis Rodrigues; 26.08.2018
comment
URL-адрес патча не работает. Пожалуйста, обновите, если возможно. - person code_dredd; 16.11.2018
comment
@code_dredd Спасибо. Я восстановил эту ссылку. - person VonC; 16.11.2018
comment
@VonC Ты уверен? Я имею в виду тот URL, который гласит: Патч последовал. В результате появляется пустая страница со следующим сообщением: ArchivedAt Ничего не найдено - пока. - person code_dredd; 16.11.2018
comment
@code_dredd Извините, я изменил не ту ссылку. Я исправил свое предыдущее исправление. - person VonC; 16.11.2018
comment
@VonC Выглядит хорошо. Благодарю за быстрое исправление! - person code_dredd; 16.11.2018
comment
Самый эпический ответ и решение. Удивительный! - person Rambou; 20.11.2020

Как указано в примечаниях к выпуску 1.7.12, вы можете использовать

$ git rebase -i --root
person ecdpalma    schedule 31.01.2013

git rebase -i позволяет удобно редактировать любые предыдущие коммиты, кроме корневого коммита. Следующие команды показывают, как это сделать вручную.

# tag the old root, "git rev-list ..." will return the hash of first commit
git tag root `git rev-list HEAD | tail -1`

# switch to a new branch pointing at the first commit
git checkout -b new-root root

# make any edits and then commit them with:
git commit --amend

# check out the previous branch (i.e. master)
git checkout @{-1}

# replace old root with amended version
git rebase --onto new-root root

# you might encounter merge conflicts, fix any conflicts and continue with:
# git rebase --continue

# delete the branch "new-root"
git branch -d new-root

# delete the tag "root"
git tag -d root
person cmcginty    schedule 24.02.2010
comment
Я следовал этим инструкциям, как n00b, и они отлично работали - спасибо! Возможно, вы захотите упомянуть добавление -a в git commit --amend или использование git add, потому что я забыл об этом в первый раз! - person Nick Craig-Wood; 11.11.2012
comment
Это уже неверно, обратитесь к принятому ответу - person Robin Kanters; 10.05.2016
comment
Большое спасибо за ваш ответ. Я использую Centos 7, а версия git - 1.7.1 с множеством ограничений на команды. Принятый ответ не сработал для меня, и это как сработало как шарм, чтобы восстановить историю репозитория из начальной фиксации - person Marcos Regis; 05.07.2016

Если вы хотите изменить только первую фиксацию, вы можете попробовать git rebase и изменить фиксацию, что похоже на этот пост: Как изменить указанную фиксацию в git?

И если вы хотите изменить все коммиты, которые содержат необработанное электронное письмо, лучшим выбором будет filter-branch. В книге Pro Git есть пример того, как изменить адрес электронной почты во всем мире, и вы можете найти эту ссылку полезной http://git-scm.com/book/en/Git-Tools-Rewriting-History

person ZelluX    schedule 11.02.2010