Da questa risposta.
- Esegui un recupero:
git fetch. - Ottieni quanti commit è presente nel branch corrente:
behind_count = $(git rev-list --count example@unixlinux.online{u}). - Ottieni quanti commit current branch sono avanti:
ahead_count = $(git rev-list --count @{u}..HEAD). (Presuppone che il punto da cui prendi sia il punto in cui spingi, vedipush.defaultopzione di configurazione). - Se entrambi
behind_counteahead_countsono 0, allora il ramo corrente è aggiornato. - Se
behind_countè 0 eahead_countè maggiore di 0, allora il ramo corrente è avanti. - Se
behind_countè maggiore di 0 eahead_countè 0, allora il ramo corrente è in ritardo. - Se entrambi
behind_counteahead_countsono maggiori di 0, allora il ramo corrente è divergente.
Spiegazione:
git rev-listelenca tutti i commit di dare un intervallo di commit.--countoption output quanti commit sarebbero stati elencati e sopprimere tutti gli altri output.HEADnomina il ramo corrente.@{u}si riferisce all'upstream locale del ramo corrente (configurato conbranch.<name>.remoteebranch.<name>.merge). C'è anche@{push}, di solito indica lo stesso di@{u}.<rev1>..<rev2>specifica l'intervallo di commit che include i commit raggiungibili da ma esclude quelli raggiungibili da . Quando o viene omesso, il valore predefinito è HEAD.
Puoi farlo con una combinazione di git merge-base e git rev-parse . Se git merge-base <branch> <remote branch> restituisce lo stesso di git rev-parse <remote branch> , allora la tua filiale locale è avanti. Se restituisce lo stesso di git rev-parse <branch> , allora la tua filiale locale è in ritardo. Se merge-base restituisce una risposta diversa rispetto a rev-parse , quindi i rami si sono separati e dovrai eseguire un'unione.
Sarebbe meglio fare un git fetch prima di controllare i rami, però, altrimenti la tua determinazione se devi o meno tirare sarà obsoleta. Dovrai anche verificare che ogni ramo che controlli abbia un ramo di tracciamento remoto. Puoi usare git for-each-ref --format='%(upstream:short)' refs/heads/<branch> fare quello. Quel comando restituirà il ramo di tracciamento remoto di <branch> o la stringa vuota se non ne ha una. Da qualche parte su SO c'è una versione diversa che restituirà un errore se il ramo non ha un ramo di tracciamento remoto, che potrebbe essere più utile per il tuo scopo.
Alla fine, l'ho implementato nel mio plugin git-ws C++11.
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;
Sembra funzionare finora. canPull deve ancora essere testato e implementato.
Spiegazione:
currentBranchottiene l'output della console, che è una stringa del nome del ramo correntecanCommitottiene se la console emette qualcosa (differenza tra le modifiche correnti e HEAD, ignorando i sottomoduli)canPushottiene il conteggio delle modifiche tra origin/currentBranche il repository locale - se> 0, il repository locale può essere inviato
Per riferimenti futuri. A partire da Git v2.17.0
git status -sb
contiene la parola dietro .In modo che possa essere utilizzato direttamente per verificare la presenza di tiri.
Nota:ricorda di eseguire git fetch prima di eseguire git status -sb