Затем я заметил, что я все еще могу оформить все другие ветки в репо, которых я никогда не трогал ...
Для правильного, тщательного ответа нам нужно отметитьдве вещи:
git checkout
можно проверить ветку. Здесь нет ничего удивительного (ну, пока нет). Когда вы делаете это, Git проверяет ветку. Это включает в себя проверку одного конкретного коммита, а также включение вас в «ветку», так что git status
говорит, например, on branch master
.
git checkout
может также проверьте вещи, которые являются не ветвями. Например, когда вы используете git checkout v2.1
(где v2.1
- имя тега), Git извлекает один конкретный коммит и вызывает, что отсоединенный HEAD .
Когда вы находитесь вВ этом отдельном режиме HEAD вы не находитесь на любой ветви. Как мы увидим через мгновение, эта отдельная вещь HEAD также применяется к другим элементам, не относящимся к имени ветви, включая имена для удаленного отслеживания , такие как origin/master
.
Здесь нам действительно нужно хорошее, четкое определение слова branch . К сожалению, в Git существует несколько противоречивых определений, в зависимости от того, как вам нравится использовать слово. (Подробнее об этом см. Что именно мы подразумеваем под «ветвью»? )
Значение, которое мы используем в пункте 1 выше, это имя ветки , который некоторые люди называют местным филиалом . Это такие имена, как master
или develop
(против origin/master
и origin/develop
). Имя ветки, подобное этим двум, которые на самом деле являются просто сокращением для более длинной формы, refs/heads/master
и refs/heads/develop
здесь, имеет два важных свойства:
- содержит идентификатор хеша одного коммита и
- Git будет автоматически обновлять хеш-идентификатор, сохраненный в этом имени при различных условиях. В частности, когда вы делаете новый коммит, находясь "на" одной из ваших веток, Git сохраняет хэш-идентификатор нового коммита в имени ветви.
Эти имена веток существуют в вашем хранилище и совершенно не зависят от имен ветвей, которые могут или не могут существовать в любом другом хранилище.
Имена, такие как origin/master
и origin/develop
, не совсем ветка имен, хотя некоторые люди любят называть их именами ветвей. 1 (Именно здесь довольно шаткие определения, используемые пользователями Git и Git, вызывают проблемы.) Они подчиняются первому правилу - они указывают наодин конкретный коммит, но не второй. 2 Вы можете запустить git checkout origin/master
, но, как и в случае с тегом v2.1
, вы получите отсоединенную головку. Вы не находитесь на любой ветви.
Так что этот может быть полным ответом:
git checkout <em>branch</em>
проверяет (локальная) ветка, которая у вас уже есть, и git checkout <em>remote-tracking-name</em>
проверяет коммит, идентифицируемый именем удаленного отслеживания.
Но это не весь ответ, потому что git checkout
можете создать ветвь для вас. 3 Предположим, что у вас нет локальной ветви с именем develop
, но do естьимя для удаленного отслеживания origin/develop
. Выполнение:
git checkout develop
обычно будет успешным и будет работать сначала , создающим a (локальный) develop
с использованием origin/develop
для установки как восходящего, так и текущего хеш-идентификатора фиксации. 4 То есть Git сначала будет искать имя существующей ветви develop
. Если это существует, Git (попытается 5 ) проверит эту ветку и будет сделано. Но если не , а не сразу потерпеть неудачу, Git будет искать, если у вас есть имя для удаленного отслеживания , которое выглядит аналогично, например origin/develop
. Если это так, checkout использует то, что Git называет DWIM - «Что я имею в виду», чтобы превратить это в git checkout -b develop origin/develop
.
Итак, к двум приведенным выше мы должны добавить:
git checkout <em>name-that-does-not-yet-exist</em>
, если сможет,
создаст ветвь и проверит ее. Функция «DWIM» находит имя удаленного отслеживания для использования в качестве руководства, создает ветвь и проверяет ее.
1 Обратите внимание, что имена для удаленного отслеживания origin/master
и origin/develop
также являются сокращенными формами для refs/remotes/origin/master
и refs/remotes/origin/develop
соответственно. Если вы когда-нибудь случайно создадите локальную ветку с именем origin/X
, ее полное имя будет refs/heads/origin/X
, и именно это делает ее локальной ветвью. Вы должны переименовать или удалить его быстро, хотя, потому что Git сократит его до origin/X
, и это может сбить вас с толку, особенно если у вас также есть refs/remotes/origin/X
, который Git также сократит до origin/X
.
2 Git обновляет имена удаленного слежения, но делает это при запуске git fetch
. Ваш Git вызывает другой Git - например, в origin
и спрашивает , что Git, который фиксирует каждое из его имен ветвей, master
и develop
в этом случае идентифицирует. Ваш Git затем получает эти коммиты, если это необходимо. Если у вас уже есть эти коммиты, ваш Git пропустит этот шаг. Затем, когда коммиты доступны локально в вашем репозитории, ваш Git теперь создает или обновляет ваши имена для удаленного отслеживания, соответствующие именам веток в другом Git.
Поскольку вы не можете быть"on" имя удаленного слежения, обновление этих имен в git fetch
время безопасно.
3 На самом деле, в нем много режимов создания веток, использующих git checkout -b
, git checkout -B
, git checkout --track
и т. Д. Но здесь мы смотрим только на то, что Git называет «DWIM».
4 Часть этого настраивается. Приведенное здесь описание охватывает только действия по умолчанию, чтобы этот ответ не был еще длиннее.
5 git checkout
иногда приводит к ошибке с ошибкой, и в этом случае он должен был оставить все в покое,Сообщение об ошибке предназначено, чтобы сообщить вам, почему оно ничего не сделало.
Заключение
Помимо проверки локальной ветки обычным способом, есть два способачто вы можете git checkout
«удаленные ветви» - что бы вы ни имели в виду под «удаленными ветвями» - потому что вы можете использовать режим отключенного HEAD для проверки и, таким образом, проверить, origin/foo
, или вы можете использовать режим DWIM для созданияlocal foo
используя origin/foo
, и проверьте это как локальную ветвь обычным способом.
Если вы do используете режим DWIM, вы накапливаете кучу новых локальных ветвей. Как только вы это сделаете, это ваши имена филиалов. Они не будут автоматически обновляться, когда что-то случится в other Git! Они будут обновляться только тогда, когда вы их включите и будете делать что-то, что их обновит.