Pourquoi git status show branch est-il à jour quand des changements existent en amont?


226

Des changements existent en amont dans une branche suivie, mais lorsque je tape git statuscela indique que ma branche locale est à jour. Est-ce un nouveau comportement, ai-je changé un paramètre de configuration ou quelque chose ne va pas?

Merci pour l'aide.

ubuntu@host:/my/repo# git status
On branch master
Your branch is up-to-date with 'origin/master'.

nothing to commit, working directory clean


ubuntu@host:/my/repo# git pull
remote: Counting objects: 11, done.
remote: Compressing objects: 100% (11/11), done.
remote: Total 11 (delta 6), reused 0 (delta 0)
Unpacking objects: 100% (11/11), done.
From bitbucket.org:my/repo
   1234567..abcdefg  master     -> origin/master
Updating 1234567..abcdefg
Fast-forward
 file1        |  1 -
 file2        | 43 +++++++++++++++++++++++++++++++++++++++++++
 file3        | 21 ++++++++++++---------
 file4        | 21 ++++++++++++---------
 4 files changed, 67 insertions(+), 19 deletions(-)
 create mode 100644 file5

Réponses:


274

Ce que le statut vous dit, c'est que vous êtes derrière l'arbitre appelé, origin/master qui est un arbitre local dans votre référentiel local . Dans ce cas, cette référence arrive à suivre une branche dans une télécommande, appelée origin, mais l'état ne vous dit rien sur la branche sur la télécommande. Il vous parle de la référence, qui n'est qu'un ID de validation stocké sur votre système de fichiers local (dans ce cas, il se trouve généralement dans un fichier appelé .git/refs/remotes/origin/masterdans votre référentiel local).

git pullfait deux opérations; tout d'abord, il effectue une git fetchmise à jour des validations dans le référentiel distant (qui met à jour la origin/masterréférence dans votre référentiel local), puis il git mergefusionne ces validations dans la branche actuelle.

Tant que vous ne faites fetchpas l' étape (seule ou via git pull), votre référentiel local n'a aucun moyen de savoir qu'il y a des commits supplémentaires en amont et git statusne regarde que votre origin/masterréférence locale .

Quand git statusdit à jour, cela signifie "à jour avec la branche que la branche actuelle suit", ce qui signifie dans ce cas "à jour avec la référence locale appelée origin/master". Cela équivaut seulement à "à jour avec le statut en amont qui a été récupéré la dernière fois que nous avons fait un fetch" qui n'est pas la même chose que "à jour avec le dernier statut en direct de l'amont".

Pourquoi ça marche comme ça? Eh bien, l' fetchétape est une opération réseau potentiellement lente et coûteuse. La conception de Git (et d'autres systèmes de contrôle de version distribués ) vise à éviter les opérations réseau lorsque cela n'est pas nécessaire, et est un modèle complètement différent du système client-serveur typique auquel de nombreuses personnes sont habituées (bien que, comme indiqué dans les commentaires ci-dessous, le concept de Git d'une "branche de suivi à distance" qui provoque ici une confusion n'est pas partagée par tous les DVCS). Il est tout à fait possible d'utiliser Git hors ligne, sans connexion à un serveur centralisé, et la sortie de git statusreflète cela.

La création et la commutation de branches (et la vérification de leur état) dans Git est censée être légère, pas quelque chose qui effectue une opération réseau lente vers un système centralisé. L'hypothèse lors de la conception de Git et de la git statussortie était que les utilisateurs le comprennent (trop de fonctionnalités Git n'ont de sens que si vous savez déjà comment Git fonctionne). Avec l'adoption de Git par de nombreux utilisateurs qui ne connaissent pas le DVCS, cette hypothèse n'est pas toujours valable.


79
Un commentaire tardif mais je suis tombé sur la même situation. Je comprends pourquoi git n'a aucun moyen de connaître les changements avant d'aller chercher. Mais alors il ne devrait pas dire «à jour», ce qui n'est tout simplement pas vrai. Il vaut mieux dire "aucune idée de ce qui aurait pu se produire à distance".
Droidum

31
C'est peut-être strictement logique, mais ce n'est pas du tout raisonnable pour l'homme. Pourquoi ne le concevriez-vous pas pour FAIRE une extraction et ALORS déclarer s'il est à jour? Ou changez le message pour dire ce qu'il a vraiment fait, par exemple "Votre branche était à jour avec 'origine / maître' lors de la dernière vérification à {horodatage}"? Ou même simplement dire: «Faites une recherche pour savoir si votre succursale est à jour»?
Colin

25
pourquoi se donner la peine de montrer le message "Votre succursale est à jour"? Je ne vois pas l'intérêt de connaître le statut d'origine / maître, et s'il est censé représenter la branche maître réelle sur la télécommande d'origine, alors il n'a clairement aucune idée de toute façon.
whiterook6

2
@pastullo, créez donc un alias.
Jonathan Wakely

23
Ceci est un parfait exemple de la terrifiante facilité d'utilisation de Git. J'adore sa puissance et sa flexibilité, mais en changeant simplement le message en quelque chose comme "Votre branche est à jour avec la version locale de 'origin / master'." serait une énorme amélioration. La confusion ici est que l'origine / master de la branche locale (correspondance de modèle avec les télécommandes / branches que vous utilisez) qui suit une branche distante.
matthewcummings516

35

En effet, votre référentiel local ne s'est pas enregistré avec les télécommandes en amont. Pour que ce travail fonctionne comme prévu, utilisez git fetchpuis exécutez à git statusnouveau un .


7

Bien que ce soient toutes des réponses viables, j'ai décidé de donner ma façon de vérifier si le dépôt local est en ligne avec la télécommande, sans aller chercher ni tirer. Pour voir où sont mes succursales, j'utilise simplement:

git remote show origin

Ce qu'il fait, c'est renvoyer toutes les branches suivies actuelles et, plus important encore, les informations, qu'elles soient à jour, devant ou derrière celles d'origine distante. Après la commande ci-dessus, voici un exemple de ce qui est retourné:

  * remote origin
  Fetch URL: https://github.com/xxxx/xxxx.git
  Push  URL: https://github.com/xxxx/xxxx.git
  HEAD branch: master
  Remote branches:
    master      tracked
    no-payments tracked
  Local branches configured for 'git pull':
    master      merges with remote master
    no-payments merges with remote no-payments
  Local refs configured for 'git push':
    master      pushes to master      (local out of date)
    no-payments pushes to no-payments (local out of date)

J'espère que cela aide quelqu'un.


0

"origine / maître" fait référence à la référence poiting à la validation HEAD de la branche "origine / maître". Une référence est un nom d'alias convivial pour un objet Git, généralement un objet commit. La référence "origin / master" n'est mise à jour que lorsque vous git pushvous connectez à votre télécommande ( http://git-scm.com/book/en/v2/Git-Internals-Git-References#Remotes ).

Depuis la racine de votre projet, exécutez:

cat .git/refs/remotes/origin/master

Comparez l'ID de validation affiché avec:

cat .git/refs/heads/master

Ils devraient être les mêmes, et c'est pourquoi Git dit qu'il masterest à jour origin/master.

Quand tu cours

git fetch origin master

Cela récupère les nouveaux objets Git localement sous le dossier .git / objects. Et Git met à jour .git / FETCH_HEAD pour que maintenant, il pointe vers le dernier commit de la branche récupérée.

Donc, pour voir les différences entre votre branche locale actuelle et la branche récupérée en amont, vous pouvez exécuter

git diff HEAD FETCH_HEAD

1
Vous ne devriez pas cat les éléments dans le répertoire .git, cela ne fonctionnera pas avec des références emballées. Le comportement d'extraction que vous avez décrit concerne également les anciennes versions de git.
Andrew C

la origin/masterréférence n'est-elle pas également mise à jour par une extraction, ainsi qu'une poussée?
Jonathan Wakely

Correct. J'utilisais Git 1.8.3 jusqu'à présent. Je peux en effet remarquer qu'avec la version 2.2.1, FETCH_HEAD est également mis à jour lors d'une extraction. De même, en ce qui concerne le message "Votre branche est à jour avec ..." ou "Votre branche est derrière ... par X commits", elle n'apparaît que si votre branche locale suit une branche distante donnée. Pour que master puisse suivre l'origine / master, il faut exécuter git branch -u origin / master depuis branch master. S'il n'y a pas de suivi, vous devez toujours exécuter git diff.
Marek Stanley

Eh bien, je vous suggère de corriger l'affirmation selon laquelle la référence "origine / maître" n'est mise à jour que lorsque vous appuyez sur votre télécommande "
Jonathan Wakely

0

Regardons un exemple de dépôt git pour vérifier si your branch (master)c'est up to dateavec origin/master.

Vérifiez que le maître local suit l'origine / le maître:

$ git branch -vv
* master a357df1eb [origin/master] This is a commit message

Plus d'informations sur la branche maître locale:

$ git show --summary
commit a357df1eb941beb5cac3601153f063dae7faf5a8 (HEAD -> master, tag: 2.8.0, origin/master, origin/HEAD)
Author: ...
Date:   Tue Dec 11 14:25:52 2018 +0100

    Another commit message

Vérifiez si origin / master est sur le même commit:

$ cat .git/packed-refs | grep origin/master
a357df1eb941beb5cac3601153f063dae7faf5a8 refs/remotes/origin/master

Nous pouvons voir le même hachage autour, et sûr de dire que la branche est en cohérence avec celle distante, au moins dans le dépôt git actuel.



0

Réponse triviale mais exacte dans certains cas, comme celle qui m'a amené ici. Je travaillais dans un dépôt qui était nouveau pour moi et j'ai ajouté un fichier qui n'était pas considéré comme nouveau par le statut.

Il en résulte que le fichier correspond à un modèle dans le fichier .gitignore.


0

dans ce cas, utilisez git add et intégrez tous les fichiers en attente, puis utilisez git commit puis git push

git add - intègre tous les fichiers pedent

git commit - sauvegarde le commit

git push - enregistrer dans le référentiel

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.