Нет единственной команды Git, которая будет делать это.
Рекомендованная последовательность команд:
git checkout <name>
, затем , если не удалось:
git checkout -b <name> [<starting-point>]
или (в зависимости от того, какое поведение вы хотите):
git checkout [-b <name>] --track <remote-tracking-name>
, где каждый элемент в угловых скобках представляет что-то, что вы заменяете (например, <name>
может быть feature/fast
), а каждый элемент в квадратных скобках представляет собой что-то необязательное.
Основная проблема здесь такова:
Если вы создаете новое имя ветви , вы должны выбрать, какой коммит будет определять это новое имя ветви. Вы выбираете конкретную отправную точку, предоставляя аргумент <starting-point>
; если вы не в состоянии назвать начальную точку, Git будет считать, что вы хотите HEAD
в качестве начальной точки.
Вы можете также выбрать, должна ли новая ветвь иметь восходящий набор: для этого --track
. Однако обратите внимание, что в некоторых случаях --track
подразумевается автоматически.
Если вы используете существующее имя ветки , вы - согласно вашему заявлению выше - не хотите изменять , который фиксирует его, будет идентифицировать. (В настоящее время у вас нет возможности установить / изменить восходящий канал для существующей ветви, так что конкретный вопрос выпадает из картинки.)
Давайте теперь затронем все побочные проблемы, которые здесь случаются.
С -b
, git checkout
всегда хочет создать новую ветку
Флаг -b
и / или --track
сообщает git checkout
, что он должен создать новую ветвь и затем переключиться на нее. Если переключение произойдет или произойдет сбой, он должен откатить всю операцию и, в конце концов, не создавать новую ветвь. Так что здесь является отправной точкой. Начальная точка может быть HEAD
. Поскольку ветвь new , она еще не имеет восходящего потока, но вы можете указать git checkout
to set upstream, используя --track
: аргумент --track
равен имя восходящего потока (которое должно быть либо именем локальной ветви, либо именем удаленного отслеживания, таким как origin/master
).
Если вы указываете флаг -b
, вы также указываете имя новой ветви, и, следовательно, это имя новой ветви. Если вы опустите флаг -b
, вы должны указать --track
и имя удаленного отслеживания: в этом случае имя ветви - это имя, полученное в результате удаления части удаленного отслеживания, например, origin/feature
становится feature
, поэтому git checkout --track origin/feature
означает то же самое, что и git checkout -b feature --track origin/feature
.
Если вы указали отправную точку, Git должен будет проверить этот конкретный коммит. Имя начальной точки может быть именем удаленного отслеживания (например, origin/master
или origin/feature
), или идентификатором хэша коммита, или любым другим, идентифицирующим коммит. В большинстве случаев предоставление имени для удаленного отслеживания в качестве отправной точки эквивалентно предоставлению также аргумента --track
, поэтому, если вы не хотите установить восходящий поток, добавьте --no-track
. См. git checkout
документацию для полного описания.
Без -b
, git checkout
все еще иногда создает новую ветвь
Когда вы пропустите -b
, git checkout <em>name</em>
будет сначала проверять, соответствует ли name какой-либо существующей ветви. Если это так, то часть операции декодирования завершена: теперь Git пытается проверить этот конкретный коммит (идентифицированный этой веткой) и, если это удается, присоединяет ваш HEAD
к этой ветке, так что вы сейчас на ветке.
Но вы можете написать, например ::
git checkout feat/ure
когда у вас нет ветки с именем feat/ure
. В этом случае Git перечислит все ваши имена для удаленного отслеживания, такие как origin/master
, upstream/master
и т. Д. Если точно один соответствует feat/ure
после удаления удаленной части, Git предполагает, что вы имели в виду , чтобы написать:
git checkout --track origin/feat/ure
(или какое-либо другое имя с удаленным пультом).Следовательно, это создаст feat/ure
, указывая на такой же коммит как origin/feat/ure
, с origin/feat/ure
в качестве настройки восходящего потока для новой ветви feat/ure
.
Если feat/ure
не существует и либо нет, либо слишком много (два или более) имен стилей удаленного слежения feat/ure
- например, существуют и origin/feat/ure
, и upstream/feat/ure
- этот git checkout
будет простопотерпите неудачу, и теперь вы должны прибегнуть к одному или нескольким из -b
и / или --track
.
Другая альтернатива
Если вам не нравятся эти альтернативы, это можно проверить, существует ли имя ветви.Для этого попросите git rev-parse
перевести имя, вставив перед ним refs/heads/
:
git rev-parse --quiet --verify refs/heads/feat/ure
Если это удастся, он напечатает хэш-идентификатор, к которому разрешается refs/heads/feat/ure
, ивыходы с нулевым статусом.Напечатанный идентификатор хэша является кончиком ветви feat/ure
, которая поэтому существует.Если это не удается, он ничего не печатает (--quiet --verify
) и завершает работу с ненулевым статусом, поэтому feat/ure
не существует.Теперь вы можете спокойно попросить создать feat/ure
- то есть, при условии, что никто не проник в ваш репозиторий и не создал feat/ure
, пока вы просматривали состояние выхода и определяли, что feat/ure
не существует (но теперь существует).
В сценарии оболочки это становится:
name=feat/ure
git rev-parse --quiet --verify refs/heads/$name >/dev/null && exists=true || exists=false
if $exists; then git checkout $name; else git checkout -b $name ...additional arguments; fi
и, конечно, вы можете превратить этот сценарий в псевдоним оболочки или в настоящий сценарий оболочки, вызываяэто все что угодно.Добавьте достаточный разбор аргументов и обработку ошибок по вкусу.