|
|||||||
Git: как переключиться на нужный коммит? Понимание, что такое ветка
Время создания: 22.06.2014 15:41
Автор: Xintrea
Текстовые метки: git, commit, коммит, checkout, переключиться, перейти, вернуться, head, ошибка, ветка, понимание, объяснение
Раздел: Компьютер - Программирование - Системы контроля версий (VCS) - Git
Запись: xintrea/mytetra_syncro/master/base/1403437294hkfzh1wflf/text.html на raw.github.com
|
|||||||
|
|||||||
Как переключиться на нужный коммит? Для переключения на нужный коммит используется действие checkout. После переключения, все файлы в проекте станут такими, какими они были в данном коммите. git checkout commit Где commit - это хеш (обозначение, имя) коммита, причем можно указывать не весь хеш, а несколько начальных символов хеша. Примечание: переключение на интересующий пользователя коммит всегда будет приводить репозитарий в состояние detached HEAD. Это нормально, не стоит этого бояться. Нахождение в состоянии "detached HEAD" можно проверить командой git status: $ git checkout 3c53ec44 ... $ git status HEAD отделён на 3c53ec44 Состояние "detached HEAD" означает, что текущий рабочий указатель не находится ни на какой ветке. Но как же так? Ведь коммит всегда принадлежит какой-то ветке! Это можно увидеть в том же gitk... А разгадка в том, что коммиты в Git - это, конечно, "снимки состояния репозитария, которые связаны между собой, образуя цепочки". Но нужно понимать, что цепочки коммитов в Git не считаются ветками! Вот это поворот! Как работают ветки в Git? Веткой в Git называется указатель на коммит, и этому указателю задано определенное имя. Если такой указатель указывает на последний коммит в цепочке, то в момент добавления нового коммита (у которого текущий является родителем) этот именованный указатель автоматически "переместится": то есть он начнет указывать на новый коммит. А имя указателя останется, естественно, без изменений. Таким образом, создается иллюзия, что программист работает в именованной ветке, и при добавлении коммитов ветка прирастает новыми коммитами. Хотя, на деле, система Git оперирует не ветками, а именно указателями на коммиты, не более того. Нужно запомнить: никаких веток, в естественном человеческом понимании, в Git нет. Вышеуказанные размышления можно продемонстрировать и по-другому. Нахождение в состоянии "detached HEAD" можно проверить командой git branch: $ git branch * (HEAD отделён на 3c53ec44) control_panel master new_engine Здесь видно, что пользователь переключился на какой-то коммит. Но не видно на какой ветке находится пользователь, и, тем более, не видно на какой ветке он находился ранее. (Перед переключением, в gitk, было видно, что коммит 3c53ec44 находится в ветке control_panel, но не является в ней последним). А так как коммит не самый последний в ветке, то после переключения рабочий указатель не начинает указывать ни на какую ветку (то есть рабочий указатель не совпадает с каким-либо именованным указателем, находящимся на конце какой-либо ветки). А такое состояние, на первый взгляд, и считается "detached HEAD". Но тогда возникает вопрос: а что произойдет, если с помощью хеша коммита переключиться на коммит, который является последним в какой-нибудь цепочке, и в gitk видно, что на данном коммите завершается ветка control_panel? Поймет ли Git, что произошло переключение на коммит, на который указывает именованный указатель с именем control_panel? То есть, поймет ли Git, что происходит переключение на ветку control_panel? Следующие команды показывают, что произошло переключение на коммит, на который так же указывает указатель ветки control_panel. И видно, что хеш коммита (на который переключились) 4c171d82 и хеш ветки 4c171d82 - совпадают. Но состояние "detached HEAD" все равно возникло: $ git checkout 4c171d82 $ git branch -v * (HEAD отделён на 4c171d82) 4c171d82 Manager и регулятор громкости control_panel 4c171d82 Manager и регулятор громкости master c4bfddfd ALS перенесен в разел коммутаторов new_engine b9bcf376 Merge branch 'new_engine' of ... То есть, даже если пользователь переключился на конечный коммит какой-либо ветки, состояние считается все равно как "detached HEAD". Надо разобраться почему так происходит. А дело вот в чем. В Git есть два указателя:
Так вот, надо знать что:
Если WT-указатель и HEAD-указатель не совпадают, такое состояние и называется "detached HEAD". А когда они совпадают - значит можно нормально работать. Причем работа будет проиcходить в ветке, имя которой соответствует именованному указателю на коммит, на который так же указывает HEAD. Важно для понимания: возможно ли в Git ветвление без веток? Да, если над проектом работает несколько человек, или если один человек работает над проектом из разных локаций (на работе, дома, в дороге), или при различных комбинациях такой организации работы. Во всех этих случаях, даже в пределах одной ветки, могут образовываться различные ветвления. Например, если человек делал несколько коммитов, находясь в дороге (и у него небыло интернета), то после того как интернет появится, эти коммиты заливаются на сервер, и они видны как одна цепочка коммитов. А другая цепочка коммитов, которые делались другими сотрудниками в этой ветке, пока человек был в дороге, будет тоже видна в этой же ветке. И выглядеть эти две цепочки будут в логе как две цепочки, которые разветвились в момент, когда человек поехал в командировку. И самое главное, что эти две цепочки не являются отдельными ветками. Это просто цепочки коммитов, различным образом разветвляющиеся и сливающиеся. Дописать... А как вернуться обратно после просмотра коммита? Ответ. Команда: git checkout - (да, в конце команды ставится символ тире "-") ... вернет состояние репозитария в ту точку, где пользователь Git был до перехода. Даже если переход производился на коммит в другой ветке, возврат будет происходить с перепрыгиванием на ту ветку, где пользователь находился изначально. Примечание: по-сути, данная команда просмативает историю перемещений пользователя по коммитам. Дописать. Показать команды просмотра истории перемещений. А как перейти в самое свежее состояние? Дописать. Свежее состояние - внутри ветки? |
|||||||
Так же в этом разделе:
|
|||||||
|
|||||||
|