IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

GIT Discussion :

Divergence surprenante entre dépôts


Sujet :

GIT

  1. #1
    Membre émérite
    Profil pro
    Développeur Web
    Inscrit en
    Février 2008
    Messages
    3 398
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Février 2008
    Messages : 3 398
    Par défaut Divergence surprenante entre dépôts
    Bonjour tout le monde,

    Après avoir restauré une sauvegarde, j'ai vu que j'avais un certain nombre de modifications à annuler car sinon un formulaire ignorait les clics de souris.

    J'ai fait ça, ça marche, mais après encore s'agit-il de m'occuper du dépôt "distant".

    Je suis allé dedans en ligne de commande, puis j'ai tapé

    Puis de retour dans le dépôt "local" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    git status
    On branch master
    Your branch is ahead of 'origin/master' by 1 commit.
      (use "git push" to publish your local commits)
    
    nothing to commit, working tree clean
    Je m'attends à pouvoir faire un git push, pas vrai ?

    Que nenni : Visual Studio a encore un historique pour remotes\origin, et si je tente un push avec synchronisation je me retrouve avec des conflits.

    Et pareil si dans Visual Studio je clique dans le menu contextuel de remotes\origin, sur Réinitialiser.

    Euh ... init, ça ne veut pas dire tout remettre à zéro ?
    Surtout que j'ai supprimé le répertoire .git (distant) avant d'y taper git init.

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 609
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 609
    Par défaut
    Hello

    Après avoir restauré une sauvegarde, j'ai vu que j'avais un certain nombre de modifications à annuler car sinon un formulaire ignorait les clics de souris. J'ai fait ça, ça marche, mais après encore s'agit-il de m'occuper du dépôt "distant".
    En fait, il va falloir que tu nous rappelles brièvement où se trouve le dépôt local et où est le « distant ».


    Je suis allé dedans en ligne de commande, puis j'ai tapé


    Euh ... init, ça ne veut pas dire tout remettre à zéro ?

    En réalité, non : git init sert à initialiser un nouveau dépôt Git s'il n'existe pas encore. En ce sens, pour cela, il va effectivement créer un sous-répertoire .git dans le répertoire courant (depuis lequel la commande a été lancée) pour pouvoir commencer à effectuer un suivi. Donc, déjà, à ce stade, il n'efface pas le contenu du répertoire déjà existant, ne serait-ce que par principe mais également, et surtout, parce que c'est probablement lui que l'on veut versionner.

    Si le dépôt est déjà initialisé, il ne se passera globalement rien. Si on lit la man page, on lit :

    Citation Envoyé par man git
    Running git init in an existing repository is safe. It will not overwrite things that are already there. The primary reason for rerunning git init is to pick up newly added
    templates (or to move the repository to another place if --separate-git-dir is given).

    Je n'en sais pas beaucoup plus car je n'ai encore jamais été confronté au cas, mais les tests montrent qu'en local, même l'état de l'index est préservé.

    Surtout que j'ai supprimé le répertoire .git (distant) avant d'y taper git init
    Dans ce cas, effectivement, tu as supprimé la totalité de l'historique de l'ancien dépôt et créé un nouveau, même si tu as préservé les fichiers du working directory. Ça veut dire que de ce côté-là, aucun commit n'a été effectué et l'historique est vierge. Cela signifie aussi qu'il n'y a plus aucune connaissance d'éventuels dépôts dans son voisinage.

    Puis de retour dans le dépôt "local" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    git status
    On branch master
    Your branch is ahead of 'origin/master' by 1 commit.
      (use "git push" to publish your local commits)
    
    nothing to commit, working tree clean
    Je m'attends à pouvoir faire un git push, pas vrai ?

    Que nenni : Visual Studio a encore un historique pour remotes\origin, et si je tente un push avec synchronisation je me retrouve avec des conflits.

    Et pareil si dans Visual Studio je clique dans le menu contextuel de remotes\origin, sur Réinitialiser.
    Oui, c'est normal car comme expliqué la dernière fois, Git n'explore un dépôt distant que lorsqu'il y a réellement besoin de le faire. Le reste du temps, il utilise le « dernier état connu » des branches des dépôts distants. Ce sont les branches qui se trouvent bien dans ton dépôt local mais sous le nom « remote/origin/… ».

    Donc ici, dans ton dépôt local, tu as bien une branche master qui correspond à son dernier état en date et une branche remote/origin/master qui, elle, pointe en local le même objet que la branche master du dépôt distant. Ton dépôt local ne « sait donc pas encore » que le dépôt distant a été réinitialisé.

    Tu peux lancer un git remote update pour mettre à jour en une fois la totalité de ce que l'on sait des dépôts distants.

  3. #3
    Membre émérite
    Profil pro
    Développeur Web
    Inscrit en
    Février 2008
    Messages
    3 398
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Février 2008
    Messages : 3 398
    Par défaut
    Ah, oui, il y a du taf.

    Bon alors déjà les chemins, le répertoire de développement est
    C:\Projects Visual Studio\WinForm\ListIrfanView

    et le dépôt "distant"
    C:\Projects Visual Studio\NewRepo\ListIrfanView

    du moins depuis hier, puisqu'avant une réparation de la machine le dépôt était sur le même chemin mais sur D:, et j'avais oublié de faire la mise à jour. Ce qui explique que ce que j'ai trouvé dedans remonte à un paquet de mois, contrairement à ce à quoi je m'attendais.

    Tout effacé, c'est vite dit, car Visual Studio m'indique encore un historique pour le dépôt local, et un autre historique pour le dépôt "distant", et je me demande bien d'où il sort celui-ci.

    Mais je dois dire que j'ai pas mal de lecture en perspective du coup.

    Alors donc, Git garde en local une image du dépôt distant, et la met à jour à la demande. Je m'attendais à pouvoir purger ça avec la commande "réinitialiser" du menu contextuel. J'ai aussi essayé une autre commande dont j'ai oublié l'intitulé exact, mais dans l'idée effacer les modifications. Il semble que j'aie mal interprété l'intitulé de la commande.

  4. #4
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 609
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 609
    Par défaut
    En fait, c'est beaucoup plus simple. C'est même presque « trivial » une fois que l'on comprend le schéma de principe mais, en effet, tant que l'on ne sait pas quel modèle Git adopte, on se visualise son fonctionnement en s'appuyant sur celui d'autres systèmes, qui sans être foncièrement compliqués restent malgré tout assez différents. Et de fait, cela rend les choses assez absconses.

    • L'historique de Git est un « graphe », formé par les différents commits qui se référencent entre eux. Chaque sommet de ce graphe est un commit ;
    • Les « commits » en particulier sont un des quatre types d'objets que Git définit : commit, tree, blob ou annotated tag ;
    • Chaque objet est un fichier (dans .git/objects) et le nom de chaque objet est la somme SHA-1 de son contenu, ce qui les rend immuables (impossible de modifier leur contenu sans modifier leur somme, qui ne correspondrait plus à leur nom) ;
    • Les commits font référence aux autres objets par leur nom, donc par leur somme SHA-1. Comme toutes ces références arrières font partie des informations d'un commit et que celui-ci est signé de la même manière, cela forme de fait une blockchain (et ce depuis 2005, c'est-à-dire bien avant que Bitcoin ne popularise le principe).


    De là, la structure du graphe étant intrinsèque, les « branches » en elles-mêmes ne sont en fait que des références vers le commit du haut de la branche, depuis lequel on peut ensuite la remonter. Git les gère sous la forme de simples fichiers là-aussi (cette fois dans .git/refs) qui contiennent exactement le nom du commit référencé, comme un lien symbolique Unix contient exactement le fichier vers le fichier pointé, et uniquement ce chemin.

    Ce qui est important, c'est que ces objets étant immuables, ce sont les mêmes du côté local et du côté distant, ainsi que sur tous les dépôts sur lesquels ils se trouvent sur la planète. De fait, lorsque tes dépôts sont synchrones et à jour, les branches homologues pointent le même objet (car elles contiennent la même somme SHA-1).

    Exemple :

    
                              master → O ← origin/master (7fd5a) dernier commit en date
                                      / \
                                     /   \
                                    ↙     ↘
        Commit principal 5 (44567) O       O (56842) Commit secondaire « c »
                                   |       |
                                   ↓       ↓
        Commit principal 4 (1023f) O       |
                                   |       |
                                   ↓       ↓
        Commit principal 3 (99fac) O       O (af675) Commit secondaire « b »
                                   |       |
                                   ↓       ↓
        Commit principal 2 (78abc) O       |
                                   |       |
                                   ↓       ↓
        Commit principal 1 (56457) O       O (8bc42) Commit secondaire « a »
                                    \     /
                                     \   /
                                      ↘ ↙
                                       O (123fe) Premier commit commun
                                       |
                                       ↓
                                       O (bbcda) Commit initial
    
    
    
    Si l'on provoque l'affichage de l'état des branches connues du dépôt local (branches locales et distantes) avec git branch -vva, on obtient :

    * master                                      7fd5a [origin/master] v2release : prise en compte de la migration du framework
      remotes/origin/HEAD                         -> origin/master
      remotes/origin/master                       7fd5a v2release : prise en compte de la migration du framework
    On voit bien que les branches master et origin/master référencent le même objet, donc se trouvent au même endroit dans le graphe (et par conséquent, dans l'historique). On peut même aller explorer directement les fichiers concernés (avec cat, ou type sous Windows) :

    $ cat .git/refs/heads/master
    7fd5af02096ee0c6dd00c07f939d51a5b0d7da47
    
    $ cat .git/refs/remotes/origin/master
    7fd5af02096ee0c6dd00c07f939d51a5b0d7da47
    Autre chose importante : les objets eux-mêmes sont tous individuels (même s'ils font référence les uns aux autres). Soit Git les produit lui-même, soit il les télécharge depuis l'extérieur mais, in fine, ils finissent tous « en vrac » au même endroit sous .git/objects.

    Lorsque tu mets un dépôt à jour, même partiellement, que soit via fetch, push, pull ou remote update, Git récupère d'abord l'état de ces branches pour les mettre à jour. Il examine ensuite le nom de l'objet référencé par chaque branche et là, soit il possède déjà l'objet en question et il peut directement passer à la suite, soit il ne l'a pas encore et il va demander au dépôt distant de lui envoyer. Il va alors examiner le contenu de cet objet à la recherche d'autres références et s'il en trouve, vérifier s'il possède aussi les objets concernés et donc, demander à se les faire envoyer également et appliquer la même procédure, récursivement. C'est de cette manière que Git peut « tirer le fil » et reconstituer l'intégralité de l'historique qui lui manque, fût-ce même à partir de rien.

    Ce qui nous amène à la situation qui t'intéresse : chaque dépot (local ou distant) possède donc sa propre copie de chaque objet. Par contre : ton dépôt local ne tient pas une « image » du dépôt distant. Il « sait » simplement que les branches distantes pointent les objets d'un même graphe, sur lequel il travaille déjà.

    Lorsque tu lances git status, Git compare simplement le dernier état connu de tes branches locales et de celles des serveurs distants pour savoir combien de commits les sépare, état récupéré la dernière fois qu'il s'est connecté à ces serveurs et qu'il conserve en local dans les fameuses branches « remotes/… ».

    Ces branches « remotes/… » sont ensuite mises à jour chaque fois que l'on y fait référence avec fetch, pull ou push, ou lorsque l'on fait la gestion des dépôts distants en particulier avec git remote. Cette dernière commande permet d'effectuer beaucoup d'opérations de maintenance dessus et, parmi elles, update te permet de mettre à jour un dépôt distant en particulier, ou tous les dépôts distants déclarés si aucun d'eux n'est explicitement spécifié.

  5. #5
    Membre émérite
    Profil pro
    Développeur Web
    Inscrit en
    Février 2008
    Messages
    3 398
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Février 2008
    Messages : 3 398
    Par défaut
    Bon, d'accord, il y a certainement à méditer là-dessus (car énoncer les vérités est assez simple, sous réserve de les connaître au départ, les assimiler mérite de méditer un peu).

    Mais quand même, le dépôt distant est supposé être une copie du dépôt original ?
    Curieusement d'ailleurs, origin n'est pas le dépôt original, mais bon peu importe.

    Donc, à ce qu'il me semble, il devrait y avoir moyen de le supprimer, d'en créer un autre, et d'y envoyer les informations pour qu'il soit à son tour une copie de l'original ?

    ***
    Ah, oui, en relisant un petit coup je vois

    Une fois que ça sera entré, ce sera plus rapide d'en remettre une couche, sans qu'il y ait besoin de ... méditer de nouveau.

    ***
    Bon mais pour le moment, je n'en suis pas encore là : même après "git remote update", le "git push" échoue encore.
    Les deux dernières modifs sont enregistrées en local, mais le dépôt distant n'en a toujours pas connaissance.

  6. #6
    Membre émérite
    Profil pro
    Développeur Web
    Inscrit en
    Février 2008
    Messages
    3 398
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Février 2008
    Messages : 3 398
    Par défaut
    Je suis intrigué par la commande pour connaître les URL des dépôts distants.

    Si je tape
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    git remote get-url --all
    il me dit de répéter, tant que je le fais.

    Il n'y a qu'une fois que je lui dis
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    git remote get-url origin --all
    que là il comprend ce que je lui dis.

    Est-ce qu'il y a moyen de lui dire que --all ça veut dire "tous" ?

  7. #7
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 609
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 609
    Par défaut
    Citation Envoyé par Gluups Voir le message
    Bon, d'accord, il y a certainement à méditer là-dessus (car énoncer les vérités est assez simple, sous réserve de les connaître au départ, les assimiler mérite de méditer un peu).
    En effet, c'est toujours beaucoup plus simple quand on sait déjà de quoi il s'agit. Il fallait quand même rappeler ces principes mais également mettre un terme au précédent post qui commençait à être un peu long et dont la rédaction a pris beaucoup de temps.

    Mais quand même, le dépôt distant est supposé être une copie du dépôt original ?
    Oui et non :

    Tout ce qui est commun est censé l'être rigoureusement (puisqu'il s'agit des mêmes objets), lorsque l'on travaille sur une branche commune ou lorsque l'on pousse sa branche de travail vers le serveur (ce qui est la même chose). En revanche, l'un comme l'autre peuvent posséder en plus du matériel qui ne se trouve pas (ou pas encore) de l'autre côté. Ça peut être une branche privée, comme ça peut être le dernier travail en date sur une branche commune et qui n'a pas encore été poussé.

    Par contre, un même dépôt (local ou distant, aucune importance ici) n'a qu'une seule et unique collection d'objets (ceux que l'on trouve dans .git/objects). Donc ton dépôt local ne conserve pas « une copie cachée du dépôt distant » pour comparaison. Il ne maintient à jour que l'état des différentes références (branches, tags, HEAD…) constatées sur les dépôts distants chaque fois qu'il entre en relation avec eux.

    Si deux branches distinctes contiennent la même signature, c'est qu'elle référencent le même objet. Objet qui non seulement recèle forcément le même contenu sur toutes les machines où on le trouve, mais dont les ancêtres sont forcément les mêmes partout également puisque les références à ces ancêtres font partie du contenu de l'objet (et participent donc à définir sa signature). Et comme la même règle s'applique pour ces ancêtres également, la simple signature d'un commit suffit à se localiser dans l'historique d'un projet, quel qu'il soit.

    Ainsi, si master et origin/master (qui reflète le dernier état connu de « master » sur le dépôt distant « origin ») contiennent la même signature, alors elle pointeront le même fichier dans .git/object sur ton dépôt local.


    Curieusement d'ailleurs, origin n'est pas le dépôt original, mais bon peu importe.
    Ça importe un peu plus qu'on pourrait le penser : ça ne change rien au principe global exposé ici mais les branches distantes font référence aux dépôts extérieurs par leur nom. Si « origin » ne pointe pas le bon mais que c'est toujours lui que tes branches suivent, ça peut expliquer certains de tes ennuis également.

    Donc, à ce qu'il me semble, il devrait y avoir moyen de le supprimer, d'en créer un autre, et d'y envoyer les informations pour qu'il soit à son tour une copie de l'original ?
    Absolument.
    Il faut juste garder à l'esprit que ce faisant, tu vas perdre également les branches « /remote/<LeDépotConcerné>/… ».

    Cela implique que si certaines branches locales sont configurées pour suivre l'état d'une de ces branches distantes (par exemple, master jumelée avec origin/master), alors ces branches locales vont également perdre cette configuration et ne sauront plus vers où il faut pousser la prochaine fois. Il faudra donc les reconfigurer pour les faire pointer vers le nouveau dépôt.

    Pas de panique toutefois, ça se fait en une seule commande (par branche).

    Ah, oui, en relisant un petit coup je vois
    Une fois que ça sera entré, ce sera plus rapide d'en remettre une couche, sans qu'il y ait besoin de ... méditer de nouveau.

    Bon mais pour le moment, je n'en suis pas encore là : même après "git remote update", le "git push" échoue encore.
    Voila. Tu dois en être à l'étape exposée au paragraphe précédent.

    Citation Envoyé par Gluups Voir le message
    Je suis intrigué par la commande pour connaître les URL des dépôts distants.

    Si je tape
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    git remote get-url --all
    il me dit de répéter, tant que je le fais.

    Il n'y a qu'une fois que je lui dis
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    git remote get-url origin --all
    que là il comprend ce que je lui dis.
    En fait, il peut y avoir plusieurs URL par dépôt (principalement s'il y a des accès différents pour fetch et push), comme expliqué dans la man page :

    Citation Envoyé par man git remote
    get-url
    Retrieves the URLs for a remote. Configurations for insteadOf and pushInsteadOf are expanded here. By default, only the first URL is listed.

    With --push, push URLs are queried rather than fetch URLs.

    With --all, all URLs for the remote will be listed.

    Ici, --all ne signifie pas « tous les dépôts » mais indique à Git de lister toutes les URL d'un même dépôt, faute de quoi il n'affiche que la première par défaut. Mais il faut toujours préciser le nom du dépôt en question.

    Tu peux en revanche utiliser :

    ou

    … pour lister tous les dépôts avec toutes les URL.

    Rappel : show est la sous-commande par défaut de la section remote lorsque l'on n'en précise aucune, et -v indique à git remote d'être « verbose ». Il faut ici placer « -v » avant « show » car autrement, git considère que l'option s'applique à la sous-commande en particulier et elle peut ne pas être définie dans ce contexte.

  8. #8
    Membre émérite
    Profil pro
    Développeur Web
    Inscrit en
    Février 2008
    Messages
    3 398
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Février 2008
    Messages : 3 398
    Par défaut
    Dans le message précédent je n'avais pas encore remarqué le graphe. Apparemment ma lecture se pratique par petites touches, si je comprends bien c'est un peu comme ça que fonctionne Git aussi.

    Et je réalise que si j'appelle origin un dépôt dans un autre répertoire, si ensuite je viens à mettre une copie en ligne, il faudra que je lui donne un autre nom que origin, sinon ça aura du mal à être clair.

    Ah oui mais dans Visual Studio il y a une interface pour "pousser", ça serait intéressant qu'elle pousse vers les deux.
    Bon mais là je ne suis pas arrivé au bout de la maturation là-dessus.

  9. #9
    Membre émérite
    Profil pro
    Développeur Web
    Inscrit en
    Février 2008
    Messages
    3 398
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Février 2008
    Messages : 3 398
    Par défaut
    Il faut que je prévoie d'y revenir de temps en temps, apparemment je n'ai pas encore bien assimilé tout ce que je devrais.
    Pour le moment, comme le dépôt sert de sauvegarde et que c'est dangereux de le laisser bloqué trop longtemps, j'ai triché, avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    git config receive.denyCurrentBranch warn
    et là ça a été comme si il n'y avait jamais eu de problème. J'ai pu faire un "git push", et cette fois tout est synchrone.

    La semaine qui vient mon esprit va encore être pas mal occupé avec autre chose, après je vais tâcher de m'y remettre.

    Ah oui il se peut que la notion de "bare repository" doive être révisée, aussi.

  10. #10
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 609
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 609
    Par défaut
    Citation Envoyé par Gluups Voir le message
    Il faut que je prévoie d'y revenir de temps en temps, apparemment je n'ai pas encore bien assimilé tout ce que je devrais.
    Pour le moment, comme le dépôt sert de sauvegarde et que c'est dangereux de le laisser bloqué trop longtemps, j'ai triché, avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    git config receive.denyCurrentBranch warn
    et là ça a été comme si il n'y avait jamais eu de problème. J'ai pu faire un "git push", et cette fois tout est synchrone.
    Ah oui, Git t'as posé des problèmes avec les dépôts non-bare. Ce n'est pas très grave dans ta situation, en effet.

    Vérifie tout de même que, bien que synchrones, l'état des deux dépôts soit le bon (si l'historique est vide des deux côtés, ce sera bien synchrone mais probablement pas l'état attendu :-)

    La semaine qui vient mon esprit va encore être pas mal occupé avec autre chose, après je vais tâcher de m'y remettre.

    Ah oui il se peut que la notion de "bare repository" doive être révisée, aussi.
    Pas très difficile : un dépôt « bare » est un dépôt « nu »., c'est-à-dire dépouillé du working directory.

    En temps normal, quand on initialise un nouveau dépôt avec git init, le répertoire courant devient un dépôt parce que Git y crée un sous-répertoire .git dans lequel il va mettre l'intégralité de l'historique, des objets et de ses méta-données. Le répertoire proprement dit devient alors le « répertoire de travail » (working directory) puisque c'est à cet endroit que l'on va écrire les fichiers que l'on souhaite suivre (et qui peut même déjà s'y trouver initialement) et c'est également dans ce même répertoire que les git checkout vont avoir lieu, c'est-à-dire que les fichiers suivis vont être remplacés par ceux de la version examinée.

    Si un dépôt distant sur trouve sur un serveur, toutefois, le working directory ne sert à rien puisqu'on ne travaille jamais directement sur ce serveur. Celui-ci ne sert qu'à héberger les projets et les mettre à disposition en ligne. Cela signifie qu'un hébergeur Git se retrouvait avec une multitude de répertoires « vides », un par dépôt, dans lesquels on ne ferait jamais le moindre git checkout et qui ne contiendraient en fait, en tout et pour tout, que le répertoire .git qui lui forme le vrai dépôt.

    Si c'est bien ce que l'on veut dire, il est alors possible de l'initialiser comme tel avec git init --bare. Dans ce cas, le sous-répertoire .git n'est pas créé et les fichiers qu'il contient en temps normal sous déposé directement à la racine du répertoire concerné. Ces fichiers sont globalement semblables à ceux créés en temps normal, à ceci près que le fichier « config » contient une entrée bare = true au lieu de false. Lorsqu'il le constate, Git sait qu'il s'agit d'un dépôt bare et qu'il n'y donc pas lieu d'y faire directement un git status ou un git checkout, mais le reste des fonctionnalités sera assuré.

    En outre, le fait qu'un dépôt soit bare n'a d'implication que sur la machine où il est hébergé. Vu de « l'extérieur », (avec push ou pull) rien ne distingue a priori un dépôt bare d'un dépôt non-bare.

    Normalement, dans tous les cas, c'est l'outil qui se charge de créer le dépôt qui configure tout cela mais effectivement, même si le fonctionnement est le même, Git peut refuser d'honorer un push vers un dépôt non-bare car il estime que quelque peut potentiellement être en train de travailler là-bas, et que l'on risque de modifier sa branche de travail sans qu'il en soit averti. D'où le flag que tu as été obligé de mettre en place.

  11. #11
    Membre émérite
    Profil pro
    Développeur Web
    Inscrit en
    Février 2008
    Messages
    3 398
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Février 2008
    Messages : 3 398
    Par défaut
    Du coup, tout s'éclaire.

    Merci.

    Peut-être un avis au sujet des adresses de dépôts distants ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    git remote get-url --all

  12. #12
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 609
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 609
    Par défaut
    Citation Envoyé par Gluups Voir le message
    Peut-être un avis au sujet des adresses de dépôts distants ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    git remote get-url --all
    Oui, on en a parlé dans le commentaire précédent.

    Dans cette situation en particulier, git remote get-url --all ne signifie pas « obtenir l'URL de tous les dépôts distants » mais « obtenir toutes les URL d'un dépôt distant donné » (car il peut y en avoir plusieurs). C'est pour cela que tu es toujours obligé de les spécifier explicitement et un par un.

  13. #13
    Membre émérite
    Profil pro
    Développeur Web
    Inscrit en
    Février 2008
    Messages
    3 398
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Février 2008
    Messages : 3 398
    Par défaut
    Citation Envoyé par Obsidian Voir le message
    Oui, on en a parlé dans le commentaire précédent.

    Dans cette situation en particulier, git remote get-url --all ne signifie pas « obtenir l'URL de tous les dépôts distants » mais « obtenir toutes les URL d'un dépôt distant donné » (car il peut y en avoir plusieurs). C'est pour cela que tu es toujours obligé de les spécifier explicitement et un par un.
    Ah, ça n'existe pas, alors ?
    Ou peut-être il faut se le mijoter sous PowerShell ?

  14. #14
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 609
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 609
    Par défaut
    Citation Envoyé par Gluups Voir le message
    Ah, ça n'existe pas, alors ?
    Ou peut-être il faut se le mijoter sous PowerShell ?
    Oui, ou sous n'importe quel shell sous Unix. C'est le pendant de set-url qui, lui, attend légitimement un dépôt distant cible.

    J'ai rapidement vérifié et je n'ai pas trouvé dans la man page quoi que ce soit qui indique qu'on puisse le faire et je viens d'examiner le code (car le code de Git est lui-même conservé dans un dépôt Git) et la fonction get_url() (dans builtin/remote.c) attend bel et bien un remote name en premier lieu.

    Cela dit, ça ne devrait pas être un problème en soi. 99 % du temps, on clone un dépôt depuis une source unique, donc il n'y a pas vraiment lieu d'itérer ici (contrairement aux branches qui, elles, peuvent être nombreuses). En plus, dans la quasi-totalité de ces cas, ce dépôt sera nommé « origin » et à moins de gérer une distribution massive à la main, il est assez peu probable que tu dépasse deux ou trois dépôts distants distincts par dépôt local (en excluant les submodules).

    Si tu es confronté à un cas de figure où cela serait vraiment utile pour toi, tu peux effectivement scripter cela très facilement et si tu estimes que ça pourrait être utile à tout le monde, alors on serait intéressé (sérieusement) par un exposé de ce cas de figure dans ce fil, dans un premier temps. Ensuite, il est possible de proposer un patch aux mainteneurs de Git qui l'intégreront si le use case est avéré.

  15. #15
    Membre émérite
    Profil pro
    Développeur Web
    Inscrit en
    Février 2008
    Messages
    3 398
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Février 2008
    Messages : 3 398
    Par défaut
    En fait, je pense que ce serait plutôt de l'ordre de deux, un dépôt distant dans un répertoire local comme j'ai là, plus un Github.

    Je suppose que si le premier s'appelle origin, il vaut mieux donner un autre nom au second pour éviter que quelqu'un se mélange les pinceaux, soit moi, soit le système.

    Si je ne laisse pas passer trop de temps sans m'en servir, effectivement je vais me rappeler le deuxième nom.
    Est-ce qu'en principe il laisse une trace quelque part sur le dépôt d'origine ?

  16. #16
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 609
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 609
    Par défaut
    Citation Envoyé par Gluups Voir le message
    Je suppose que si le premier s'appelle origin, il vaut mieux donner un autre nom au second pour éviter que quelqu'un se mélange les pinceaux, soit moi, soit le système.
    Tu ne peux pas déclarer plusieurs dépôts distants portant le même nom en local. Chacun doit avoir le sien. En revanche, il est tout-à-fait possible de renommer un dépôt distant.

    Si je ne laisse pas passer trop de temps sans m'en servir, effectivement je vais me rappeler le deuxième nom.
    Si tu l'oublies, il te suffit de re-saisir git remote seul, sans argument (ou git remote show) pour retrouver la liste de tous les dépôts distants déclarés.

    Est-ce qu'en principe il laisse une trace quelque part sur le dépôt d'origine ?
    Pas si tu ne lui demandes pas de le faire.

    origin est simplement le nom par défaut donné au dépôt distant lorsque tu effectues un git clone en local, à la fois parce que lorsque tu le fais, il déclare automatiquement la source comme dépôt distant en plus de rapatrier le code, mais également parce que ce dépôt distant en particulier est précisément l'endroit d'où provient initialement le contenu de ton dépôt (ce qui n'est pas forcément le cas quand tu en déclares d'autres). En ce sens, c'est assez cohérent.

    Mais une fois fait, origin est un dépôt distant ordinaire au même titre que tous les autres. Tu peux donc le renommer comme tu le souhaites.

  17. #17
    Membre émérite
    Profil pro
    Développeur Web
    Inscrit en
    Février 2008
    Messages
    3 398
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Février 2008
    Messages : 3 398
    Par défaut
    Citation Envoyé par Obsidian Voir le message
    Tu ne peux pas déclarer plusieurs dépôts distants portant le même nom en local. Chacun doit avoir le sien. En revanche, il est tout-à-fait possible de renommer un dépôt distant.



    Si tu l'oublies, il te suffit de re-saisir git remote seul, sans argument (ou git remote show) pour retrouver la liste de tous les dépôts distants déclarés.
    Ah, je me disais aussi.
    Merci.

    Pas si tu ne lui demandes pas de le faire.

    origin est simplement le nom par défaut donné au dépôt distant lorsque tu effectues un git clone en local, à la fois parce que lorsque tu le fais, il déclare automatiquement la source comme dépôt distant en plus de rapatrier le code, mais également parce que ce dépôt distant en particulier est précisément l'endroit d'où provient initialement le contenu de ton dépôt (ce qui n'est pas forcément le cas quand tu en déclares d'autres). En ce sens, c'est assez cohérent.
    Ah oui, si on clone un dépôt distant, bien entendu, c'est l'origine du code.

    Parfois il m'arrive de créer mes propres projets, et là origin est la cible, la sauvegarde.


    Mais une fois fait, origin est un dépôt distant ordinaire au même titre que tous les autres. Tu peux donc le renommer comme tu le souhaites.
    OK.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 0
    Dernier message: 28/10/2020, 08h03
  2. Réponses: 0
    Dernier message: 12/04/2017, 16h35
  3. [MySQL] divergeance entre easyphp et apache
    Par domi232 dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 14/01/2013, 17h54
  4. comportement de sed diverge entre ligne de commande et script
    Par yobbas dans le forum Shell et commandes GNU
    Réponses: 2
    Dernier message: 08/07/2010, 19h26
  5. Divergence entre hébergeur de test et hébergeur de prod
    Par soledad_001 dans le forum Autres hébergeurs
    Réponses: 0
    Dernier message: 01/02/2010, 13h24

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo