Смущен git checkout
Я новичок в мерзости и пытаюсь обернуть голову вокруг работы веток. Согласно документации Git Checkout
Обновляет файлы в рабочем дереве в соответствии с версией в индексе или указанным деревом. Если> пути не заданы, git checkout также обновит HEAD, чтобы установить указанную ветвь в качестве> текущей ветки.
Поэтому, насколько я понимаю, файлы в моем каталоге, в котором я работаю (файл, в котором я выполнял git init), должны меняться в зависимости от того, в какой ветке я нахожусь. Я запутался, потому что этого не происходит, когда я меняюсь между ветвями. Изменения, над которыми я работал до того, как переключил ветви, присутствуют в той ветви, на которую я переключился. Я делаю что-то не так или Git Checkout не работает таким образом, и я просто неправильно понимаю документы?
2 ответа
У Git есть общая проблема - собрать в одну команду восемь или десять разных вещей.
git checkout
может обновить рабочее дерево, и обычно делает.
Это может измениться где HEAD
указывает, а иногда и делает, иногда нет.
Он может перезаписать работу, которую вы сделали с файлом, в случае, если вы хотите сбросить файл и отменить свою работу. Или он может отказаться от перезаписи выполненной вами работы с файлом, оставив его неизменным при изменении HEAD
или не меняется HEAD
,
Суть всего этого в том, что, хотя это удивительно сложно описать, на самом деле все это имеет смысл, и через некоторое время вы привыкаете к этому и обнаруживаете, что одна команда выполняет то, что вы имеете в виду, большую часть времени. (Конечно, это "большая часть времени" может быть проблемой...)
В любом случае, конкретное поведение, которое вы видите, является преднамеренной. Допустим, вы начинаете на ветке master
, как это делают большинство репозиториев:
$ git clone ...
$ git branch
* master
$
В этот момент вы можете отредактировать некоторые файлы, приступить к работе и только потом понять: "Гах! Я хотел сделать это на ветке develop
! "1
Git позволяет вам в этот момент переключаться на (или создавать) ветку develop
, сохраняя ваши модификации, при одном условии: переход на develop
не требует их уничтожения. Допустим, вы изменили файл f1
и создал новый f2
, и теперь вы хотите создать и проверить локальное отделение develop
который должен начинаться, и автоматически "отслеживать",2 origin/develop
:
$ git checkout develop
(в очень старых версиях GIT, вы должны записать это git checkout -b develop --track origin/develop
).
Давайте также скажем, что файл f1
то же самое на кончиках филиала master
и филиал develop
,3 Для git это означает, что он может делать эту проверку, потому что он не должен изменять файл f1
так что он может оставить ваши существующие изменения в f1
на месте.
Если файл f2
также одинаково в обоих коммитах, или (как в этом случае) не существует ни в одном из них, тогда файлы не будут засорены, и git checkout
создаст ваше новое местное отделение develop
, модифицируя рабочее дерево для соответствия origin/develop
по мере необходимости - и это не включает в себя изменение f1
ни удаление f2
так что работа, которую вы проделали до сих пор, остается нетронутой.
Это позволяет вам зафиксировать ваши новые изменения в вашем локальном develop
,
(Если вы сталкиваетесь со случаями, когда git действительно должен отменить ваши изменения, но все же хотите "переместить" их в другую ветку, обычным трюком является использование git stash
скрипт. Это звучит как простая вещь, и git stash
часто прост в использовании, но на самом деле это довольно сложный маленький зверь под одеялом. Не беспокойтесь об этом, пока вам это не понадобится.)
1 Это происходит со мной все время. Много раз я хотел создать новую не отслеживающую ветку, которая немного проще, чем переключение на существующую ветку, но принцип все еще применяется.
2 Это автоматическое отслеживание позволяет вам легче вносить изменения, сделанные другими людьми: как только git заберет их git fetch
, Git сообщит вам об изменениях других людей, и позволит вам использовать git merge
или же git rebase
объединить ваши изменения с их изменениями, без лишних раздумий, чтобы выяснить, чьи изменения идут куда.
3 Поскольку вы новичок в git, такие понятия, как различение "кончика ветви", который является конкретным коммитом, от "ветви", которая на самом деле неоднозначна - есть метки ветвей, а затем есть структуры ветвей, образованные дерево коммитов - это то, что вы обычно должны игнорировать некоторое время. Главное, что нужно отметить, это то, что в репозитории git есть специальный файл с именем HEAD
и в этом специальном файле git записывает строку ref: refs/heads/master
или же ref: refs/heads/develop
, чтобы отслеживать, на какой ветке вы находитесь. Так git checkout X
напишет ref: refs/heads/X
в HEAD
как только он переключается на филиал X
,
Между тем, другой набор специальных файлов в хранилище сообщает git, что ветка master
относится к одному из тех больших уродливых SHA-1, как c06f8d11b75e28328cdc809397eddd768ebeb533
, Это "верхушка" ветки master
, Когда вы делаете новый коммит на master
git создает новый коммит "один за старым советом", затем записывает новый SHA-1 в файлы веток, так что master
теперь ваш новый коммит.
Точные детали не так важны, как идея, что новые коммиты просто продвигают подсказку.
Эта путаница признана Git 2.23.
Git 2.23 (3 квартал 2019 г.) заменитgit checkout
с двумя новыми командами:
git switch
git restore
( показано здесь)
См совершают 97ed685, совершает d16dc42, совершает bcba406 (20 июн 2019), совершает 4e43b7f, совершает 1235875, совершают 80f537f, совершает fc991b4, совершает 75f4c7c, совершают 4df3ec6, совершает 2f0896e, совершает a5e5f39, совершает 3a733ce, совершает e3ddd3b, совершает 183fb44, совершает 4058199, зафиксировать a6cfb9b, зафиксировать be8ed50, зафиксировать c9c935f, зафиксировать 46e91b6 (25 апреля 2019 г.) и commit 328c6cb (29 марта 2019 г.), автор: Nguyễn Thái Ngọc Duy (pclouds
).
(Слияние Junio C Hamano -gitster
- в коммите f496b06, 09 июл 2019)
checkout
: разделить часть на новую команду 'switch
'"
git checkout
"выполнение слишком большого количества действий является источником путаницы для многих пользователей (и иногда это даже кусает старожилов).
Чтобы исправить это, команда будет разделена на две новые: переключение и восстановление. Старая добрая".git checkout
"команда все еще здесь и будет, пока она всем (или большинству пользователей) не надоест.
А также:
переключатель: отклонить, если выполняется какая-то операция
Если вы не знаете, что делаете, переключение на другую ветку, чтобы что-то сделать, с последующим переключением назад может сбивать с толку. Хуже того, вы можете даже забыть, что занимаетесь чем-то. К тому времени, когда вы это поймете, вы, возможно, уже проделали тонну работы, и вернуться к ней станет труднее.
Новый вариант
--ignore-in-progress
был рассмотрен, но отклонен, потому что не совсем ясно, что должно произойти.
Иногда можно переключиться, безопасно вернуться и продолжить работу. Иногда нет.
Иgit-checkout
поведение автоматически очищается merge / revert / cherry-pick, что делает его еще более запутанным.
См. Это обсуждение.Мы можем пересмотреть и добавить эту опцию в будущем.
Но пока перестрахуйтесь и не допускайте этого (вы даже не можете пропустить эту проверку с помощью--force
).
Пользователю предлагается отменить операцию самостоятельно (и, надеюсь, они учтут последствия, а не вслепую набирают команду) или создать отдельное рабочее дерево вместо переключения.Третий вариант - старый добрый "
git checkout
", но об этом не упоминается.
Видеть git switch
страница руководства
ОПИСАНИЕ
Переключиться на указанную ветку.
Рабочее дерево и индекс обновляются в соответствии с веткой.
Все новые коммиты будут добавляться в верхушку этой ветки.При желании новую ветку можно создать с помощью
-c
,-C
, автоматически из удаленной одноименной ветки (см.--guess
) или отсоедините рабочее дерево от любой ветви с помощью--detach
, вместе с переключением.Для переключения ветвей не требуется чистый индекс и рабочее дерево (т.е. никаких различий по сравнению с
HEAD
).
Однако операция прерывается, если операция приводит к потере локальных изменений, если иное не указано в--discard-changes
или--merge
.
ПРИМЕРЫ
Следующая команда переключается на "
master
" ветвь:$ git switch master
После работы в неправильной ветке переключение на правильную ветку будет выполнено с помощью:
$ git switch mytopic
Однако ваша "неправильная" ветка и правильная "
mytopic
"ветвь может отличаться в файлах, которые вы изменили локально, и в этом случае вышеуказанный переключатель выйдет из строя следующим образом:$ git switch mytopic error: You have local changes to 'frotz'; not switching branches.
Вы можете дать
-m
флаг к команде, которая попытается выполнить трехстороннее слияние:$ git switch -m mytopic Auto-merging frotz
После этого трехстороннего слияния локальные модификации не регистрируются в вашем индексном файле, поэтому
git diff
покажет вам, какие изменения вы внесли с момента открытия новой ветки.Чтобы вернуться к предыдущей ветке до того, как мы перешли на
mytopic
(т.е. "master
" ветвь):$ git switch -
Вы можете вырастить новую ветку из любого коммита.
Например, переключитесь на "HEAD~3
"и создать ветку"fixup
":$ git switch -c fixup HEAD~3 Switched to a new branch 'fixup'
Если вы хотите создать новую ветку из удаленной ветки с тем же именем:
$ git switch new-topic Branch 'new-topic' set up to track remote branch 'new-topic' from 'origin' Switched to a new branch 'new-topic'
Чтобы проверить фиксацию
HEAD~3
для временной проверки или эксперимента без создания новой ветки:$ git switch --detach HEAD~3 HEAD is now at 9fc9555312 Merge branch 'cc/shared-index-permbits'
Если окажется, что все, что вы сделали, стоит сохранить, вы всегда можете создать для него новое имя (не переключаясь):
$ git switch -c good-surprises
Обратите внимание на сообщения об ошибках, которые "git switch
"упоминает о возможности создания новой ветки",-b/-B
"варианты были показаны, где"-c/-C
должны быть, что было исправлено в Git 2.27 (второй квартал 2020 г.).
См. Commit 7c16ef7 (30 апреля 2020 г.) Дентон Лю (Denton-L
).
(Слияние Junio C Hamano -gitster
- в коммите f4675f3, 08 мая 2020 г.)
switch
: исправить ошибки и комментарии, связанные с -c и -CАвтор отчета: Роберт Симпсон
Подписано: Дентон Лю
Рецензент: Тейлор БлауВ d787d311db ("
checkout
: разделить его часть на новую команду 'switch'", 2019-03-29, Git v2.23.0-rc0 - слияние указано в пакете №4),git switch
команда была создана путем извлечения общих функцийcmd_checkout()
вcheckout_main()
.Однако в b7b5fce270 ("
switch
: лучшие имена для-b
а также-B
", 2019-03-29, Git v2.23.0-rc0 - слияние указано в пакете №4), параметры создания ветки и принудительного создания для 'switch
'были изменены на-c
а также-C
соответственно.В результате этого сообщения об ошибках и комментарии, которые ранее упоминались
-b
а также-B
стал недействительным дляgit switch
.Сообщения об ошибках, относящиеся к
-b
а также-B
используйте вместо этого строку формата, чтобы-c
а также-C
можно распечатать, когдаgit switch
вызывается.
Когда вы создаете ветку, эта ветка автоматически получит файлы той ветки, в которой вы находились, когда создавали эту новую ветку.
Допустим, вы находитесь в основной ветке и хотите создать ветку "разработка"
Все вместе должно выглядеть так:
** git checkout -b development // создаем и переключаемся на разработку ветки
touch text.txt // создаем документ text.txt
мерзавец добавить. // добавляем text.txt
git commit -m "добавление text.txt"
мастер проверки
И тогда вы не увидите text.txt, так как вы в Мастер