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.defaultoption de configuration). - Si les deux
behind_countetahead_countsont 0, alors la branche actuelle est à jour. - Si
behind_countvaut 0 etahead_countest supérieur à 0, alors la branche actuelle est en avance. - Si
behind_countest supérieur à 0 etahead_countest 0, alors la branche actuelle est derrière. - Si les deux
behind_countetahead_countsont supérieurs à 0, alors la branche actuelle est divergente.
Explication :
git rev-listrépertorier tous les commits de donner une plage de commits.--countoption affiche le nombre de commits qui auraient été répertoriés et supprime toutes les autres sorties.HEADnomme la branche actuelle.@{u}fait référence à l'amont local de la branche actuelle (configuré avecbranch.<name>.remoteetbranch.<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 :
currentBranchobtient la sortie de la console, qui est une chaîne du nom de la branche actuellecanCommitobtient si la console affiche quelque chose (différence entre les changements actuels et HEAD, en ignorant les sous-modules)canPushobtient le nombre de changements entre l'origine/currentBranchet 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