Как переключаться между коммитами git
Перейти к содержимому

Как переключаться между коммитами git

  • автор:

Как переключаться между коммитами git

Скачай курс
в приложении

Перейти в приложение
Открыть мобильную версию сайта

© 2013 — 2023. Stepik

Наши условия использования и конфиденциальности

Get it on Google Play

Public user contributions licensed under cc-wiki license with attribution required

Как вернуться (откатиться) к более раннему коммиту?

A , B , C , D — коммиты в ветке master .
(HEAD) — местоположение указателя HEAD.
(i) — состояние индекса Git. Если совпадает c (HEAD) — пуст. Если нет — содержит изменения, подготовленные к следующему коммиту.
(wt) — состояние рабочей области проекта (working tree). Если совпадает с (i) — нет неиндексированных изменений, если не совпадает — есть изменения.
↑ обозначает коммит, на который указывает определенная ветка или указатель.

Вот решения, в зависимости от задачи:

1. Временно переключиться на другой коммит

Если вам нужно просто переключиться на другой коммит, чтобы, например, посмотреть на его содержимое, достаточно команды git checkout :

git checkout aaaaaa (wt) (i) A - B - C - D ↑ ↑ (HEAD) master 

Сейчас репозиторий находится в состоянии «detached HEAD». Чтобы переключиться обратно, используйте имя ветки (например, master ):

git checkout master 

2. Переключиться на коммит и продолжить работу с него

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

git checkout -b имя-новой-ветки aaaaaa (wt) (i) A - B - C - D ↑ ↑ new master (HEAD) 

3. Удалить изменения в рабочей области и вернуть ее к состоянию как при последнем коммите.

 (i) (wt) A - B - C - D - ? - ? ↑ master (HEAD) 

3.1 Безопасно — с помощью кармана (stash)

3.1.1 Только неиндексированные

Можно удалить прикарманить только те изменения, которые еще не были индексированы (командой add ):

git stash save --keep-index 
 (wt) (i) A - B - C - D - ? ? ↑ ↑ master stash (HEAD) 

3.1.2 Индексированные и нет

Эта команда отменяет все индексированные и неиндексированные изменения в рабочей области, сохраняя их в карман (stash).

git stash save 
 (wt) (i) A - B - C - D ? ↑ ↑ master stash (HEAD) 

Восстановление несохраненных изменений: легко и просто.

git stash apply 

Если stash совсем не нужен, его можно удалить.

# удалить последнюю запись кармана git stash drop 

После этого восстановить изменения всё ещё можно, но сложнее: How to recover a dropped stash in Git?

3.2 Опасный способ

Осторожно! Эта команда безвозвратно удаляет несохраненные текущие изменения из рабочей области и из индекса Если они вам все-таки нужны, воспользуйтесь git stash .

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

Здесь мы будем использовать git reset —hard

git reset --hard HEAD 
 (wt) (i) A - B - C - D - х - х ↑ master (HEAD) 

4. Перейти к более раннему коммиту в текущей ветке и удалить из нее все последующие (неопубликованные)

Осторожно! Эта команда переписывает историю Git-репозитория. Если вы уже опубликовали ( git push ) свои изменения, то этот способ использовать нельзя (см. почему). Используйте вариант из пункта 5 ( git revert ).

4.1 При этом сохранить изменения в индекс репозитория:

git reset --soft bbbbbb 

После этого индекс репозитория будет содержать все изменения от cccccc до dddddd . Теперь вы можете сделать новый коммит (или несколько) на основе этих изменений.

 (wt) (i) A - B - C - D ↑ master (HEAD) 

4.2 Сохранить изменения в рабочей области, но не в индексе.

git reset bbbbbb 

Эта команда просто перемещает указатель ветки, но не отражает изменения в индексе (он будет пустым).

 (i) (wt) A - B - C - D ↑ master (HEAD) 

4.3 Просто выбросить изменения.

Осторожно! Эта команда безвозвратно удаляет несохраненные текущие изменения. Если удаляемые коммиты не принадлежат никакой другой ветке, то они тоже будут потеряны.

Восстановление коммитов: Используйте git reflog и этот вопрос чтобы найти и восстановить коммиты; иначе сборщик мусора удалит их безвозвратно через некоторое время.

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

 (i) (wt) A - B - C - D - ? - ? ↑ master (HEAD) 
git reset --hard bbbbbb 
 (wt) (i) A - B - C - D - х - х ↑ master (HEAD) 

5. Отменить уже опубликованные коммиты с помощью новых коммитов

Воспользуйтесь командой git revert . Она создает новые коммиты, по одному на каждый отменяемый коммит. Таким образом, если нужно отменить все коммиты после aaaaaa :

# можно перечислить отменяемые коммиты git revert bbbbbb cccccc dddddd # можно задать диапазон от более раннего к более позднему (новому) git revert bbbbbb..dddddd # либо в относительных ссылках git revert HEAD~2..HEAD # можно отменить коммит слияния, указывая явным образом номер предка (в нашем примере таких нет): git revert -m 1 abcdef # после этого подтвердите изменения: git commit -m'детальное описание, что и почему сделано' 

Восстановление: Если revert-коммит оказался ошибочным, используйте этот ответ.

Git checkout — работа с ветками

Рассказываем о команде git checkout, которая позволяет перемещаться между ветками, коммитами и состояниями файлов.

Введение

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

Что такое git checkout

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

Git checkout позволяет переключаться между ветками и восстанавливать предыдущее состояние файлов. Это дает полный контроль над рабочим процессом.

Как использовать git checkout

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

git checkout [наименование ветки | хэш коммита]

Команда выше является общим шаблоном задействования git checkout для перехода к определенной ветке или коммиту. Из этого можно понять, что переключение происходит с использованием ссылок (refs). Как пример, переключение по ветке:

git checkout pretty_branch

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

git branch

Строка ветки, которая задействована прямо сейчас, будет помечена звездочкой (*). Если требуется показать все ветвление (включая ветки удаленного репозитория), необходимо добавить флаг -a. Задействовав флаг -r, будет выведен список только удаленных веток.

Варианты использования git checkout

Переключение веток

Одним из типичных вариантов использования git checkout является переключением между ветками. Посмотрев список веток, выберем ветку feature для переключения:

git checkout feature

Если же необходимость переключиться на удаленную ветку, синтаксис остается прежним, но вместо локальной ветки пишется удаленная:

git checkout origin/feature

Создание новой ветки

Создание ветки и переключение на нее же — распространенное действие в Git. Осуществляется это действие при помощи git checkout таким образом:

git checkout -b new_branch

Где new_branch — название создаваемой ветки. Работа над новой веткой будет происходить независимо от основной. Закончив с изменениями, можно их объединить с основной веткой.

Проверка коммитов и состояние отсоединенного HEAD

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

git checkout [хэш коммита]

Посмотреть список последних коммитов наряду с их хэшем можно командой git log. При проверке коммита нужно быть внимательным, так как переключение по хэшу приводит к состоянию отсоединенного указателя HEAD (detached HEAD). Это состояние означает, что новые коммиты не будут принадлежать ни одной из веток, дальнейшая разработка может привести к случайной потере данных.

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

Отмена изменений в рабочей директории и восстановление файлов

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

git checkout -- [путь к файлу]

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

git checkout -- .

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

git checkout [хэш коммита] -- [путь к файлу]

Такая команда поместит нужный файл в рабочую директорию. Рекомендуется использовать git diff вместе с git checkout, чтобы посмотреть изменения в файлах, прежде чем их отменить. Также помогает команда git status, обнаруживающая новые изменения.

Копирование удаленной ветки

Совместная работа в удаленном репозитории часто включает в себя множество веток для разработки. Git checkout позволяет получить конкретную удаленную ветку и создать ее локальную копию, если воспользоваться следующим вводом:

git checkout -b [локальная ветка] origin/[удаленная ветка]

Получается рабочая копия ветки удаленного репозитория.

Git checkout против git reset

Git checkout и git reset позволяют перемещаться между коммитами, но работают они по-разному.

  • Git checkout в основном используется для переключения веток, проверки коммитов и восстановления файлов.
  • Git reset используется для отмены коммитов и перемещения указателя ветки на другой коммит, эффективно удаляя некоторые коммиты из истории репозитория.

Говоря вкратце, git checkout используется в основном для навигации по репозиторию, а git reset — для перезаписи истории.

Возможные ошибки при работе с git checkout

Разработчики могут столкнуться с трудностями при работе с командами Git. Чтобы быть готовым к ним, приведем примеры возможных ошибок, которые могут возникнуть с git checkout.

  • Потеря несохраненных изменений. Если есть несохраненные изменения в рабочем каталоге, при переключении на другую ветку Git предупреждает, что изменения могут быть потеряны. В этом случае лучше выполнить коммит или сохранить изменения во временном хранилище с помощью git stash.
  • Некорректное указание коммита или ветки. При разработке следует всегда быть внимательным к названиям коммитов и веток.
  • Отсутствие указанного файла.
  • Конфликт изменений файлов. Такое может произойти, если переключиться на ветку, которая имеет такой же файл, но с другими изменениями. В этом случае стоит вручную произвести слияние веток, либо выбрать, какие изменения использовать.

Флаги и опции git checkout

Git checkout также поддерживает различные опции, расширяющие возможности данной команды. Например, —track или -t позволяет установить слежение между новой веткой (как в примере ниже — feature) и одноименной удаленной.

git checkout -t origin/main

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

git checkout --orphan branchname

Возможно и принудительное переключение на другую ветку через флаг -f или —force:

git checkout -f force_switched

Также может возникнуть ситуация, когда понадобится выбрать изменения при переключении веток в конфликте изменений файлов. Выбор осуществляется опциями —ours (выбор изменений из текущей ветки) или —theirs (выбор изменений из переключаемой ветки).

git checkout [--ours | --theirs] [путь к файлу]

Заключение

Git checkout — фундаментальная команда в системе контроля версий Git, позволяющая разработчикам перемещаться между ветками, коммитами и состояниями файлов. Но чтобы разработка шла более плавно, стоит обратить внимание на такие вещи как:

  • Состояние отсоединенного HEAD: при перемещении между коммитами HEAD перестает ссылаться на ветку и является отсоединенным. Лучше всегда создавать новую ветку, если планируются вносить изменения после определенного коммита при отсоединенном состоянии HEAD.
  • Переключение между ветками: следует убедиться, что индекс чист (нет незафиксированных изменений), прежде чем переключаться между ветками. Это позволит предотвратить возможную потерю данных.
  • Конфликты: перед объединением веток следует проверять код на конфликты.

Зарегистрируйтесь в панели управления

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

Как переключаться между коммитами git

Как переключиться на нужный коммит?

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

git checkout commit

Где commit — это хеш (обозначение, имя) коммита, причем можно указывать не весь хеш, а несколько начальных символов хеша.

Примечание: переключение на интересующий пользователя коммит всегда будет приводить репозитарий в состояние detached HEAD . Это нормально, не стоит этого бояться.

Нахождение в состоянии «detached HEAD» можно проверить командой git status :

$ git checkout 3c53ec44

HEAD отделён на 3c53ec44

Состояние «detached HEAD» означает, что текущий рабочий указатель не находится ни на какой ветке. Но как же так? Ведь коммит всегда принадлежит какой-то ветке! Это можно увидеть в том же gitk. А разгадка в том, что коммиты в Git — это, конечно, «снимки состояния репозитария, которые связаны между собой, образуя цепочки». Но нужно понимать, что цепочки коммитов в Git не считаются ветками! Вот это поворот!

Веткой в Git называется указатель на коммит, и этому указателю задано определенное имя. Если такой указатель указывает на последний коммит в цепочке, то в момент добавления нового коммита (у которого текущий является родителем) этот именованный указатель автоматически «переместится»: то есть он начнет указывать на новый коммит. А имя указателя останется, естественно, без изменений. Таким образом, создается иллюзия, что программист работает в именованной ветке, и при добавлении коммитов ветка прирастает новыми коммитами. Хотя, на деле, система Git оперирует не ветками, а именно указателями на коммиты, не более того.

Нужно запомнить: никаких веток, в естественном человеческом понимании, в Git нет.

Вышеуказанные размышления можно продемонстрировать и по-другому. Нахождение в состоянии «detached HEAD» можно проверить командой git branch :

* (HEAD отделён на 3c53ec44)

Здесь видно, что пользователь переключился на какой-то коммит. Но не видно на какой ветке находится пользователь, и, тем более, не видно на какой ветке он находился ранее. (Перед переключением, в gitk, было видно, что коммит 3c53ec44 находится в ветке control_panel , но не является в ней последним). А так как коммит не последний в ветке, то после переключения рабочий указатель не начинает указывать ни на какую ветку (то есть рабочий указатель не совпадает с каким-либо именованным указателем, находящимся на конце какой-либо ветки). А такое состояние, на первый взгляд, и считается «detached HEAD».

Но тогда возникает вопрос: а что произойдет, если с помощью хеша коммита переключиться на коммит, который является последним в какой-нибудь цепочке, и в gitk видно, что на данном коммите завершается ветка control_panel ? Поймет ли Git, что произошло переключение на коммит, на который указывает именованный указатель с именем control_panel ? То есть, поймет ли Git, что происходит переключение на ветку control_panel ?

Следующие команды показывают, что произошло переключение на коммит, на который так же указывает указатель ветки control_panel . И видно, что хеш коммита (на который переключились) 4c171d82 и хеш ветки 4c171d82 — совпадают. Но состояние «detached HEAD» все равно возникло:

$ git checkout 4c171d82

* (HEAD отделён на 4c171d82) 4c171d82 Manager и регулятор громкости

control_panel 4c171d82 Manager и регулятор громкости

master c4bfddfd ALS перенесен в разел коммутаторов

new_engine b9bcf376 Merge branch ‘new_engine’ of .

То есть, даже если пользователь переключился на конечный коммит какой-либо ветки, состояние считается все равно как «detached HEAD». Надо разобраться почему так происходит.

А дело вот в чем. В Git есть два указателя:

  • Указатель рабочей области проекта — так называемый working tree, или WT-указатель.
  • Указатель рабочей ветки — так называемый HEAD-указатель

Так вот, надо знать что:

  • Команда git checkout ХЕШ_КОММИТА — перемещает WT-указатель, но HEAD-указатель не трогает.
  • Команда git checkout ИМЯ_ВЕТКИ — перемещает WT-указатель и HEAD-указатель.

Если WT-указатель и HEAD-указатель не совпадают, такое состояние и называется «detached HEAD». А когда они совпадают — значит можно нормально работать. Причем работа будет проиcходить в ветке, имя которой соответствует именованному указателю на коммит, на который так же указывает HEAD.

А как вернуться обратно после просмотра коммита?

(да, в конце команды ставится символ тире «-«)

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

Примечание: по-сути, данная команда просмативает историю перемещений пользователя по коммитам.

Дописать. Показать команды просмотра истории перемещений.

А как перейти в самое свежее состояние?

Дописать. Свежее состояние — внутри ветки?

  • Бесплатные сервиса размещения репозитариев Git
  • Git workflow — Теория
  • Git workflow — Краткое введение по основным инструкциям
  • Git Wizardry
  • Про Git на пальцах (для переходящих с SVN)
  • Git на двоих
  • Ежедневный Git
  • Удачная модель ветвления для Git
  • Синхронизация через GIT
  • Git stash — работа с «карманом» в Git
  • Как посмотреть настройки репозитария Git и как их изменить
  • GIT: Инструкция-шпаргалка для начинающих
  • Как перенести локальный GIT-репозитарий на сервер вместе со всей историей
  • git reset — возврат к определенному коммиту, откат изменений, «жесткий» или «мягкий»
  • git revert — отмена изменений, произведенных в прошлом отдельным коммитом
  • Git — работа с ветками
  • Git: Путь Github. Цикл разработки — Простое объяснение
  • Машина времени в GIT
  • Git Rebase: руководство по использованию
  • Git: просмотр лога (истории) в консоли в виде дерева
  • Git: понимание команды git merge
  • Git: Опции слияния для команд merge и pull — определение стратегии слияния
  • Git: как переключиться на нужный коммит
  • Git: как смержить изменения из experimental в master
  • Git: как посмотреть изменения, внесенные определенным коммитом
  • Git: как посмотреть историю изменения одного файла
  • Git: как вернуть один файл в состояние, которое было в определенном коммите
  • git log — особенности данной команды при навигации по истории через git checkout
  • Git: Как исправить HEAD detached from
  • Git: что делать в состоянии detached head
  • Работа в команде с использованием Git на примере проекта в среде Blender 3D
  • Git: Как внести изменения в последний коммит
  • Как в Git создать новую ветку в условиях, когда что-то уже было изменено после последнего коммита
  • Как в Git залить новую локальную ветку в удаленный репозитарий
  • Git: Как подключить новую ветку с удаленного сервера
  • Git: Как узнать текущую ветку
  • Git: В чем разница между Fetch и Pull?
  • GIT: Как исправить ошибочный комментарий к коммиту или файлы в коммите
  • Как настроить git на использование proxy-сервера
  • Использование Git через HTTP-proxy
  • Настройка работы Git через Proxy-сервер
  • Git через proxy
  • Использование git за прокси с аутентификацией
  • Как в Git смержить изменения до конкретного коммита?
  • Самый удобный визуальный клиент Git под основные платформы — SmartGit
  • Основы системы управления версиями Git для новичков на примере SmartGit
  • Как сделать подключение к репозитарию Git через Socks Proxy в условиях отсутствия DNS
  • Как сделать подключение к репозитарию Git через проксирующее SSH соединение
  • Как работать с незавершенными изменениями в коде? Как их коммитить в Git?
  • Как в Git посмотреть незакоммиченные изменения в текстах исходников?
  • Как поместить на GitHub уже существующий репозитарий
  • Что происходит при откате изменений через git reset —soft
  • Не бойся хардресета! Он твой друг и помощник. (Как пользоваться git reset)
  • Визуальное объяснение Hard Reset и Soft Reset в Git
  • Как пометить определенный коммит тегом версии
  • Как в Git удалить файлы из индекса, не удаляя их в рабочей директории
  • Как настроить GIT, чтобы при конфликте слияния он прописывал в файл не только различия, но и «базу» этих различий
  • Git: Разрешение конфликтов объединений
  • Git: Извлечение старой версии файла
  • Git stash: временный отказ от проделанной работы
  • Git: проверка состояния репозитария, поддержание репозитария в рабочем состоянии
  • Как в Git отменить локальные изменения и получить новое состояние из удаленного репозитария
  • Как искать изменения в нужных файлах с помощью интерфейса gitk?
  • Как выбрать одну из версий бинарного файла при возникновнии конфликта слияния?
  • Как в Git посмотреть старый коммит, а потом вернуться обатно к самому последнему коммиту
  • Получение хеша последнего коммита и его даты в Git (для версионирования)
  • Памятка по неочевидным деталям использования Git
  • Как синхронизировать форк на Github с основным репозитарием через веб-интерфейс
  • Как пользоваться GitHUb: форки, ветки, запросы на добавление кода
  • Как отменить (сбросить) еще не закоммиченные изменения в Git
  • Первоначальная настройка имени пользователя и Email в Git-проекте
  • Можно ли принимать изменения через git pull если не закоммичены изменения рабочей директории
  • Как посмотреть какие команды генерирует git gui
  • Как удалить файл в Git-репозитарии с изменением истории

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *