Рассмотрим в этом уроке что делать, если что-то пошло не так и как "откатить" сделанные изменения в сервисе контроля версий Git.

По традиции текущее состояние мы узнаем командой:

$ git status

Если мы видим, что какой-то файл находится в статусе modified и отмечен красным цветом, то нам нужно посмотреть какие изменения были сделаны в файле или файлах:

$ git diff

Откатить изменения можно командой:

$ git checkout <file_name>

И теперь если мы проверим статус гита, то не увидим никаких предупреждений о модифицированном файле.

Можно также восстановить удаленный файл, если он был закоммичен ранее.

К примеру, если мы удалим файл, то проверка статуса Git покажет, что файл отмечен словом deleted. Восстановить его можно этой же командой:

$ git checkout <file_name>

Команда checkout возвращает состояние файла до последнего коммита, но вернуть состояние до checkout мы уже не сможем. Всё что вы не коммитили - потеряется, поэтому сбрасываете только те изменения, которые вам не нужны.

Мы можем также вернуть состояние файла до какого-либо коммита. Для этого нам нужно знать хеш коммита, который мы можем посмотреть после использования команды:

$ git log

Копируем хеш нужного нам коммита и вводим команду в консоли:

$ git checkout <commit_hash> <file_name>

Заменяем <commit_hash> на хеш коммита, а <file_name> на имя нужного файла, состояние которого мы хотим вернуть.

После чего мы смотрим статус и видим, что наш файл изменен и уже проиндексирован.

Нам нужно посмотреть изменения в этом файле. Мы используем знакомую нам команду diff, но с использованием дополнительного флага --staged:

$ git diff --staged

Команда diff нам показывала не проиндексированные изменения, а добавление флага нам позволяет смотреть проиндексированные изменения. Индекс часто называют "staged area".

Теперь мы можем делать коммит знакомой нам командой:

$ git commit -m "your message here"

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

К примеру, у нас есть два файла в статусе modified - index.html и main.css, и при этом мы не хотим включать index.html в коммит. Тогда мы используем следующую команду:

$ git reset HEAD index.html

После проверим статус и увидим следующее:

Статус нам показывает, что изменения в main.css проиндексированы, а в index.html не проиндексированы. И если мы сделаем коммит, то в него попадут только изменения в main.css.

На скриншоте команда status показывает, что изменения файла index.html не проиндексированы.

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

Вводим далее:

$ git add index.html
$ git commit -m "made changes in index file"

Не забываем проверить статус и посмотреть лог. Также мы можем посмотреть изменения в конкретном коммите через команду show и хеш коммита:

$ git show <commit_hash>

Что если при создании коммита мы сделали ошибку в сообшении (подписи)? Возможно ли исправить ошибку?

Если мы увидели, что в последнем коммите есть ошибка в сообщении, то для начала мы используем команду:

$ git log -1

Флаг -1 говорит терминалу показать только последний коммит, а флаг -2 показывает два коммита, -3 - три и т.д.

Чтобы исправить сообщение коммита мы используем команду:

$ git commit --amend -m "correct message"

Параметр amend позволяет изменить последний коммит.

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

Также есть возможность удалить из коммита лишний файл. Для этого мы используем команду:

$ git rm <file_name>

Если после этой команды мы посмотрим гит статус, то увидим, что файл будет помечен как deleted (рус. - удаленный). Теперь мы применяем команду:

$ git commit --amend --no-edit

В данном случае опять хеш коммита изменится.

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

$ git rm --cached <file_name>

Теперь мы увидим следующее:

Видим, что файл test.css одновременно в статусе deleted и untracked (рус. - не отслеживается). Используем команду:

$ git commit --amend --no-edit

Теперь файл не находится в коммите, но не удален из папки.

Если вам нужно посмотреть информацию про разные команды гита, то вы можете использовать команду help:

$ git help checkout

Команда выше покажет справку по команде checkout, что с ней можно делать и какие флаги (опции) с ней можно использовать. Листать справку можно стрелками с клавиатуры вверх и вниз.