2010-02-11 4 views
328

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

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

ответ

484

Как отметил ecdpalmabelow, git 1.7.12+ (август 2012) повысило возможность --root для git rebase:

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

Это новое поведение было изначально discussed here:

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

patch followed.


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

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

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

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

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

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

+4

На OS X Mountain Lion с системой установленной мерзавца 1.7.9.6 (Apple Git-31,1) Я поставил '<коммит после изменен>' для быть тем же самым хешем, который я использовал в команде 'git reset -hard'. Помимо этого незначительного изменения, это прекрасно работает, чтобы обновить информацию об авторе во всех транзакциях в репо. – berto

+4

вы можете привести пример того, что должно быть $ tip. 'git rebase -i -root' работал для меня. –

+0

@ RémiBenoit да, '$ tip' может быть любой фиксацией, которую вы хотите. 'master' (что означает' master HEAD' commit) в порядке. – VonC

0

Если вы хотите изменить только первый коммит, вы можете попробовать Git перебазироваться и изменить коммит, который похож на этот пост: How to modify a specified commit in git?

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

71

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 
+10

Я следовал этим инструкциям, как n00b, и они отлично работали - спасибо! Возможно, вы захотите добавить '-a' в' git commit -amend' или использовать 'git add', потому что я забыл об этом в первый раз! –

+1

Это больше не соответствует действительности, см. Принятый ответ. –

+0

Большое спасибо за ваш ответ. Я использую Centos 7, а версия git - 1.7.1 с большим количеством ограничений на команды. Принятый ответ не сработал для меня, и этот _ ** как ** _ работал как шарм, чтобы перестроить историю хранилища из _ ** начального коммита ** _ –

126

Как указано в 1.7.12 Release Notes, вы можете использовать

$ git rebase -i --root 
+2

git версия 1.7.9 жалуется: 'Вы должны указать - -onto при использовании --root' –

+2

Он отлично работает с git 1.9.4 –

+2

Работал чудесно для меня тоже, используя git 1.9.4. –