Як перевірити, чи існує віддалене відділення в даному віддаленому сховищі?


106

Мені потрібно здійснити об'єднання піддірень для певної гілки, якщо вона існує в заданому віддаленому сховищі. Проблема полягає в тому, що віддалений сховище не перевіряється локально, тому я не можу його використовувати git branch -r. Я маю лише віддалену адресу, щось подібне https://github.com/project-name/project-name.git. Чи є спосіб перерахувати віддалені відділення лише за віддаленою адресою? Я нічого не міг знайти корисне :(

Відповіді:


124
$ git ls-remote --heads git@github.com:user/repo.git branch-name

Якщо branch-nameви знайдете, ви отримаєте такий результат:

b523c9000c4df1afbd8371324083fef218669108        refs/heads/branch-name

Інакше вихід не буде надісланий.

Тому трубопровід wcдасть вам 1або 0:

$ git ls-remote --heads git@github.com:user/repo.git branch-name | wc -l

Крім того, ви можете встановити --exit-codeпрапор, на git ls-remoteякому буде повернути код виходу, 2якщо не знайдеться відповідні реф. Це найбільш ідіоматичне рішення. Результат можна перевірити безпосередньо в тесті оболонки або перевіривши змінну стану $?.

$ git ls-remote --exit-code --heads  git@github.com:user/repo.git branch-name

7
Я використовував, git ls-remote --heads ${REPO} ${BRANCH} | grep ${BRANCH} >/dev/nullпісля чогоif [ "$?" == "1" ] ; then echo "Branch doesn't exist"; exit; fi
sibaz

1
Я шукав цю акуратну та точну відповідь кілька годин, блискучий.
medik

Вам потрібно вказати назву філії як /refs/heads/branch-name. В іншому випадку філія foo/branch-nameбуде повернута навіть тоді, коли її немає branch-name.
FuzzY

Вітаю із золотою значкою "Великий відповідь". :)
jmort253

4
Примітка. Якщо вам не потрібно вказувати URL-репо, ви можете замість цього вказати віддалене ім’я репо, наприклад:git ls-remote --heads origin branch-name
daveruinseverything

50
git ls-remote --heads https://github.com/rails/rails.git
5b3f7563ae1b4a7160fda7fe34240d40c5777dcd    refs/heads/1-2-stable
81d828a14c82b882e31612431a56f830bdc1076f    refs/heads/2-0-stable
b5d759fd2848146f7ee7a4c1b1a4be39e2f1a2bc    refs/heads/2-1-stable
c6cb5a5ab00ac9e857e5b2757d2bce6a5ad14b32    refs/heads/2-2-stable
e0774e47302a907319ed974ccf59b8b54d32bbde    refs/heads/2-3-stable
13ad87971cc16ebc5c286b484821e2cb0fc3e3b1    refs/heads/3-0-stable
3df6c73f9edb3a99f0d51d827ef13a439f31743a    refs/heads/3-1-stable
f4db3d72ea564c77d5a689b850751ce510500585    refs/heads/compressor
c5a809e29e9213102351def7e791c3a8a67d7371    refs/heads/deps_refactor
821e15e5f2d9ef2aa43918a16cbd00f40c221e95    refs/heads/encoding
8f57bf207ff4f28fa8da4544ebc573007b65439d    refs/heads/master
c796d695909c8632b4074b7af69a1ef46c68289a    refs/heads/sass-cleanup
afd7140b66e7cb32e1be58d9e44489e6bcbde0dc    refs/heads/serializers

Я також не знав про ls-remote. Дякую!
Кін

7
Мені потрібно було зробити тест на баш-скрипт, і тому мене дійсно цікавив код виходу, тому я зробив наступне в локальному клоні: git ls-remote --exit-code . origin/branch-name &> /dev/nullтоді використовувався $?як тестовий операнд
Даррен Бішоп

5
@Darren, просто використання команди безпосередньо в умовному режимі, як і у випадку if git ls-remote ...; then ...; fi, є менш схильним до помилок, ніж перевірка $?(що можна змінити шляхом реєстрації виписок, пасток тощо).
Чарльз Даффі

Чому --heads?
Стів

@JohnLinux --headsперераховує лише гілки. використовувати лише --tagsдля переліку тегів.
римо

19

Ще один спосіб, який ви можете використовувати в поточній папці, якщо це git repo для запуску

git branch -a | egrep 'remotes/origin/${YOUR_BRANCH_NAME}$'

2
Використовуйте подвійні цитати:git branch -a | egrep "remotes/origin/${YOUR_BRANCH_NAME}$"
Іван

3
Це не є оптимальним, тому що воно поверне справжнє, навіть якщо ви відповідали лише частині існуючої назви гілки, але не відповідали цільовій гілці. Тому це не можна безпечно використовувати в сценарії, щоб перевірити, чи існує гілка, перш ніж перевірити її. Дякуємо за те, що все-таки поділилися, оскільки я вважаю це корисним. Можна виправити так:git branch -a | grep "\b${BRANCH}$"
EntangledLoops

2
git fetchПотрібно, якщо ви користуєтеся git branch -aтаким чином, усі віддалені рефлекси отримують спочатку. Інше використання, git ls-remoteяк вказують інші.
hIpPy

git branch -a --list '<pattern>'також є варіантом. Якщо вам потрібен код повернення для вашого сценарію, виконайте це рішення.
ЗАНЯТТЯ

17

Ви також можете скористатися цим:

git show-branch remotes/origin/<<remote-branch-name>>

повертає останню комісію та вартість $? є 0, інакше повертається "фатально: погана посилання sha1 видаляє / походження / <>" та значення $? становить 128


Це не витягне гілки з віддаленого перед перевіркою, тому ви не отримаєте останнього віддаленого стану.
siemanko

11

Ви можете зробити щось подібне в терміналі Bash. Просто замініть відгомони командами, які ви хочете виконати.

if git ls-remote https://username:password@github.com/project-name/project-name.git | grep -sw "remote_branch_name" 2>&1>/dev/null; then echo "IT EXISTS..START MERGE" ; else echo "NOT FOUND" ; fi

Сподіваюся, це допомагає.


1
Мені це подобається. інші відповіді також мають ls-remote, що мені подобається - "якщо".
Кам’яний

11

Тоді не потрібно кожного разу вручну передавати ім’я сховища.

git ls-remote origin <branch>

Замість

git ls-remote <full repo url> <branch>

Приклад:

git ls-remote git@bitbucket.org:landmarkgroupme/in-store-application.git  uat_21dec

АБО

git ls-remote origin uat_21dec

Обидва дадуть однаковий вихід:

введіть тут опис зображення

Детальніше про Origin : Git має поняття "віддалені", які є просто URL-адресами до інших копій вашого сховища. Коли ви клонуєте інше сховище, Git автоматично створює віддалене ім’я "походження" і вказує на нього. Додаткову інформацію про пульт можна переглянути, ввівши git remote show origin.


11

Усі відповіді тут стосуються оболонки Linux, що не дуже допомагає, якщо ви знаходитесь в середовищі, яке не підтримує такі операції - наприклад, командний рядок Windows.

На щастя, git ls-remoteприймає --exit-codeаргумент, який повертає 0 або 2 залежно від того, існує гілка відповідно чи ні. Так:

git ls-remote --exit-code --heads origin <branch-that-exists-in-origin>

поверне 0, і

git ls-remote --exit-code --heads origin <branch-that-only-exists-locally>

повернеться 2.

Для PowerShell ви можете просто використовувати вбудовану семантику обробки правдивості:

if (git ls-remote --heads origin <branch-that-exists-in-origin>) { $true } else { $false }

врожайність $true, тоді як:

if (git ls-remote --heads origin <branch-that-only-exists-locally>) { $true } else { $false }

врожайність $false.


6
$ git ls-remote --heads origin <branch> | wc -l

працює більшу частину часу.

Але не вийде, якщо відділення збігається частково, як показано нижче,

$ git branch -a
creative/dev
qa/dev

$ git ls-remote --heads origin dev | wc -l
2

Використовуйте

git ls-remote --heads origin <branch> | \
    cut -d$'\t' -f2 | \
    sed 's,refs/heads/,,' | \
    grep ^<branch>$ | wc -l

якщо ви хочете надійного способу.

Якщо ви хочете використовувати в скрипті і не хочете вважати origin, що віддалений за замовчуванням, то

git ls-remote --heads $(git remote | head -1) "$branch" | \
    cut -d$'\t' -f2 | \
    sed 's,refs/heads/,,' | \
    grep ^"$branch"$ | wc -l

повинен працювати.

Зверніть увагу, що git branch -a | grep ...це не є надійним, оскільки це може пройти деякий час з часу fetchзапуску останнього .


Для мене це прийнята відповідь, поєднана з відповіддю від Амітеш (коротке віддалене ім’я), поєднаною з тією від Джеймса Кеша ( grep -x "$branch"тотожна grep ^"$branch"$). Хоча в сценаріях я віддаю перевагу довго-форма переходить: --line-regexp. Також робити це не потрібно wc -l. Поміщення порожнього виводу в Bash if [ -z ] ефективно оцінюється як істинне, так що це означає, що гілка не існує. Це економить кілька мілісекунд.
Амедей Ван Гассе

1

Ви можете додати сховище, яке ви маєте у віддаленому режимі, git remote add something https://github.com/project-name/project-name.gitа потім виконатиgit remote show something щоб отримати всю інформацію про віддалений. Для цього потрібне підключення до мережі та є корисним для людського використання.

Крім того, зробіть git fetch something. Це отримає всі гілки на віддаленому телефоніsomething та зберегти їх у вашому локальному сховищі. Потім ви можете об'єднати їх у свій місцевий відділення, як завгодно. Я рекомендую цей шлях , тому що якщо ви , нарешті , вирішити , що ви повинні зливатися це те , що вам потрібно зробити.

OT: Використання "перевірено локально" означає, що ви підходите до цього з точки зору централізованої системи управління версіями. Зазвичай це глухий кут, коли ти маєш справу з git. Він використовує такі слова, як "замовлення" тощо, інакше, ніж старі системи.


Дякуємо за пояснення. Я ще не звик до гетів, і це вимагає іншого способу мислення.
Кін

1

Ви можете спробувати

git diff --quiet @{u} @{0}

Тут @{u}посилається на віддалений / висхідний потік і @{0}посилається на поточний локальний HEAD (з новою версією git @{0}можна скоротити як @). Якщо віддаленого пристрою не існує, він виходить з помилки.

З git 2.16.2 (я не впевнений, яка версія першою має цю функціональність, наприклад, у git 1.7.1 її немає), ви можете це зробити

git checkout

Якщо існує віддалене відділення, з'явиться певний вихід, наприклад

Your branch is up to date with 'origin/master'

Інакше виходу немає.


1

Поверне всі гілки (віддалені або локальні), які містять запит у назві.

git branch --all | grep <query>


0

Якщо назви вашої гілки дуже конкретні, можливо, вам не знадобиться використовувати grep для простого узгодження імен гілок:

git ls-remote --heads $(git remote | head -1) "*${BRANCH_NAME}*" | \
    cut -d$'\t' -f2 | \
    sed 's,refs/heads/,,' | \
    wc -l

для якого працює

BRANCH=master
BRANCH=mas
BRANCH=NonExistingBranch (returns 0)
BRANCH=ISSUE-123

Ми використовуємо унікальний ідентифікатор випуску як назви філій, і він чудово працює.


0

Я просто спробував це:

git ls-remote --heads 2>/dev/null|awk -F 'refs/heads/' '{print $2}'|grep -x "your-branch"|wc -l

Це поверне 1, якщо буде знайдено гілку "ваша-філія", а 0 - в іншому випадку.


0

Я поєдную в сценарії деякі відповіді вище:

BRANCHES=(develop master 7.0 7.0-master)
ORIGIN=bitbucket
REMOTE=github

for BRANCH in "${BRANCHES[@]}"; do
  BRANCH=$(git ls-remote --heads "${ORIGIN}" "${BRANCH}" \
      | cut --delimiter=$'\t' --fields=2 \
      | sed 's,refs/heads/,,' \
      | grep --line-regexp "${BRANCH}")
  if [ -n "${BRANCH}" ]
  then
    git branch --force "${BRANCH}" "${ORIGIN}"/"${BRANCH}"
    git checkout "${BRANCH}"
    git push "${REMOTE}" "${BRANCH}"
  fi
done

git push github --tags

Цей скрипт отримає 4 гілки з віддаленого бітбукета, і пересуне їх до віддаленого github, а потім підштовхне всі теги до github. Я використовую це в роботі Дженкінса, тому ви не бачите жодного git fetchабоgit pull , що вже зроблено в конфігурації сховища Дженкінса.

Зазвичай я віддаю перевагу варіантам довгих форм у сценаріях. Я міг би поєднатись git branchі git checkoutза допомогою git checkout -B.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.