Bagaimana cara memeriksa apakah cabang jarak jauh ada pada repositori jarak jauh tertentu?

106

Saya perlu melakukan penggabungan subtree untuk cabang tertentu, jika itu ada di repositori jarak jauh tertentu. Masalahnya adalah repositori jarak jauh tidak diperiksa secara lokal, jadi saya tidak dapat menggunakan git branch -r. Yang saya miliki hanyalah alamat remote, seperti ini https://github.com/project-name/project-name.git. Apakah ada cara untuk membuat daftar cabang jarak jauh hanya dengan alamat jarak jauh? Saya tidak dapat menemukan apa pun yang bergunal :(

Tajam
sumber

Jawaban:

124
$ git ls-remote --heads [email protected]:user/repo.git branch-name

Jika branch-nameditemukan, Anda akan mendapatkan output berikut:

b523c9000c4df1afbd8371324083fef218669108        refs/heads/branch-name

Jika tidak, tidak ada keluaran yang akan dikirim.

Jadi menyalurkannya ke wcakan memberi Anda 1atau 0:

$ git ls-remote --heads [email protected]:user/repo.git branch-name | wc -l

Atau Anda dapat mengatur --exit-codebendera git ls-remoteyang akan mengembalikan kode keluar 2jika tidak ada referensi yang cocok ditemukan. Ini adalah solusi yang paling idiomatis. Hasilnya dapat diperiksa secara langsung dalam pengujian shell atau dengan memeriksa variabel status $?.

$ git ls-remote --exit-code --heads  [email protected]:user/repo.git branch-name
pengguna487772
sumber
7
Saya digunakan git ls-remote --heads ${REPO} ${BRANCH} | grep ${BRANCH} >/dev/nulldiikuti olehif [ "$?" == "1" ] ; then echo "Branch doesn't exist"; exit; fi
sibaz
1
Saya mencari jawaban yang rapi & tepat ini selama beberapa jam, brilian.
medik
Anda perlu menentukan nama cabang sebagai /refs/heads/branch-name. Jika tidak, cabang foo/branch-nameakan dikembalikan meskipun tidak ada branch-name.
FuzzY
Selamat atas lencana emas 'Jawaban Hebat' Anda. :)
jmort253
4
Catatan: Jika Anda tidak ingin menentukan URL repo, Anda dapat menentukan nama remote repo sebagai gantinya, misalnya: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
Dogbert
sumber
Saya juga tidak tahu tentang ls-remote. Terima kasih!
Tertarik
7
Saya perlu melakukan tes dalam skrip bash dan hanya tertarik pada kode keluar, jadi saya melakukan hal berikut di klon lokal: git ls-remote --exit-code . origin/branch-name &> /dev/nullkemudian digunakan $?sebagai operan tes
Darren Bishop
5
@ Darren, hanya menggunakan perintah secara langsung dalam kondisi, seperti if git ls-remote ...; then ...; fi, kurang rentan terhadap kesalahan daripada memeriksa $?(yang dapat diubah dengan membuat log pernyataan, perangkap, dll).
Charles Duffy
Mengapa --heads?
Steve
@JohnLinux --headshanya mencantumkan cabang. menggunakan--tags untuk mendaftar tag saja.
rymo
19

Cara lain yang dapat Anda gunakan di folder saat ini jika itu adalah git repo untuk dijalankan

git branch -a | egrep 'remotes/origin/${YOUR_BRANCH_NAME}$'
РАВИ
sumber
2
Gunakan tanda kutip ganda:git branch -a | egrep "remotes/origin/${YOUR_BRANCH_NAME}$"
Ivan
3
Ini tidak optimal karena akan mengembalikan nilai true meskipun Anda hanya cocok dengan bagian dari nama cabang yang ada, tetapi tidak sama persis dengan cabang target. Jadi ini tidak dapat digunakan dengan aman dalam skrip untuk menguji apakah cabang tersebut ada sebelum memeriksanya. Terima kasih telah berbagi, karena menurut saya ini berguna. Dapat diperbaiki seperti ini:git branch -a | grep "\b${BRANCH}$"
EntangledLoops
2
git fetchdiperlukan jika menggunakan git branch -ajadi semua referensi jarak jauh diambil terlebih dahulu. Lain digunakan git ls-remoteseperti yang ditunjukkan oleh orang lain.
hIpPy
git branch -a --list '<pattern>'juga merupakan pilihan. Gunakan pipa ke grep jika Anda membutuhkan kode pengembalian untuk skrip Anda.
LOAS
17

Anda juga dapat menggunakan ini:

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

mengembalikan komit terbaru dan nilai $? is 0 sebaliknya mengembalikan "fatal: bad sha1 reference remotes / origin / <>" dan nilai $? adalah 128

Ajo Paul
sumber
Ini tidak akan menarik cabang dari jarak jauh sebelum memeriksa, jadi Anda tidak mendapatkan status jarak jauh terbaru.
siemanko
11

Anda dapat melakukan sesuatu seperti ini di terminal Bash. Cukup ganti echos dengan perintah yang ingin Anda jalankan.

if git ls-remote https://username:[email protected]/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

Semoga membantu.

sagunms
sumber
1
Saya suka itu. jawaban lain juga memiliki ls-remote, yang saya suka adalah "jika".
Stony
11

Maka tidak perlu setiap kali meneruskan nama repositori secara manual.

git ls-remote origin <branch>

Dari pada

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

Contoh:

git ls-remote [email protected]:landmarkgroupme/in-store-application.git  uat_21dec

ATAU

git ls-remote origin uat_21dec

Keduanya akan memberikan hasil yang sama:

masukkan deskripsi gambar di sini

Lebih lanjut tentang Origin : Git memiliki konsep "remote", yang merupakan URL sederhana ke salinan lain dari repositori Anda. Saat Anda mengkloning repositori lain, Git secara otomatis membuat remote bernama "origin" dan menunjuk ke sana. Anda dapat melihat informasi lebih lanjut tentang remote dengan mengetik git remote show origin.

Amitesh Bharti
sumber
11

Semua jawaban di sini adalah khusus untuk shell Linux, yang tidak banyak membantu jika Anda berada di lingkungan yang tidak mendukung operasi semacam itu - misalnya, command prompt Windows.

Untungnya git ls-remotemenerima --exit-codeargumen yang mengembalikan 0 atau 2 bergantung pada apakah cabang itu ada atau tidak. Begitu:

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

akan mengembalikan 0, dan

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

akan mengembalikan 2.

Untuk PowerShell, Anda cukup menggunakan semantik penanganan kebenaran bawaan:

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

hasil $true, sementara:

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

hasil $false.

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

bekerja hampir sepanjang waktu.

Tetapi tidak akan berfungsi jika cabang cocok sebagian seperti di bawah ini,

$ git branch -a
creative/dev
qa/dev

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

Menggunakan

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

jika Anda menginginkan cara yang dapat diandalkan.

Jika Anda ingin menggunakan script dan tidak ingin menganggap originremote default maka

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

harus bekerja.

Perhatikan bahwa git branch -a | grep ...tidak dapat diandalkan karena mungkin beberapa saat sejak terakhir fetchdijalankan.

hIpPy
sumber
Bagi saya, ini adalah jawaban yang diterima, dikombinasikan dengan yang dari Amitesh (nama jarak jauh pendek), dikombinasikan dengan yang dari James Cache ( grep -x "$branch"identik dengan grep ^"$branch"$). Meskipun dalam skrip Saya lebih suka bentuk panjang switch: --line-regexp. Juga, tidak perlu dilakukan wc -l. Menempatkan keluaran kosong di Bash if [ -z ] secara efektif mengevaluasi sebagai benar sehingga itu berarti bahwa cabang tidak ada. Itu menghemat beberapa milidetik.
Amedee Van Gasse
1

Anda dapat menambahkan repositori yang Anda miliki sebagai remote menggunakan git remote add something https://github.com/project-name/project-name.gitdan kemudian melakukan agit remote show something untuk mendapatkan semua informasi tentang remote tersebut. Ini membutuhkan koneksi jaringan dan berguna untuk digunakan manusia.

Sebagai alternatif, lakukan a git fetch something. Ini akan mengambil semua cabang pada remote yang dipanggil somethingdan menyimpannya di repositori lokal Anda. Anda kemudian dapat menggabungkannya ke cabang lokal Anda sesuka Anda. Saya merekomendasikan jalur ini karena jika Anda akhirnya memutuskan bahwa Anda harus menggabungkan, inilah yang perlu Anda lakukan.

OT: Penggunaan "check out secara lokal" menunjukkan bahwa Anda mendekati ini dari sudut pandang sistem kontrol versi terpusat. Itu biasanya jalan buntu ketika Anda berurusan dengan git. Ia menggunakan kata-kata seperti "checkout" dll. Secara berbeda dari bagaimana sistem yang lebih lama melakukannya.

Noufal Ibrahim
sumber
Terima kasih atas penjelasannya. Saya belum terbiasa git, dan itu memang membutuhkan cara berpikir yang berbeda.
Tertarik
1

Anda dapat mencoba

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

Di sini @{u}mengacu pada remote / upstream, dan @{0}mengacu pada HEAD lokal saat ini (dengan versi git yang lebih baru, @{0}dapat disingkat sebagai @). Jika jarak jauh tidak ada, kesalahan keluar.

Dengan git 2.16.2 (Saya tidak yakin versi mana yang pertama memiliki fungsi ini, misalnya, git 1.7.1 tidak memilikinya), Anda dapat melakukannya

git checkout

Jika ada cabang jarak jauh, akan ada beberapa keluaran, seperti

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

Jika tidak, tidak ada keluaran.

no
sumber
1

Akan mengembalikan semua cabang (jarak jauh atau lokal) yang berisi kueri dalam nama.

git branch --all | grep <query>

alexoviedo999
sumber
0

Jika nama cabang Anda sangat spesifik, Anda mungkin tidak perlu menggunakan grep untuk pencocokan nama cabang yang sederhana:

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

yang berhasil

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

Kami menggunakan id masalah unik sebagai nama cabang dan berfungsi dengan baik.

Fabio
sumber
0

Saya baru saja mencoba ini:

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

Ini akan mengembalikan 1 jika cabang "cabang-Anda" ditemukan dan 0 jika tidak.

James Cache
sumber
0

Saya menggabungkan beberapa jawaban di atas dalam sebuah skrip:

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

Skrip ini akan mendapatkan 4 cabang dari bitbucket jarak jauh, dan mendorongnya ke github jarak jauh, dan kemudian akan mendorong semua tag ke github. Saya menggunakan ini dalam pekerjaan Jenkins, itulah mengapa Anda tidak melihat satu pun git fetchataugit pull , itu sudah dilakukan di konfigurasi repositori pekerjaan Jenkins.

Saya biasanya lebih suka opsi bentuk panjang dalam skrip. Saya bisa menggabungkan git branchdan git checkoutmenggunakan git checkout -B.

Amedee Van Gasse
sumber