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.default
opsi konfigurasi). - Jika keduanya
behind_count
danahead_count
adalah 0, maka cabang saat ini adalah yang terbaru. - Jika
behind_count
adalah 0 danahead_count
lebih besar dari 0, maka cabang saat ini ada di depan. - Jika
behind_count
lebih besar dari 0 danahead_count
adalah 0, maka cabang saat ini berada di belakang. - Jika keduanya
behind_count
danahead_count
lebih besar dari 0, maka cabang saat ini menyimpang.
Penjelasan:
git rev-list
daftarkan semua komit untuk memberikan rentang komit.--count
keluaran opsi berapa banyak komit yang akan dicantumkan, dan sembunyikan semua keluaran lainnya.HEAD
nama cabang saat ini.@{u}
mengacu pada upstream lokal dari cabang saat ini (dikonfigurasi denganbranch.<name>.remote
danbranch.<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:
currentBranch
mendapatkan output konsol, yang merupakan string dari nama cabang saat inicanCommit
mengetahui apakah konsol mengeluarkan sesuatu (perbedaan antara perubahan saat ini dan HEAD, mengabaikan submodul)canPush
mendapatkan jumlah perubahan antara Origin/currentBranch
dan 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