Da questa risposta.
- Esegui un recupero:
git fetch
. - Ottieni quanti commit è presente nel branch corrente:
behind_count = $(git rev-list --count [email protected]{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.default
opzione di configurazione). - Se entrambi
behind_count
eahead_count
sono 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_count
eahead_count
sono maggiori di 0, allora il ramo corrente è divergente.
Spiegazione:
git rev-list
elenca tutti i commit di dare un intervallo di commit.--count
option output quanti commit sarebbero stati elencati e sopprimere tutti gli altri output.HEAD
nomina il ramo corrente.@{u}
si riferisce all'upstream locale del ramo corrente (configurato conbranch.<name>.remote
ebranch.<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:
currentBranch
ottiene l'output della console, che è una stringa del nome del ramo correntecanCommit
ottiene se la console emette qualcosa (differenza tra le modifiche correnti e HEAD, ignorando i sottomoduli)canPush
ottiene il conteggio delle modifiche tra origin/currentBranch
e 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