Dari jawaban ini.
- Lakukan pengambilan:
git fetch. - Dapatkan berapa banyak komit yang ada di belakang cabang saat ini:
behind_count = $(git rev-list --count [email protected]{u}). - Dapatkan berapa banyak komitmen cabang saat ini di depan:
ahead_count = $(git rev-list --count @{u}..HEAD). (Diasumsikan bahwa dari mana Anda mengambil adalah tempat Anda mendorong, lihatpush.defaultopsi konfigurasi). - Jika keduanya
behind_countdanahead_countadalah 0, maka cabang saat ini adalah yang terbaru. - Jika
behind_countadalah 0 danahead_countlebih besar dari 0, maka cabang saat ini ada di depan. - Jika
behind_countlebih besar dari 0 danahead_countadalah 0, maka cabang saat ini berada di belakang. - Jika keduanya
behind_countdanahead_countlebih besar dari 0, maka cabang saat ini menyimpang.
Penjelasan:
git rev-listdaftarkan semua komit untuk memberikan rentang komit.--countkeluaran opsi berapa banyak komit yang akan dicantumkan, dan sembunyikan semua keluaran lainnya.HEADnama cabang saat ini.@{u}mengacu pada upstream lokal dari cabang saat ini (dikonfigurasi denganbranch.<name>.remotedanbranch.<name>.merge). Ada juga@{push}, biasanya menunjuk sama dengan@{u}.<rev1>..<rev2>menentukan rentang komit yang menyertakan komit yang dapat dijangkau dari tetapi mengecualikan komit yang dapat dijangkau dari . Jika salah satu atau dihilangkan, defaultnya adalah HEAD.
Anda dapat melakukannya dengan kombinasi git merge-base dan git rev-parse . Jika git merge-base <branch> <remote branch> mengembalikan sama dengan git rev-parse <remote branch> , maka cabang lokal Anda ada di depan. Jika kembali sama dengan git rev-parse <branch> , maka cabang lokal Anda ada di belakang. Jika merge-base mengembalikan jawaban yang berbeda dari rev-parse , maka cabang telah menyimpang dan Anda harus melakukan penggabungan.
Sebaiknya lakukan git fetch sebelum memeriksa cabang, jika tidak, penentuan apakah Anda perlu menarik atau tidak akan ketinggalan zaman. Anda juga ingin memverifikasi bahwa setiap cabang yang Anda periksa memiliki cabang pelacakan jarak jauh. Anda dapat menggunakan git for-each-ref --format='%(upstream:short)' refs/heads/<branch> untuk melakukannya. Perintah itu akan mengembalikan cabang pelacakan jarak jauh dari <branch> atau string kosong jika tidak ada. Di suatu tempat di SO ada versi berbeda yang akan mengembalikan kesalahan jika cabang tidak memiliki cabang pelacakan jarak jauh, yang mungkin lebih berguna untuk tujuan Anda.
Pada akhirnya, saya menerapkannya di plugin C++11 git-ws saya.
string currentBranch = run("git rev-parse --abbrev-ref HEAD");
bool canCommit = run("git diff-index --name-only --ignore-submodules HEAD --").empty();
bool canPush = stoi(run("git rev-list HEAD...origin/" + currentBranch + " --ignore-submodules --count")[0]) > 0;
Tampaknya bekerja sejauh ini. canPull masih perlu diuji dan diterapkan.
Penjelasan:
currentBranchmendapatkan output konsol, yang merupakan string dari nama cabang saat inicanCommitmengetahui apakah konsol mengeluarkan sesuatu (perbedaan antara perubahan saat ini dan HEAD, mengabaikan submodul)canPushmendapatkan jumlah perubahan antara Origin/currentBranchdan repo lokal - jika> 0, repo lokal dapat didorong
Untuk referensi di masa mendatang. Sejak Git v2.17.0
git status -sb
mengandung kata belakang .Sehingga dapat digunakan langsung untuk memeriksa tarikan.
Catatan:Ingatlah untuk menjalankan git fetch sebelum menjalankan git status -sb