git checkout <branch>или <commit> - PullRequest
       3

git checkout <branch>или <commit>

0 голосов
/ 15 декабря 2018

Есть ли способ получить и проверить предоставленный аргумент, не заботясь, является ли это именем ветви или хешем коммита?

git fetch
git checkout origin/<branch> or origin/<commit>

как?git checkout origin/<commit> говорит, что такой ветки нет.Простой git checkout <argument> невозможен, потому что он не проверяет удаленную ветвь, как git checkout origin/<argument>.

Ответы [ 3 ]

0 голосов
/ 15 декабря 2018

Предпосылка вашего вопроса неверна:

Простое git checkout <argument> невозможно, потому что оно не проверяет удаленную ветвь так, как git checkout origin/<argument>.

Здесь важно понять несколько взаимосвязанных вещей о Git:

  1. Всегда есть - ну, почти всегда - текущий коммит, который вы можете использовать как слово HEADfind.
  2. Не всегда существует текущая ветвь, но если она есть, это имя ветки , то есть ссылка, полное имя которой имеет вид refs/heads/<em>name</em>.Одно и то же слово - HEAD, заглавными буквами, находит название этой ветви.Если не является текущим именем ветви, Git называет это отсоединенным HEAD .
  3. A именем удаленного отслеживания , таким как origin/master, это не имя ветви .Его полная форма начинается с refs/remotes/, а не refs/heads/.
  4. Если вы скажете git checkout проверить коммит, но идентифицируете его чем-то отличным от branch name, Gitбудет - если проверка прошла успешно, то есть - создаст состояние detached HEAD , описанное в пункте 2. (Вы можете также создать это же состояние с именем ветви, используя git checkout --detach.)

Следствием пункта 4 выше является то, что git checkout origin/<em>name</em> приводит к отсоединению HEAD, так же, как git checkout <em>hash-ID</em>.

Это означает, что ваш скрипт может просто использовать git checkout <argument>, так как он будетсделайте то же самое - создайте отдельный HEAD - если аргумент является идентификатором хэша или если это имя удаленного отслеживания, например origin/develop.

Обратите внимание, однако, что если мы изменим этот оператор на чтение:

Простой git checkout <argument> не подходит, поскольку он не будет сначала создавать, а затем извлекать локальную ветвь на основе существующего имени удаленного отслеживания, как git checkout <argument minus the leading origin/ part>.

мы получаем истинное утверждение: git checkout develop будет создать новая (локальная) ветка с именем develop с именем origin/develop (при условии, конечно, что локальная develop еще не существует).Тем не менее, нет очевидной проблемы с простым разрешением <argument> здесь и предоставлением пользователю develop в качестве имени:

#! /bin/sh
git fetch && git checkout "$@"

, например.

Примечания

Здесь есть интересное следствие пунктов 1 и 2, а именно: каково значение HEAD на данный момент действительно задает один из двух разных вопросов:

  • HEAD подключен к ветке?Если да, то какая ветвь?
  • Каков хэш-идентификатор текущего коммита?

Команда git symbolic-ref HEAD отвечает только на первый вопрос;git rev-parse HEAD в основном отвечает на второй вопрос, но можно сказать, что он отвечает и на первый тоже / вместо этого.


В пункте 1 выше почти существует по определенной причине.Представьте, что вы только что создали новый, абсолютно пустой репозиторий. В этом репозитории нет коммитов , так какой коммит является текущим коммитом?

Эта ситуация проблематична для Git.Вы находитесь на ветке, а именно master, которой не существует .Git называет это сиротская ветвь или ветвь, которую еще предстоит создать (в зависимости от того, какая часть Git выполняет вызов).Git обрабатывает это, чтобы сохранить имя ветки в .git/HEAD без фактического создания самой ветки в справочной базе данных.Когда вы делаете новый коммит, это создает саму ветвь, и теперь проблема решена: вы находитесь на ветке, которая идентифицирует только что сделанный новый коммит, который является текущим коммитом, поэтому HEAD называет как текущий коммит , так и текущую ветвь.

(Git может воссоздать эту слегка проблемную ситуацию по требованию, используя git checkout --orphan, который записывает имя новой ветки в HEAD без создания новой ветви.)

0 голосов
/ 19 декабря 2018

Этот аккуратный трюк, кажется, делает то, что я хочу:

git show-ref --head --sha | grep -q ^argument

Его код выхода будет равен 0, если аргумент является хэшем коммита, 1 в противном случае.Взято отсюда https://stackoverflow.com/a/29707340/3116571

0 голосов
/ 15 декабря 2018

Вы можете сначала получить все удаленные ветви (автоматически включая ту, которая имеет желаемый коммит) в вашу локальную сеть:

git fetch -a

, а затем простоизвлеките коммит по его хешу:

git checkout <commit-hash>

Сначала необходимо fetch, так как в противном случае ваш локальный пользователь может знать или не знать о хеше коммитов на удаленном компьютере.Без fetch, если бы вы непосредственно выполняли checkout, он жаловался бы на то, что хеш коммитов недействителен.

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