Belirli bir uzak depoda uzak dal olup olmadığı nasıl kontrol edilir?


106

Belirli bir uzak depoda mevcutsa, belirli bir dal için alt ağaç birleştirme yapmam gerekiyor. Sorun şu ki, uzak deponun yerel olarak kontrol edilmemesi, bu yüzden kullanamıyorum git branch -r. Sahip olduğum tek şey uzak bir adres, bunun gibi bir şey https://github.com/project-name/project-name.git. Uzak dalları yalnızca uzak bir adresle listelemenin bir yolu var mı? Yararlı bir şey bulamadım :(

Yanıtlar:


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

Bulunması durumunda branch-nameaşağıdaki çıktıyı alacaksınız:

b523c9000c4df1afbd8371324083fef218669108        refs/heads/branch-name

Aksi takdirde çıktı gönderilmez.

Öyleyse onu wcvermek size 1veya 0:

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

Alternatif olarak, eşleşen referansların bulunmaması durumunda çıkış kodunu döndürecek bir --exit-codebayrak ayarlayabilirsiniz . Bu en deyimsel çözümdür. Sonuç, doğrudan bir kabuk testinde veya durum değişkeninin kontrol edilmesiyle kontrol edilebilir .git ls-remote2$?

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

7
Ben kullanılan git ls-remote --heads ${REPO} ${BRANCH} | grep ${BRANCH} >/dev/nullizlediif [ "$?" == "1" ] ; then echo "Branch doesn't exist"; exit; fi
sibaz

1
Birkaç saat boyunca bu düzgün ve kesin cevabı arıyordum, harika.
medik

Şube adını olarak belirtmeniz gerekiyor /refs/heads/branch-name. Aksi takdirde şube foo/branch-nameolmasa bile şube iade edilir branch-name.
FuzzY

'Harika Yanıt' altın rozetiniz için tebrikler. :)
jmort253

4
Not: git ls-remote --heads origin branch-name
Depo

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

Is-remote'ı da bilmiyordum. Teşekkür ederim!
Keen

7
Bir bash betiğinde bir test yapmam gerekiyordu ve bu yüzden sadece çıkış koduyla gerçekten ilgileniyordum, bu yüzden yerel bir klonda aşağıdakileri yaptım: git ls-remote --exit-code . origin/branch-name &> /dev/nulldaha sonra $?test operatörü olarak kullanıldı
Darren Bishop

5
@Darren, sadece bir koşulda doğrudan komutu kullanmak, if git ls-remote ...; then ...; fikontrol etmekten daha az hataya meyillidir $?(bu, ifadeleri, tuzakları vb. Günlüğe kaydederek değiştirilebilir).
Charles Duffy

Neden --heads?
Steve

@JohnLinux --headsyalnızca şubeleri listeler. --tagssadece etiketleri listelemek için kullanın .
rymo

19

Çalıştırmak için bir git deposu ise mevcut klasörde kullanabileceğiniz başka bir yol

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

2
Çift tırnak kullanın:git branch -a | egrep "remotes/origin/${YOUR_BRANCH_NAME}$"
Ivan

3
Bu optimal değildir, çünkü mevcut bir dal adının yalnızca bir kısmını eşleştirseniz, ancak hedef dalla tam olarak eşleşmeseniz bile doğru döndürür. Dolayısıyla bu, teslim almadan önce dalın var olup olmadığını test etmek için bir komut dosyasında güvenli bir şekilde kullanılamaz. Yine de paylaştığınız için teşekkürler, çünkü yararlı buldum. Şu şekilde düzeltilebilir:git branch -a | grep "\b${BRANCH}$"
EntangledLoops

2
git fetchgit branch -atüm uzaktan kumanda referansları önce getirilirse gereklidir . Başkaları git ls-remotetarafından işaret edildiği şekliyle başka kullanım .
hIpPy

git branch -a --list '<pattern>'aynı zamanda bir seçenektir. Komut dosyanız için bir dönüş koduna ihtiyacınız varsa grep'e yönlendirin.
LOAS

16

Bunu da kullanabilirsiniz:

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

$ 'ın en son commit ve değerini döndürür? 0 yoksa "ölümcül: kötü sha1 referans uzak / kaynak / <>" ve $ değerini döndürür? 128


1
Bu, kontrol etmeden önce dalları uzaktan çekmez, böylece en son uzak durumu alamazsınız.
siemanko

12

Buradaki tüm cevaplar Linux kabuğuna özgüdür ve bu tür işlemleri desteklemeyen bir ortamdaysanız - örneğin, Windows'un komut istemi - pek yardımcı olmaz.

Neyse ki , dalın var olup olmamasına bağlı olarak 0 veya 2 döndüren git ls-remotebir --exit-codebağımsız değişkeni kabul eder . Yani:

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

0 döndürecektir ve

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

2 döndürecektir.

PowerShell için, yerleşik doğruluk işleme semantiğini kullanabilirsiniz:

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

ürün $trueverirken:

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

verim $false.


11

Bash terminalinde buna benzer bir şey yapabilirsiniz. Sadece yankıları yürütmek istediğiniz komutlarla değiştirin.

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

Umarım yardımcı olur.


1
Bunu sevdim. diğer cevaplarda da ls-remote var, sevdiğim şey "eğer".
Taşlı

11

Bu durumda arşiv adını her seferinde manuel olarak aktarmanıza gerek kalmaz.

git ls-remote origin <branch>

Onun yerine

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

Misal :

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

VEYA

git ls-remote origin uat_21dec

Her ikisi de aynı çıktıyı verecektir:

görüntü açıklamasını buraya girin

Origin hakkında daha fazla bilgi : Git, deponuzun diğer kopyalarının URL'leri olan "uzak" kavramına sahiptir. Başka bir depoyu klonladığınızda, Git otomatik olarak "origin" adlı bir uzak oluşturur ve onu işaret eder. Git remote show origin yazarak uzaktan kumanda hakkında daha fazla bilgi görebilirsiniz.


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

çoğu zaman işe yarar.

Ancak şube aşağıdaki gibi kısmen eşleşirse çalışmaz,

$ git branch -a
creative/dev
qa/dev

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

Kullanım

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

güvenilir bir yol istiyorsanız.

Komut dosyasında kullanmak istiyorsanız ve originvarsayılan uzaktan kumanda olarak kabul etmek istemiyorsanız

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

çalışmalı.

git branch -a | grep ...Son fetchçalıştırıldıktan sonra biraz zaman alabileceği için bunun güvenilir olmadığını unutmayın .


Benim için bu, Amitesh'den gelen cevapla (kısa uzak isim) James Cache'den gelenle birleştirilen ( grep -x "$branch"ile aynıdır grep ^"$branch"$) kabul edilen cevaptır . Komut ben tercih etse de uzun formlu geçer: --line-regexp. Ayrıca yapmaya gerek yok wc -l. Bash'e boş çıktı koymak, if [ -z ] etkin bir şekilde doğru olarak değerlendirilir, bu nedenle dalın olmadığı anlamına gelir. Bu size birkaç milisaniye kazandırır.
Amedee Van Gasse

1

Sahip olduğunuz depoyu uzaktan kullanarak ekleyebilir git remote add something https://github.com/project-name/project-name.gitve ardından birgit remote show something uzaktan kumanda hakkında tüm bilgileri almak . Bu, bir ağ bağlantısı gerektirir ve insan kullanımı için yararlıdır.

Alternatif olarak, bir git fetch something. Bu, çağrılan uzaktaki tüm dalları alacak somethingve yerel deponuzda tutacaktır. Daha sonra bunları yerel şubenizde istediğiniz gibi birleştirebilirsiniz. Bu yolu tavsiye ederim, çünkü sonunda birleşmeniz gerektiğine karar verirseniz, yapmanız gereken budur.

OT: "Yerel olarak kontrol edildi" ifadesini kullanmanız, buna merkezi bir sürüm kontrol sistemi bakış açısından yaklaştığınızı gösterir. Git ile uğraşırken bu genellikle bir çıkmazdır. Eski sistemlerin yaptığından farklı olarak "ödeme" vb. Kelimeleri kullanır.


Açıklamalar için teşekkürler. Henüz gitmeye alışamadım ve farklı bir düşünce tarzı gerektiriyor.
Keen

1

Deneyebilirsin

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

Burada @{u}uzak / yukarı akış @{0}anlamına gelir ve mevcut yerel HEAD'e atıfta bulunur (git'in daha yeni sürümüyle, @{0}şu şekilde kısaltılabilir:@ ). Uzaktan kumanda yoksa, hata verir.

Git 2.16.2 ile (Bu işlevselliğe ilk sahip olan sürümün hangisi olduğundan emin değilim, örneğin git 1.7.1'e sahip değil), yapabilirsiniz

git checkout

Uzak bir dal varsa, bazı çıktılar olacaktır.

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

Aksi takdirde çıktı olmaz.


1

Adında sorguyu içeren tüm dalları (uzak veya yerel) döndürür.

git branch --all | grep <query>


0

Şube adlarınız çok spesifikse, basit şube adı eşleştirmesi için grep kullanmanız gerekmeyebilir:

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

hangisi için çalışıyor

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

Şube adları olarak benzersiz sorun kimliği kullanıyoruz ve sorunsuz çalışıyor.


0

Ben sadece bunu denedim:

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

Bu, dal "şubeniz" bulunursa 1, aksi takdirde 0 döndürür.


0

Yukarıdaki cevaplardan bazılarını bir senaryoda birleştiriyorum:

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

Bu komut dosyası uzak bir bitbucket'ten 4 dal alacak ve onları uzaktaki bir github'a gönderecek ve ardından tüm etiketleri github'a gönderecektir. Bunu bir Jenkins işinde kullanıyorum, bu yüzden hiç görmüyorsun git fetchveyagit pull bu Jenkins iş deposu yapılandırmasında zaten yapılmıştır.

Komut dosyalarında genellikle uzun biçim seçeneklerini tercih ederim. Ben kombine olabilirdi git branchve git checkoutkullanarak git checkout -B.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.