Как в Git изменить файлы в старом (не последнем) коммите

Добавлено 11 августа 2023 в 22:31

Предположим, внести изменения в файлы в старом (не самом последнем) коммите.

Как изменить файлы в старом коммите

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. После этого вы переключитесь на следующий коммит, отмеченный для редактирования. И так далее.

Теги

GitСистемы контроля версий

На сайте работает сервис комментирования DISQUS, который позволяет вам оставлять комментарии на множестве сайтов, имея лишь один аккаунт на Disqus.com.

В случае комментирования в качестве гостя (без регистрации на disqus.com) для публикации комментария требуется время на премодерацию.