De cette réponse.
- Faire une récupération :
git fetch
. - Obtenir combien de commits la branche actuelle est en retard :
behind_count = $(git rev-list --count [email protected]{u})
. - Obtenez combien de commits la branche actuelle est en avance :
ahead_count = $(git rev-list --count @{u}..HEAD)
. (Il suppose que l'endroit où vous récupérez est l'endroit où vous poussez, voirpush.default
option de configuration). - Si les deux
behind_count
etahead_count
sont 0, alors la branche actuelle est à jour. - Si
behind_count
vaut 0 etahead_count
est supérieur à 0, alors la branche actuelle est en avance. - Si
behind_count
est supérieur à 0 etahead_count
est 0, alors la branche actuelle est derrière. - Si les deux
behind_count
etahead_count
sont supérieurs à 0, alors la branche actuelle est divergente.
Explication :
git rev-list
répertorier tous les commits de donner une plage de commits.--count
option affiche le nombre de commits qui auraient été répertoriés et supprime toutes les autres sorties.HEAD
nomme la branche actuelle.@{u}
fait référence à l'amont local de la branche actuelle (configuré avecbranch.<name>.remote
etbranch.<name>.merge
). Il y a aussi@{push}
, il pointe généralement vers le même que@{u}
.<rev1>..<rev2>
spécifie la plage de commits qui inclut les commits accessibles à partir de mais exclut ceux qui sont accessibles à partir de . Lorsque ou est omis, la valeur par défaut est HEAD.
Vous pouvez le faire avec une combinaison de git merge-base
et git rev-parse
. Si git merge-base <branch> <remote branch>
renvoie la même chose que git rev-parse <remote branch>
, alors votre succursale locale est en avance. S'il renvoie la même chose que git rev-parse <branch>
, alors votre succursale locale est en retard. Si merge-base
renvoie une réponse différente de rev-parse
, alors les branches ont divergé et vous devrez faire une fusion.
Le mieux serait de faire un git fetch
avant de vérifier les branches, sinon votre décision de savoir si vous devez ou non tirer sera obsolète. Vous voudrez également vérifier que chaque branche que vous vérifiez a une branche de suivi à distance. Vous pouvez utiliser git for-each-ref --format='%(upstream:short)' refs/heads/<branch>
pour faire ça. Cette commande renverra la branche de suivi à distance de <branch>
ou la chaîne vide si elle n'en a pas. Quelque part sur SO, il existe une version différente qui renverra une erreur si la branche n'a pas de branche de suivi à distance, ce qui peut être plus utile pour votre objectif.
Au final, j'ai implémenté cela dans mon 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;
Semble fonctionner jusqu'à présent. canPull
doit encore être testé et mis en œuvre.
Explication :
currentBranch
obtient la sortie de la console, qui est une chaîne du nom de la branche actuellecanCommit
obtient si la console affiche quelque chose (différence entre les changements actuels et HEAD, en ignorant les sous-modules)canPush
obtient le nombre de changements entre l'origine/currentBranch
et le dépôt local - si> 0
, le dépôt local peut être poussé
Pour référence future. À partir de Git v2.17.0
git status -sb
contient le mot derrière .Donc, cela peut être utilisé directement pour vérifier les tractions.
Remarque :N'oubliez pas d'exécuter git fetch
avant d'exécuter git status -sb