Изменение одного файла в прошлом в git

Я хочу исправить файл в прошлом. Это может повлиять на все восходящие коммиты.

Есть ли простой способ сделать это? Можете ли вы дать мне руководство о том, как это сделать?

Много раз, когда я делаю два раза, я обнаружил, что у меня была ошибка в первом фиксации, и я хочу исправить ошибку, не имея "git reset" моей последней хорошей фиксации.

Для уточнения. Я хочу изменить фактическое commit, то есть хочу, чтобы содержимое прошлой фиксации было изменено. IOW Я хочу изменить историю!

Ответ 1

Если вы хотите изменить второе и последнее коммит (например, недавно, особенно не до многих ветвей и слияний), я использую эту процедуру:

  • git checkout -b tmp bad-commit
  • исправить файлы
  • git commit --amend
  • git rebase tmp master

Если у вас есть слияния между ними, вы можете попробовать rebase -i -p, но результаты могут отличаться.

Ответ 2

Похоже:

  • a filter-branch (сложная команда, которая может делать то, что вы хотите)
  • и изменить и переустановить, как описано jpalecek. Вы найдете то же самое решение более подробно в этом другом связанном вопросе.

Вы можете найти пример переадресации в этот комментарий: тогда вы могли бы избежать временной ветки, но, опять же, она сложнее.

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

Приведенный пример:
Я переименовал функцию foo в bar и передал ее с комментарием, который гласит: "переименовано в foo to bar".
Затем я перехожу к следующей функции или исправлению и фиксирую это и перехожу к следующему.
 На полпути я обнаружил, что пропустил экземпляр foo!
Я выполняю свою работу (или использую git -stash), исправить недостающее "foo" и зафиксировать это, а затем использовать git-rebase --interactive, чтобы объединить все исправления foo вместе в один чистый commit.
Если я не использовал git-stash, тогда я воспользуюсь git-commit --amend (другая форма переустановки), когда я, наконец, закончу выполняемую функцию.

Когда мои патчи выставляются для просмотра, все части верны и сообщают последовательную историю. Иногда я использую git-rebase --interactive только для смещения разделенных по времени изменений, которые влияют на одни и те же биты, так что изменения находятся в контексте.