Bagaimana saya memeriksa apakah repositori jarak jauh telah berubah dan saya perlu menarik?
Sekarang saya menggunakan skrip sederhana ini:
git pull --dry-run | grep -q -v 'Already up-to-date.' && changed=1
Tapi ini agak berat.
Apakah ada cara yang lebih baik? Solusi ideal akan memeriksa semua cabang jarak jauh, dan mengembalikan nama cabang yang diubah dan jumlah komit baru di masing-masing cabang.
git fetch -v --dry-run
apa yang kamu butuhkan.Jawaban:
Pertama kali digunakan
git remote update
, untuk memperbaharui referensi jarak jauh Anda. Maka Anda dapat melakukan salah satu dari beberapa hal, seperti:git status -uno
akan memberi tahu Anda apakah cabang yang Anda lacak ada di depan, di belakang atau telah menyimpang. Jika tidak mengatakan apa-apa, lokal dan remote adalah sama.git show-branch *master
akan menunjukkan kepada Anda komit di semua cabang yang namanya berakhiran 'master' (mis. master dan asal / master ).Jika Anda menggunakan
-v
dengangit remote update
(git remote -v update
) Anda dapat melihat cabang mana yang diperbarui, sehingga Anda tidak benar-benar membutuhkan perintah lebih lanjut.Namun, sepertinya Anda ingin melakukan ini dalam skrip atau program dan berakhir dengan nilai true / false. Jika demikian, ada cara untuk memeriksa hubungan antara komit HEAD Anda saat ini dan kepala cabang yang Anda lacak, meskipun karena ada empat kemungkinan hasil yang Anda tidak bisa menguranginya menjadi jawaban ya / tidak. Namun, jika Anda siap untuk melakukannya
pull --rebase
maka Anda dapat memperlakukan "lokal ada di belakang" dan "lokal telah menyimpang" sebagai "perlu menarik", dan dua lainnya sebagai "tidak perlu menarik".Anda bisa mendapatkan id komit dari setiap referensi yang menggunakan
git rev-parse <ref>
, sehingga Anda bisa melakukan ini untuk master dan origin / master dan membandingkannya. Jika mereka sama, cabang-cabangnya sama. Jika mereka tidak setara, Anda ingin tahu yang di depan yang lain. Menggunakangit merge-base master origin/master
akan memberi tahu Anda nenek moyang yang sama dari kedua cabang, dan jika mereka tidak menyimpang ini akan sama dengan yang satu atau yang lainnya. Jika Anda mendapatkan tiga id berbeda, cabang-cabangnya telah berbeda.Untuk melakukan ini dengan benar, misalnya dalam skrip, Anda harus dapat merujuk ke cabang saat ini, dan cabang jarak jauh yang dilacaknya. Fungsi bash prompt-setting di
/etc/bash_completion.d
memiliki beberapa kode yang berguna untuk mendapatkan nama cabang. Namun, Anda mungkin sebenarnya tidak perlu mendapatkan namanya. Git memiliki beberapa singkatan yang rapi untuk merujuk pada cabang dan komitmen (seperti yang didokumentasikan dalamgit rev-parse --help
). Secara khusus, Anda dapat menggunakan@
untuk cabang saat ini (dengan asumsi Anda tidak berada dalam keadaan kepala terpisah) dan@{u}
untuk cabang hulu (misalnyaorigin/master
). Jadigit merge-base @ @{u}
akan mengembalikan (hash dari) komit di mana cabang saat ini dan hulu berbeda dangit rev-parse @
dangit rev-parse @{u}
akan memberi Anda hash dari dua tips. Ini dapat diringkas dalam skrip berikut:Catatan: git versi lama tidak mengizinkannya
@
sendiri, jadi Anda mungkin harus menggunakannya@{0}
.Jalur ini
UPSTREAM=${1:-'@{u}'}
memungkinkan Anda untuk secara opsional melewati cabang upstream secara eksplisit, jika Anda ingin mengecek cabang jarak jauh yang berbeda dari yang dikonfigurasi untuk cabang saat ini. Ini biasanya berupa remotename / nama cabang . Jika tidak ada parameter yang diberikan, nilai defaultnya adalah@{u}
.Script mengasumsikan bahwa Anda telah melakukan
git fetch
atau yanggit remote update
pertama, untuk membuat cabang pelacakan up to date. Saya tidak membuat ini menjadi skrip karena lebih fleksibel untuk dapat melakukan pengambilan dan perbandingan sebagai operasi terpisah, misalnya jika Anda ingin membandingkan tanpa mengambil karena Anda sudah mengambil baru-baru ini.sumber
git status -s -u no
, yang memberikan hasil lebih pendek darigit status -u no
.git remote -v update
,. Lihatlah outputgit remote --help
untuk penjelasan yang lebih lengkap.@{u}
bekerja dengan git 1.8.3.2 tetapi@
tidak. Namun@
bekerja dengan1.8.5.4
. Moral dari cerita ini: git terus membaik dan layak memiliki versi terbaru yang Anda bisa.Jika Anda memiliki cabang hulu
Jika Anda tidak memiliki cabang hulu
Bandingkan dua cabang:
Sebagai contoh:
(Saya berasumsi
origin/master
adalah cabang pelacakan jarak jauh Anda)Jika ada komit yang tercantum dalam output di atas, maka Anda memiliki perubahan yang masuk - Anda harus menggabungkan. Jika tidak ada komitmen terdaftar pada
git log
saat itu maka tidak ada yang perlu digabung.Perhatikan bahwa ini akan berfungsi bahkan jika Anda menggunakan cabang fitur - yang tidak memiliki remote pelacakan, karena jika secara eksplisit merujuk pada
origin/master
alih-alih secara implisit menggunakan cabang upstream yang diingat oleh Git.sumber
git fetch; git log HEAD.. --oneline
dapat digunakan jika ada cabang jarak jauh default untuk cabang lokal.git rev-list HEAD...origin/master --count
akan memberi Anda jumlah total komitmen "berbeda" antara keduanya.Jika ini untuk skrip, Anda dapat menggunakan:
(Catatan: manfaat dari jawaban ini vs. jawaban sebelumnya adalah Anda tidak perlu perintah terpisah untuk mendapatkan nama cabang saat ini. "HEAD" dan "@ {u}" (hulu cabang saat ini) mengurusnya. Lihat "git rev-parse --help" untuk lebih jelasnya.)
sumber
git rev-parse @{u}
benar-benar menunjukkan komit terbaru tanpagit fetch
?==
yang berarti "jika tidak ada perubahan dari hulu". Saya dulu!=
memeriksa "apakah ada perubahan dari hulu" untuk aplikasi saya. Jangan lupagit fetch
dulu!@
kependekan dariHEAD
btw.@{u}
eggit rev-parse '@{u}'
Perintah
akan mencantumkan head saat ini pada remote - Anda dapat membandingkannya dengan nilai sebelumnya atau melihat apakah Anda memiliki SHA di repo lokal Anda.
sumber
git rev-list HEAD...origin/master --count
akan memberi Anda jumlah total komitmen "berbeda" antara keduanya.git fetch
ataugit remote update
pertama.git status
juga menunjukkan hitungan, btw...
adalah "komit di asal / master, kurangi KEPALA" (yaitu jumlah komit di belakang). Sedangkan,...
adalah perbedaan simetris (yaitu depan dan belakang)fetch
.Berikut adalah Bash satu-kapal yang membandingkan cabang saat ini KEPALA melakukan hash terhadap cabang hulu terpencil, tidak ada yang berat
git fetch
ataugit pull --dry-run
operasi diperlukan:Inilah cara garis yang agak padat ini dipecah:
$(x)
Bash .git rev-parse --abbrev-ref @{u}
mengembalikan ref hulu yang disingkat (misalnyaorigin/master
), yang kemudian dikonversi ke bidang yang dipisahkan olehsed
perintah piped , misorigin master
.git ls-remote
mana mengembalikan komit kepala dari cabang jauh. Perintah ini akan berkomunikasi dengan repositori jarak jauh.cut
Perintah pipa mengekstrak hanya bidang pertama (hash komit), menghapus string referensi tab-terpisah.git rev-parse HEAD
mengembalikan hash komit lokal.[ a = b ] && x || y
melengkapi one-liner: ini adalah perbandingan string Bash=
dalam konstruk tes[ test ]
, diikuti oleh dan-daftar dan atau-daftar konstruk&& true || false
.sumber
Saya sarankan Anda pergi melihat skrip https://github.com/badele/gitcheck . Saya telah mengkodekan skrip ini untuk memeriksa dalam satu pass semua repositori Git Anda, dan ini menunjukkan siapa yang belum berkomitmen dan siapa yang tidak mendorong / menarik.
Di sini hasil sampel:
sumber
git mrepo -c
ini akan menampilkan semua komitmen yang tertunda.Saya mendasarkan solusi ini pada komentar @ jberger.
sumber
...
tampaknya menjadi bagian yang valid dari solusi Anda.Ada banyak jawaban yang kaya fitur dan cerdik. Untuk memberikan beberapa kontras, saya bisa puas dengan garis yang sangat sederhana.
sumber
Saya pikir cara terbaik untuk melakukan ini adalah:
Dengan anggapan Anda telah mendaftarkan refspec ini. Anda harus jika Anda telah mengkloning repositori, jika tidak (yaitu, jika repo dibuat secara lokal, dan didorong ke remote), Anda perlu menambahkan refspec secara eksplisit.
sumber
Script di bawah ini berfungsi dengan sempurna.
sumber
Saya akan melakukan cara yang disarankan oleh brool. Skrip satu baris berikut mengambil SHA1 dari versi yang terakhir Anda komit dan membandingkannya dengan salah satu dari asal yang jauh, dan menarik perubahan hanya jika mereka berbeda. Dan itu bahkan lebih ringan dari solusi berdasarkan
git pull
ataugit fetch
.sumber
git rev-parse --verify HEAD
git log --pretty=%H ...refs/heads/master^
untuk mendapatkan SHA1 dari versi komit terakhir Anda, dan kemudian jalankangit ls-remote origin -h refs/heads/master |cut -f1
untuk mendapatkan SHA1 dari asal jarak jauh. Keduanya adalah perintah git dan tidak ada hubungannya dengan bash. Apa yang dilakukan bash di dalam tanda kurung siku adalah untuk membandingkan output dari perintah pertama dengan yang kedua, dan jika mereka sama itu mengembalikan true dan berjalangit pull
.git pull
". Saya tahu saya menjadi rewel, tetapi hanya untuk menyelamatkan seseorang kebingungan, itu harus "dan jika mereka tidak sama". Juga, untuk alasan apa pun, perintah git pertama tidak bekerja untuk saya. (Saya on git2.4.1
.) Jadi saya hanya menggunakangit log --pretty=%H master | head -n1
saja. Tapi saya tidak yakin apakah itu persis sama.Jika Anda menjalankan skrip ini, itu akan menguji apakah cabang saat ini membutuhkan
git pull
:Sangat mudah untuk menempatkannya sebagai pre-commit Git hook yang harus dihindari
kapan kamu
commit
sebelumnyapulling
.Untuk menggunakan kode ini sebagai pengait, cukup salin / tempel skrip ke
dan
sumber
Saya hanya ingin memposting ini sebagai posting yang sebenarnya karena mudah untuk melewatkan ini di komentar.
Jawaban yang benar dan terbaik untuk pertanyaan ini diberikan oleh @Jake Berger, Terima kasih banyak, semua orang membutuhkan ini dan semua orang melewatkan ini di komentar. Jadi untuk semua orang yang berjuang dengan ini di sini adalah jawaban yang benar, cukup gunakan output dari perintah ini untuk mengetahui apakah Anda perlu melakukan git pull. jika outputnya 0 maka jelas tidak ada yang diperbarui.
@stackoverflow, beri orang ini lonceng. Terima kasih @ Jake Berger
sumber
Jalankan
git fetch (remote)
untuk memperbarui referensi jarak jauh Anda, itu akan menunjukkan kepada Anda apa yang baru. Kemudian, ketika Anda checkout cabang lokal Anda, itu akan menunjukkan kepada Anda apakah itu di belakang hulu.sumber
git status
akan menunjukkan itu juga.git pull --dry-run
dilakukan, tetapi saya pikir ini terlalu berat untuk menjalankan skrip cron setiap menit.fetch
tidak akan melakukan banyak hal selain memeriksa status. Jika Anda memerlukan reaksi yang sangat cepat dan ringan pada pembaruan jarak jauh, Anda mungkin ingin melihat mengaitkan semacam pemberitahuan ke repositori jarak jauh.Semua saran kompleks seperti itu sementara solusinya sangat singkat dan mudah:
sumber
git remote update
dieksekusi sebelum kode Anda, untuk mendapatkan info komit asal terbarugit remote update
Bukankah seharusnya menambahkan sebelumgit show
perintah?Inilah versi saya dari skrip Bash yang memeriksa semua repositori di folder yang telah ditentukan:
https://gist.github.com/henryiii/5841984
Itu dapat membedakan antara situasi umum, seperti tarikan yang dibutuhkan dan dorong yang dibutuhkan, dan itu multithreaded, sehingga pengambilan terjadi sekaligus. Ini memiliki beberapa perintah, seperti tarikan dan status.
Letakkan symlink (atau skrip) di folder di jalur Anda, lalu berfungsi sebagai
git all status
(, dll.). Ini hanya mendukung asal / master, tetapi dapat diedit atau dikombinasikan dengan metode lain.sumber
akan mendaftar semua yang direferensikan di remote mana pun yang tidak ada di repo Anda. Untuk mengetahui perubahan ref jarak jauh pada hal-hal yang sudah Anda miliki (mis. Me-reset ke commit sebelumnya) membutuhkan sedikit lebih banyak:
sumber
Mungkin ini, jika Anda ingin menambahkan tugas sebagai crontab:
sumber
Menggunakan regexp sederhana:
sumber
Saya menggunakan versi naskah berdasarkan jawaban Stephen Haberman:
Dengan asumsi skrip ini disebut
git-fetch-and-rebase
, skrip ini dapat dipanggil dengan argumen opsionaldirectory name
dari repositori Git lokal untuk menjalankan operasi. Jika skrip dipanggil tanpa argumen, ia menganggap direktori saat ini menjadi bagian dari repositori Git.Contoh:
Ini tersedia di sini juga.
sumber
Setelah membaca banyak jawaban dan banyak posting, dan menghabiskan setengah hari mencoba berbagai permutasi, inilah yang saya dapatkan.
Jika Anda menggunakan Windows, Anda dapat menjalankan skrip ini di Windows menggunakan Git Bash yang disediakan oleh Git untuk Windows (instalasi atau portable).
Script ini membutuhkan argumen
Script akan
Jika ada perubahan seperti yang dicetak oleh skrip, maka Anda dapat melanjutkan untuk mengambil atau menarik. Skripnya mungkin tidak efisien, tetapi tugasnya selesai untuk saya.
Pembaruan - 2015-10-30: stderr ke dev null untuk mencegah pencetakan URL dengan kata sandi ke konsol.
sumber
Untuk pengguna windows yang akhirnya pada pertanyaan ini mencari ini, saya telah memodifikasi beberapa jawaban menjadi skrip PowerShell. Tweak seperlunya, simpan ke
.ps1
file dan jalankan sesuai permintaan atau dijadwalkan jika Anda mau.sumber
Karena jawaban Neils sangat membantu saya di sini adalah terjemahan Python tanpa ketergantungan:
hth
sumber
Anda juga dapat menemukan skrip Phing yang melakukannya sekarang.
Saya membutuhkan solusi untuk memperbarui lingkungan produksi saya secara otomatis dan kami sangat senang berkat skrip yang saya bagikan ini.
Script ditulis dalam XML dan membutuhkan Phing .
sumber