Как в Git изменить файлы в старом (не последнем) коммите
Предположим, внести изменения в файлы в старом (не самом последнем) коммите.
Как изменить файлы в старом коммите
1. Если вы уже изменили какие-либо файлы, то сначала их нужно спрятать. Для этого выполняем команду:
git stash
2. Теперь посмотрим список коммитов, чтобы найти нужный:
git log -5 --oneline --decorate
14bfad4 (HEAD -> main) Commit #04
871a760 Commit #03
4c90c4c Commit #02
08660e4 Commit #01
Здесь использовались следущие флаги команды git log
:
-5
– значит, вывести последние 5 коммитов;--oneline
– каждый коммит вывести в одну строку;--decorate
– вывести все ссылки (ветки, теги и т.д.) для каждого коммита.
В примере у нас только 4 коммита. Предположим, нам необходимо изменить коммит - Commit #02.
3. Выполняем команду git rebase -i
и указываем ей номер коммита (относительно HEAD
), который хотим изменить. В данном случае мы хотим изменить третий коммит.
git rebase -i HEAD~3
4. Откроется текстовый редактор со списком коммитов и подсказками.
pick 4c90c4c Commit #02
pick 871a760 Commit #03
pick 14bfad4 Commit #04
# Rebase 08660e4..14bfad4 onto 08660e4 (3 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup [-C | -c] <commit> = like "squash" but keep only the previous
# commit's log message, unless -C is used, in which case
# keep only this commit's message; -c is same as -C but
# opens the editor
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# create a merge commit using the original merge commit's
# message (or the oneline, if no original merge commit was
# specified); use -c <commit> to reword the commit message
# u, update-ref <ref> = track a placeholder for the <ref> to be updated
# to this position in the new commits. The <ref> is
# updated at the end of the rebase
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
Измените слово pick
на edit
(или просто на букву e
) у коммита, который вы хотите изменить.
e 4c90c4c Commit #02
pick 871a760 Commit #03
pick 14bfad4 Commit #04
5. Сохраните изменения в файле и закройте текстовый редактор. Вы снова окажетесь в командной строке.
6. Теперь внесите те изменения, которые вы хотели сделать с файлами. Если вы на первом шаге спрятали эти изменения, то сейчас их можно снова извлечь:
git stash pop
Или просто отредактируйте файлы.
7. Добавьте отредактированные файлы в индекс:
git add file_02.txt
8. Примените изменения к коммиту:
git commit --amend
Или, если не хотите редактировать сообщение коммита:
git commit --amend --no-edit
9. Завершаем процесс перебазирования (rebase):
git rebase --continue
Если всё пройдет успешно, то появится подобное сообщение:
Successfully rebased and updated refs/heads/main.
Как изменить несколько коммитов
Предположим, что нам нужно внести изменения сразу в несколько коммитов.
Выполняем все те же самые действия, что и выше, но на шаге 4 отметьте несколько коммитов, которые хотите изменить. Для этого нужно изменить слово pick
на edit
/e
сразу у нескольких коммитов в списке.
После сохранения файла (шаг 5) вы переключитесь на первый коммит – самый старый из отмеченных для редактирования.
Выполните для него шаги с 6 по 8. После этого вы переключитесь на следующий коммит, отмеченный для редактирования. И так далее.