Как выбрать только текущую ветку - PullRequest
1 голос
/ 20 февраля 2020

Я хочу выбрать только текущую ветвь:

git fetch origin HEAD

, но как определить удаленный по умолчанию?

git fetch DEFAULT_REMOTE HEAD

Я предполагаю, что HEAD является наиболее обобщенным c способ ссылки на текущую ветку, но мне также нужен универсальный c способ ссылки на пульт по умолчанию для текущей ветви?

Обратите внимание, что при этом:

git fetch HEAD

give мне эта проблема:

неустранимый: 'HEAD' не похоже на git хранилище

неустранимый: не удалось прочитать из удаленного хранилища.

Ответы [ 2 ]

1 голос
/ 20 февраля 2020

Я предполагаю, что HEAD - это наиболее общий c способ ссылки на текущую ветку ...

Да, это так. Хотя здесь есть ловушка, как мы увидим через мгновение.

, но мне также нужен универсальный c способ ссылки на пульт по умолчанию для текущей ветви?

Есть много способов сделать это, и у каждого есть свои возможные ловушки, но я думаю, что самое простое - использовать git config, чтобы прочитать обратно половину текущей настройки upstream текущей ветви.

Очевидным подводным камнем здесь является то, что текущая ветвь не может иметь восходящий поток.

Если у вас современный Git, git rev-parse может вернуть информацию о восходящем потоке любой ветви, включая текущую ветвь:

$ git rev-parse --symbolic-full-name HEAD
refs/heads/master
$ git rev-parse --symbolic-full-name HEAD@{u}
refs/remotes/origin/master

Здесь текущая ветвь равна master, а ее восходящая ветвь равна origin/master. Они используют полное написание каждого ссылки, что является хорошей идеей, если вы пишете сценарии, поскольку сокращенные имена (master и origin/master) могут неправильно анализироваться: например, master может превратиться в refs/tags/master , если кто-то создал тег с именем master.

Восходящий поток, если таковой имеется - git branch --unset-upstream master будет удалять восходящий поток, например, для master - устанавливается как две части:

$ git config --get branch.master.remote
origin
$ git config --get branch.master.merge
refs/heads/master

Параметр branch.master.remote - это именно то, что вам нужно: имя пульта или, в данном случае, origin. Поэтому, если вы впервые найдете текущее имя ветви :

$ git symbolic-ref --short HEAD
master

, вы можете использовать его для получения соответствующего удаленного имени:

branch=$(git symbolic-ref --short HEAD) || die ...
remote=$(git config --get branch.$branch.remote) || die ...

Теперь вы можете запустить:

$ git fetch $remote HEAD

Но теперь мы попали в первую ловушку, которую я упомянул:

remote: Enumerating objects: 928, done.
remote: Counting objects: 100% (928/928), done.
remote: Compressing objects: 100% (401/401), done.
remote: Total 928 (delta 601), reused 809 (delta 526)
Receiving objects: 100% (928/928), 843.84 KiB | 1.62 MiB/s, done.
Resolving deltas: 100% (601/601), completed with 74 local objects.
From [url]
 * branch                  HEAD       -> FETCH_HEAD

Обратите внимание, что, хотя у меня есть современный (я sh) Git здесь (2.24.0 ), Я не получил обновленный origin/master. Чтобы сделать это, я должен использовать вместо этого:

$ git fetch $remote $branch
From [url]
 * branch                  master     -> FETCH_HEAD
   c7a6207591..51ebf55b93  master     -> origin/master

На этот раз мой origin/master был обновлен соответствующим образом.

Редактировать: Я не упомянул об этом изначально, но мы можем видеть здесь, что мои Git попросили их Git для их HEAD. Их HEAD это их master; будь я в какой-то другой ветке, я бы все равно получил их HEAD, то есть их master, в моем .git/FETCH_HEAD. Так что это не просто косметика c: вы должны указать здесь свое Git название ветви, а не символ c имя HEAD. Сравните с git push, где вы можете безопасно использовать HEAD для вашей стороны, потому что с git push ваш Git, а не их, разрешает символ c имя HEAD на имя ветви.

Заключение и еще один подводный камень

Сначала вы должны получить текущее имя ветви. Помните, что это может не сработать: может не быть текущего имени ветви. Затем используйте git config --get, чтобы получить remote часть восходящей настройки. (Оставшаяся часть требует сопоставления с помощью сопоставления по умолчанию для удаленного извлечения refspe c, но нам это не нужно - git fetch справится с этим - так что вообще не беспокойтесь о наборе branch.$branch.merge.)

Последняя ошибка, о которой стоит упомянуть, это: в приведенном выше примере кода используется git config --get ... || die ..., где die - это (предположительно) функция оболочки для полного выхода из сценария. Однако, если у нет установлен восходящий поток для текущей ветви, git fetch сама не будет выходить из этой точки. Он будет просто использовать жестко закодированное имя origin. Таким образом, в зависимости от того, насколько рабски вы хотите имитировать raw git fetch, вы можете захотеть:

remote=$(git config --get branch.$branch.remote) || remote=origin

. Поскольку вы пишете сценарий, вы можете контролировать край и ошибки здесь.

1 голос
/ 20 февраля 2020

Ответ

git fetch origin $(git rev-parse --abbrev-ref HEAD)

С Generi c Пульт

git fetch $(git config --local branch.$(git rev-parse --abbrev-ref HEAD).remote) $(git rev-parse --abbrev-ref HEAD)

Объяснение

Согласно документы , которые вы можете выдать git получить из указанного c refspe c.

Используя следующий формат git fetch, вы можете попросить указать c ref: git fetch [<options>] [<repository> [<refspec>…​]]

Указывает, какие ссылки получать и какие локальные ссылки обновлять.

Эта подоболочка $(git rev-parse --abbrev-ref HEAD) взята из этого ответа .

Другой, который я написал сам, и следующий $(git config --local branch.$(git rev-parse --abbrev-ref HEAD).remote), он использует первый для увеличения обобщения, но он возвращает имя удаленного, связанного с веткой, в вашей локальной конфигурации , следуя этой схеме git config --local branch.<branch_name>.remote.

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