Comment vérifier si le référentiel distant a changé et que je dois tirer?
Maintenant, j'utilise ce script simple:
git pull --dry-run | grep -q -v 'Already up-to-date.' && changed=1
Mais c'est plutôt lourd.
Y a-t-il une meilleure façon? La solution idéale consisterait à vérifier toutes les branches distantes et à renvoyer les noms des branches modifiées et le nombre de nouvelles validations dans chacune.
git fetch -v --dry-run
ce dont vous avez besoin.Réponses:
Première utilisation
git remote update
, pour mettre à jour vos références de télécommande. Ensuite, vous pouvez effectuer plusieurs opérations, telles que:git status -uno
vous dira si la branche que vous suivez est devant, derrière ou a divergé. S'il ne dit rien, le local et le distant sont les mêmes.git show-branch *master
vous montrera les commits dans toutes les branches dont les noms se terminent par «master» (par exemple master et origin / master ).Si vous utilisez
-v
avecgit remote update
(git remote -v update
), vous pouvez voir quelles branches ont été mises à jour, vous n'avez donc pas vraiment besoin d'autres commandes.Cependant, il semble que vous souhaitiez le faire dans un script ou un programme et vous retrouver avec une valeur vraie / fausse. Dans l'affirmative, il existe des moyens de vérifier la relation entre votre validation HEAD actuelle et le chef de la branche que vous suivez, bien qu'il existe quatre résultats possibles, vous ne pouvez pas la réduire à une réponse oui / non. Cependant, si vous êtes prêt à le faire,
pull --rebase
vous pouvez traiter "local is behind" et "local has diverged" comme "need to pull", et les deux autres comme "don't need to pull".Vous pouvez obtenir l'ID de validation de n'importe quelle référence en utilisant
git rev-parse <ref>
, vous pouvez donc le faire pour master et origin / master et les comparer. S'ils sont égaux, les branches sont les mêmes. S'ils sont inégaux, vous voulez savoir ce qui est en avance sur l'autre. L'utilisationgit merge-base master origin/master
vous indiquera l'ancêtre commun des deux branches, et si elles n'ont pas divergé, ce sera la même chose que l'une ou l'autre. Si vous obtenez trois identifiants différents, les branches ont divergé.Pour le faire correctement, par exemple dans un script, vous devez être en mesure de vous référer à la branche actuelle et à la branche distante qu'elle suit. La fonction de configuration d'invite bash dans
/etc/bash_completion.d
contient du code utile pour obtenir les noms de branche. Cependant, vous n'avez probablement pas besoin d'obtenir les noms. Git a quelques raccourcis pour faire référence aux branches et commits (comme documenté dansgit rev-parse --help
). En particulier, vous pouvez utiliser@
pour la branche actuelle (en supposant que vous n'êtes pas dans un état de tête détachée) et@{u}
pour sa branche en amont (par exempleorigin/master
). Ainsigit merge-base @ @{u}
retournera le (hachage du) commit auquel la branche courante et son amont divergent etgit rev-parse @
etgit rev-parse @{u}
vous donnera les hachages des deux astuces. Cela peut être résumé dans le script suivant:Remarque: les anciennes versions de git ne le permettaient pas
@
, vous devrez donc peut-être utiliser à la@{0}
place.La ligne
UPSTREAM=${1:-'@{u}'}
vous permet éventuellement de passer explicitement une branche en amont, au cas où vous voudriez comparer avec une branche distante différente de celle configurée pour la branche actuelle. Il s'agit généralement de la forme nom distant / nom de branche . Si aucun paramètre n'est donné, la valeur par défaut est@{u}
.Le script suppose que vous avez fait une
git fetch
ou unegit remote update
première pour mettre à jour les branches de suivi. Je n'ai pas intégré cela dans le script car il est plus flexible de pouvoir faire la récupération et la comparaison en tant qu'opérations distinctes, par exemple si vous voulez comparer sans récupérer car vous avez déjà récupéré récemment.la source
git status -s -u no
, ce qui donne une sortie plus courte quegit status -u no
.git remote -v update
. Regardez la sortie degit remote --help
pour une explication plus complète.@{u}
fonctionne avec git 1.8.3.2 mais@
pas. Fonctionne cependant@
avec1.8.5.4
. Morale de l'histoire: git continue de s'améliorer et cela vaut la peine d'avoir la version la plus récente possible.Si vous avez une succursale en amont
Si vous n'avez pas de succursale en amont
Comparez les deux branches:
Par exemple:
(Je suppose que
origin/master
c'est votre branche de suivi à distance)Si des validations sont répertoriées dans la sortie ci-dessus, vous avez des modifications entrantes - vous devez fusionner. Si aucun commit n'est répertorié par,
git log
il n'y a rien à fusionner.Notez que cela fonctionnera même si vous êtes sur une branche de fonctionnalité - qui n'a pas de télécommande de suivi, car si elle fait explicitement référence au
origin/master
lieu d'utiliser implicitement la branche en amont mémorisée par Git.la source
git fetch; git log HEAD.. --oneline
peut être utilisée s'il existe une branche distante par défaut pour une branche locale.git rev-list HEAD...origin/master --count
vous donnera le nombre total de commits "différents" entre les deux.S'il s'agit d'un script, vous pouvez utiliser:
(Remarque: l'avantage de cette réponse par rapport aux réponses précédentes est que vous n'avez pas besoin d'une commande distincte pour obtenir le nom de la branche actuelle. "HEAD" et "@ {u}" (la branche actuelle en amont) s'en occupent. Voir "git rev-parse --help" pour plus de détails.)
la source
git rev-parse @{u}
fait le dernier commit sans ungit fetch
?==
ce qui signifie "s'il n'y a AUCUN changement depuis l'amont". J'avais l'habitude!=
de vérifier "s'il y a des changements en amont" pour mon application. N'oubliez pas degit fetch
commencer!@
est l'abréviation deHEAD
btw.@{u}
exemplegit rev-parse '@{u}'
La commande
affichera la tête actuelle sur la télécommande - vous pouvez la comparer à une valeur précédente ou voir si vous avez le SHA dans votre référentiel local.
la source
git rev-list HEAD...origin/master --count
vous donnera le nombre total de commits "différents" entre les deux.git fetch
ou d'git remote update
abord.git status
montre également un décompte, btw...
"commits en origine / master, en soustrayant HEAD" (ie nombre de commits derrière). Considérant que,...
est la différence symétrique (c'est-à-dire devant et derrière)fetch
.Voici un one-liner Bash qui compare le hachage de validation HEAD de la branche actuelle à sa branche en amont distante, sans lourdeur
git fetch
nigit pull --dry-run
opération requise:Voici comment cette ligne quelque peu dense est décomposée:
$(x)
Bash syntaxe de .git rev-parse --abbrev-ref @{u}
renvoie une référence abrégée en amont (par exempleorigin/master
), qui est ensuite convertie en champs séparés par des espaces par lased
commande canalisée , par exempleorigin master
.git ls-remote
laquelle renvoie le commit de tête de la branche distante. Cette commande communiquera avec le référentiel distant. Lacut
commande canalisée extrait uniquement le premier champ (le hachage de validation), supprimant la chaîne de référence séparée par des tabulations.git rev-parse HEAD
renvoie le hachage de validation local.[ a = b ] && x || y
complète le one-liner: il s'agit d'une comparaison de chaînes Bash=
dans une construction de test[ test ]
, suivie de constructions and-list et or-list&& true || false
.la source
Je vous suggère d'aller voir le script https://github.com/badele/gitcheck . J'ai codé ce script pour archiver en un seul passage tous vos référentiels Git, et il montre qui n'a pas commis et qui n'a pas poussé / tiré.
Voici un exemple de résultat:
la source
git mrepo -c
cela affichera toutes les validations en attente.J'ai basé cette solution sur les commentaires de @jberger.
la source
...
semble être une partie valide de votre solution.Il existe déjà de nombreuses réponses très riches et ingénieuses. Pour apporter un peu de contraste, je pourrais me contenter d'une ligne très simple.
la source
Je pense que la meilleure façon de procéder serait:
En supposant que vous avez enregistré cette refspec. Vous devriez, si vous avez cloné le référentiel, sinon (c'est-à-dire si le référentiel a été créé de novo localement et poussé sur la télécommande), vous devez ajouter explicitement la refspec.
la source
Le script ci-dessous fonctionne parfaitement.
la source
Je ferais la manière suggérée par brool. Le script d'une ligne suivant prend le SHA1 de votre dernière version validée et le compare à celui de l'origine distante, et ne récupère les modifications que si elles diffèrent. Et c'est encore plus léger des solutions basées sur
git pull
ougit fetch
.la source
git rev-parse --verify HEAD
git log --pretty=%H ...refs/heads/master^
pour obtenir le SHA1 de votre dernière version validée, puis exécutezgit ls-remote origin -h refs/heads/master |cut -f1
pour obtenir le SHA1 de l'origine distante. Ces deux sont des commandes git et n'ont rien à voir avec bash. Ce que bash fait à l'intérieur des crochets est de comparer la sortie de la première commande avec la seconde, et si elles sont égales, elle retourne vrai et s'exécutegit pull
.git pull
". Je sais que je suis nerveux, mais juste pour éviter la confusion de quelqu'un, cela devrait être "et s'ils ne sont pas égaux". De plus, pour une raison quelconque, la première commande git ne fonctionne pas pour moi. (Je suis sur git2.4.1
.) Donc j'utilise juste à lagit log --pretty=%H master | head -n1
place. Mais je ne sais pas si c'est exactement la même chose.Si vous exécutez ce script, il testera si la branche actuelle a besoin d'un
git pull
:Il est très pratique de le mettre en pré-commit du hook Git pour éviter
quand tu
commit
avantpulling
.Pour utiliser ce code comme hook, copiez / collez simplement le script dans
et
la source
Je veux juste poster ceci comme un message réel car il est facile de manquer cela dans les commentaires.
La réponse correcte et la meilleure pour cette question a été donnée par @Jake Berger, Merci beaucoup mec, tout le monde en a besoin et tout le monde le manque dans les commentaires. Donc, pour tous ceux qui luttent avec cela, voici la bonne réponse, utilisez simplement la sortie de cette commande pour savoir si vous avez besoin de faire un git pull. si la sortie est 0, il n'y a évidemment rien à mettre à jour.
@stackoverflow, donnez à ce gars une cloche. Merci @ Jake Berger
la source
Exécutez
git fetch (remote)
pour mettre à jour vos références distantes, il vous montrera les nouveautés. Ensuite, lorsque vous passez à la caisse de votre succursale locale, elle vous indique si elle est en amont.la source
git status
cela le montrera également.git pull --dry-run
, mais je pense que c'est trop lourd pour un script cron exécuté chaque minute.fetch
, cela ne va pas faire beaucoup plus que de vérifier le statut. Si vous avez besoin d'une réaction très rapide et légère sur les mises à jour à distance, vous voudrez peut-être envisager de connecter une sorte de notifications au référentiel distant.Toutes ces suggestions complexes alors que la solution est si courte et si simple:
la source
git remote update
exécutée avant votre code, pour obtenir les dernières informations de validation d'originegit remote update
pas s'ajouter avant lesgit show
commandes?Voici ma version d'un script Bash qui vérifie tous les référentiels dans un dossier prédéfini:
https://gist.github.com/henryiii/5841984
Il peut faire la différence entre des situations courantes, comme la traction nécessaire et la poussée nécessaire, et il est multithread, de sorte que la récupération se produit en même temps. Il a plusieurs commandes, comme pull et status.
Mettez un lien symbolique (ou le script) dans un dossier de votre chemin, puis cela fonctionne comme
git all status
(, etc.). Il ne prend en charge que l'origine / master, mais il peut être modifié ou combiné avec une autre méthode.la source
répertorie tout ce qui est référencé dans toute télécommande qui n'est pas dans votre référentiel. Pour attraper les changements de référence à distance sur des choses que vous aviez déjà (par exemple, réinitialise les validations précédentes) prend un peu plus:
la source
Peut-être cela, si vous souhaitez ajouter une tâche en tant que crontab:
la source
Utilisation d'une expression rationnelle simple:
la source
J'utilise une version d'un script basé sur la réponse de Stephen Haberman:
En supposant que ce script est appelé
git-fetch-and-rebase
, il peut être invoqué avec un argument facultatifdirectory name
du référentiel Git local pour effectuer l'opération. Si le script est appelé sans arguments, il suppose que le répertoire courant fait partie du référentiel Git.Exemples:
Il est également disponible ici .
la source
Après avoir lu de nombreuses réponses et plusieurs articles, et passé une demi-journée à essayer différentes permutations, voici ce que j'ai trouvé.
Si vous êtes sous Windows, vous pouvez exécuter ce script dans Windows en utilisant Git Bash fourni par Git pour Windows (installation ou portable).
Ce script nécessite des arguments
Le script
S'il y a un changement tel qu'imprimé par le script, vous pouvez alors procéder à la récupération ou à l'extraction. Le script n'est peut-être pas efficace, mais il fait le travail pour moi.
Mise à jour - 30/10/2015: stderr dev dev null pour empêcher l'impression de l'URL avec le mot de passe sur la console.
la source
Pour les utilisateurs de Windows qui se retrouvent sur cette question à la recherche de cela, j'ai modifié une partie de la réponse en un script PowerShell. Ajustez si nécessaire, enregistrez dans un
.ps1
fichier et exécutez à la demande ou planifié si vous le souhaitez.la source
Parce que la réponse de Neils m'a tellement aidé, voici une traduction Python sans dépendances:
hth
la source
Vous pouvez également trouver un script Phing qui le fait maintenant.
J'avais besoin d'une solution pour mettre à jour automatiquement mes environnements de production et nous sommes très heureux grâce à ce script que je partage.
Le script est écrit en XML et nécessite Phing .
la source