Branche Git: maître vs origine / maître vs télécommandes / origine / maître

201

Je pense que je suis sur la bonne voie pour comprendre les concepts de base de git.

J'ai déjà configuré et cloné un référentiel distant. J'ai également créé un référentiel vide côté serveur et y ai lié mon référentiel local.

Mon problème est que je ne comprends pas la différence entre:

  • origine / maître vs télécommandes / origine / maître

Pour autant que je sache, master est une branche locale, et remotes / origin / master est distante.

Mais qu'est-ce que l' origine / le maître exactement ?

John Rumpel
la source
1
@ChristopherWallace: Vous avez provoqué deux questions sur la méta avec votre montage: " Avons-nous vraiment besoin d'une balise [origin]? " Et " Quel est le vrai [Maître]? ".
Deduplicator
@Deduplicator Est-ce un problème?
nbro
@ChristopherWallace: Eh bien, beaucoup semblent penser que les deux balises (celle que vous avez créée et celle que vous venez d'ajouter) sont mauvaises. Il se trouve que je suis d'accord, mais vous avez peut-être quelque chose à ajouter à la discussion liée qui n'a pas été examinée. Sinon, semble-t-il.
Deduplicator
Question de suivi: pourquoi .git/refs/origin/masterdériverait-il jamais .git/refs/remotes/origin/master? Cela m'arrive maintenant et je suis expulsé.
Paul

Réponses:

219

Prenez un clone d'un référentiel distant et exécutez git branch -a(pour afficher toutes les branches que git connaît). Cela ressemblera probablement à ceci:

* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master

Voici masterune branche du référentiel local. remotes/origin/masterest une branche nommée mastersur la télécommande nommée origin. Vous pouvez vous y référer soit origin/mastercomme dans:

git diff origin/master..master

Vous pouvez également vous y référer comme remotes/origin/master:

git diff remotes/origin/master..master

Ce ne sont que deux façons différentes de se référer à la même chose (d'ailleurs, ces deux commandes signifient «montrez-moi les changements entre la masterbranche distante et ma masterbranche).

remotes/origin/HEADest le nom default branchde la télécommande origin. Cela vous permet simplement de dire originau lieu de origin/master.

larsks
la source
5
Bonne réponse. Je pense que git branch -amontrer la branche distante remotes/origin/masterest en partie parce que la référence sous-jacente est stockée .git/refs/remotes/origin(si elle n'a pas été emballée). À mon avis, la sortie de git branch -apourrait être beaucoup plus claire, peut-être en séparant le nom de la télécommande du nom de la branche par autre chose qu'une barre oblique.
Matt Hurne
14
Notez également que git branch -r, qui consiste à afficher uniquement les branches distantes, affichera la branche simplement origin/masterparce que le remotes/préfixe n'est pas nécessaire.
Matt Hurne
3
@misterbiscuit: c'est vrai. Le résultat est plus déroutant que clarifiant. Merci beaucoup, une excellente réponse à ma question qui m'a donné les bons indices
John Rumpel
Si je regarde, git logje vois commit fa9sd8jasdf98 (HEAD -> master), qu'est-ce que cela signifie? Qu'est-ce que HEAD dans ce cas? Je pensais que j'étais actuellement "maître" et je m'engageais origin/master. Je pense que j'ai mélangé quelque chose, quelqu'un pourrait-il aider à se calmer? MODIFIER LA MISE À JOUR: Je pense que je l'ai, est-il correct de supposer que HEAD pointe actuellement vers la branche master, ce qui signifie que je suis actuellement en train de m'engager sur master?
Sebastian Nielsen
@SebastianNielsen oui vous avez raison, la partie HEAD -> master signifie que vous êtes actuellement sur la branche master.
iRestMyCaseYourHonor
108

Réponse courte pour les nuls comme moi (volés à Torek):

  • origine / maître est "où le maître était là-bas la dernière fois que j'ai vérifié"
  • le maître est "où le maître est ici en fonction de ce que je fais"
ErichBSchulz
la source
9
origin / master = sauvegarde de la machine distante, mise à jour la dernière fois que vous avez vérifié master = votre copie d'origine / master
sakurashinken
40

Techniquement il n'y a pas réellement de choses « à distance » du tout 1 dans votre repo Git, il y a juste des noms locaux qui doivent correspondre aux noms sur un autre, différent repo. Ceux nommés origin/whatevercorrespondront initialement à ceux du dépôt que vous avez cloné:

git clone ssh://some.where.out.there/some/path/to/repo # or git://some.where...

fait une copie locale de l'autre dépôt. En cours de route, il note toutes les succursales qui se trouvaient là-bas, et les valide, et les colle dans votre référentiel local sous les noms refs/remotes/origin/.

Selon le temps que vous passez avant vous git fetchou l'équivalent pour mettre à jour "ma copie de ce qui est some.where.out.there", ils peuvent changer leurs branches, en créer de nouvelles et en supprimer. Lorsque vous effectuez votre git fetch(ou git pullqui est vraiment chercher et fusionner), votre référentiel fera des copies de leur nouveau travail et modifiera toutes les refs/remotes/origin/<name>entrées selon les besoins. C'est ce moment d' fetching qui fait que tout concorde (enfin, ça, et le clone initial, et certains cas d' pushing aussi - essentiellement chaque fois que Git a la chance de vérifier - mais voir la mise en garde ci-dessous).

Git vous fait normalement référence à la vôtre refs/heads/<name>comme juste <name>, et aux télécommandes comme origin/<name>, et tout fonctionne simplement parce qu'il est évident lequel est lequel. Il est parfois possible de créer vos propres noms de branche qui ne le rendent pas évident, mais ne vous inquiétez pas jusqu'à ce que cela se produise. :-) Donnez simplement à Git le nom le plus court qui le rende évident, et il ira de là: origin/masterc'est "où le maître était là-bas la dernière fois que j'ai vérifié", et masterc'est "où le maître est ici basé sur ce que j'ai fait" . Exécutez git fetchpour mettre à jour Git sur "là où le maître est là-bas" selon les besoins.


Mise en garde: dans les versions de Git antérieures à 1.8.4, git fetchcertains modes ne mettent pas à jour "là où le maître est là-bas" (plus précisément, les modes qui ne mettent à jour aucune branche de suivi à distance). Courir git fetch origin, ou git fetch --all, ou même juste git fetch, ne mise à jour. La course git fetch origin master ne fonctionne pas . Malheureusement, ce mode "ne se met pas à jour" est déclenché par l'ordinaire git pull. (Il s'agit principalement d'une gêne mineure et est corrigé dans Git 1.8.4 et versions ultérieures.)


1 Eh bien, il y a une chose que l'on appelle une «télécommande». Mais c'est aussi local! Le nom originest ce que Git appelle "une télécommande". Il s'agit essentiellement d'un nom court pour l'URL que vous avez utilisée lors du clonage. Il est également où originen origin/mastervient. Le nom origin/masterest appelé une branche de suivi à distance , qui est parfois raccourci en "branche distante", en particulier dans la documentation plus ancienne ou plus informelle.

torek
la source
2
Excellente description pour un débutant comme moi, merci! Clarifié pourquoi elle a mis l' origin/masterautocollant sur le localgraphique du dépôt, et non sur remotecelui (je recommande sans réserve la présentation de "Git Happens" de Jessica Kerr pour les nouveaux venus sur git: vimeo.com/46010208 . Je me grattais la tête entre 30h00 et 30h30 : 19.)
aîné aîné
11

J'essaierais de rendre la réponse de @ ErichBSchulz plus simple pour les débutants:

  • origin / master est l'état de la branche master sur le référentiel distant
  • master est l'état de la branche master sur le référentiel local
MKJ
la source
1
bon essai mais à mon humble avis, last time I've checkedil perd un point important
Alexei Martianov
6
  1. origin - Il s'agit d'un nom personnalisé et le plus courant pour pointer vers distant.

$ git remote add origin https://github.com/git/git.git--- Vous exécuterez cette commande pour lier votre projet github à l'origine. Ici, l'origine est définie par l'utilisateur. Vous pouvez le renommer en$ git remote rename old-name new-name


  1. master - Le nom de branche par défaut dans Git est master. Pour ordinateur distant et local.

  1. origin / master - Ceci est juste un pointeur pour référencer la branche master dans le repo distant. Rappelez-vous que je dis que l'origine pointe vers la télécommande.

$ git fetch origin- Télécharge les objets et les références du référentiel distant sur votre ordinateur local [origine / maître]. Cela signifie que cela n'affectera pas votre branche principale locale, sauf si vous les fusionnez à l'aide $ git merge origin/master. N'oubliez pas de vérifier la bonne branche où vous devez fusionner avant d'exécuter cette commande

Remarque: Le contenu récupéré est représenté comme une branche distante. La récupération vous donne la possibilité d'examiner les modifications avant de les intégrer à votre copie du projet. Pour afficher les changements entre le vôtre et la télécommande$git diff master..origin/master

Gnanasekar S
la source
5

Une précision (et un point qui m'a dérouté):

"télécommandes / origine / HEAD est la branche par défaut" n'est pas vraiment correct.

remotes / origin / master était la branche par défaut dans le référentiel distant (la dernière fois que vous avez vérifié). HEAD n'est pas une branche, il pointe simplement vers une branche.

Considérez HEAD comme votre espace de travail. Lorsque vous y pensez de cette façon, «git checkout branchname» est logique en ce qui concerne la modification de vos fichiers de zone de travail pour qu'ils soient ceux d'une branche particulière. Vous "retirez" les fichiers de branche dans votre zone de travail. TÊTE à toutes fins pratiques est ce que vous voyez dans votre zone de travail.

meule
la source
Plus précisément, HEADest un "pointeur vers une branche" (le fichier réel dans votre référentiel local contient souvent la chaîne ref: refs/heads/master, par exemple ... à moins qu'il ne soit "détaché", ce qui est une tout autre chose). Cependant, il y a une sorte de bogue dans la façon d' cloneinterpréter la " tête distante": les protocoles de transfert ne peuvent pas envoyer du tout une branche indirecte, juste un SHA-1 brut, donc git a un truc qui fait que cela "fonctionne principalement". De temps en temps, quelqu'un tombe sur un cas étrange. Je souhaite en quelque sorte que Git n'ait pas créé remotes/origin/HEADdu tout, surtout quand il se trompe ...
Torek
2

Je pense que cette notation git slash est probablement mieux comprise en regardant à l'intérieur de votre .gitdossier.


Par exemple, voici un arbre quelque peu abrégé de mon .git pour la base source de LibreOffice.

Sous Linux, il sudo apt-get install tree est utile de voir cela.
Sous Windows, je pense que la treecommande pourrait encore fonctionner.

Faites défiler vers le bas et jetez un œil aux références (alias «références») près du bas:

$ tree  
.  
├── branches  
├── config  
├── description  
├── FETCH_HEAD  
├── gitk.cache  
├── HEAD  
├── hooks  
│   ├── applypatch-msg.sample  
    ...
├── index  
├── info  
│   └── exclude  
├── logs  
│   ├── HEAD  
│   └── refs  
│       ├── heads  
│       │   ├── master  
│       │   └── remotes  
│       │       └── origin  
│       └── remotes  
│           └── origin  
│               ├── distro  
│               │   ├── cib  
│               │   │   └── libreoffice-6-0  
│               │   ├── collabora  
│               │   │   └── cp-6.0  
│               │   └── lhm  
│               │       └── libreoffice-5-2+backports  
│               ├── HEAD  
│               ├── libreoffice-6-2  
│               ├── master  
│               └── private  
│                   └── mst  
│                       └── sw_redlinehide_4a  
├── objects  
│   ├── info  
│   └── pack  
│       ├── pack-b80087dc57e2b3315f449ca0f1aaa91987bf0c5e.idx  
│       ├── pack-b80087dc57e2b3315f449ca0f1aaa91987bf0c5e.pack  
│       ├── pack-eb4e6808029e712d8d9c2671accbbd98aaeb9a04.idx  
│       └── pack-eb4e6808029e712d8d9c2671accbbd98aaeb9a04.pack  
├── ORIG_HEAD  
├── packed-refs  
└── refs  
    ├── heads  
    │   ├── master  
    │   └── remotes  
    │       └── origin  
    ├── remotes  
    │   └── origin  
    │       ├── distro  
    │       │   ├── cib  
    │       │   │   └── libreoffice-6-0  
    │       │   ├── collabora  
    │       │   │   └── cp-6.0  
    │       │   └── lhm  
    │       │       └── libreoffice-5-2+backports  
    │       ├── HEAD  
    │       ├── libreoffice-6-2  
    │       ├── master  
    │       └── private  
    │           └── mst  
    │               └── sw_redlinehide_4a  
    └── tags  
        └── libreoffice-6-2-branch-point  

32 directories, 45 files

Cela aurait pu être moins déroutant si cela avait été présenté comme ça, mais ce n'était pas le cas:

repositories (i.e. independent trees)
├──local
│  └──master
│
└──origin1
│  └──master
└──origin2
   └──master

Nous avons trois types de références de base: têtes , télécommandes et balises .

  • .git / refs / heads détient notre maître local .

  • .git / refs / télécommandes peuvent contenir un certain nombre de télécommandes, bien que pour le moment nous avons seulement l' origine en elle.

  • .git / refs / tags (est discuté ailleurs).

origine ainsi, est notre seule et unique télécommande. Il contient origine / master .


Nous constatons que nous avons 2 HEADS (pointeurs vers les branches actuelles), un local et un distant:

$ cat .git/HEAD                        #         local:  HEAD -> master
ref: refs/heads/master

$ cat .git/refs/remotes/origin/HEAD    # remote origin:  HEAD -> master
ref: refs/remotes/origin/master

Si vous listez vos succursales :

$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/aoo/aw080
  remotes/origin/aoo/trunk
  remotes/origin/distro/capgemini/cg-4.1
  remotes/origin/distro/cib/libreoffice-5-0
  remotes/origin/distro/cib/libreoffice-5-1
  remotes/origin/distro/cib/libreoffice-5-2
  ...
  • La première branche répertoriée ( maître ) est la seule qui n'est pas une télécommande. Donc, dans ce cas, nous avons une succursale locale. C'est à partir de là que nous commencerons notre propre travail, pour nos propres nouvelles succursales et commits ultérieurs.

Ensuite, vous pouvez avoir de nombreuses succursales de suivi à distance, et nous en avons ici. Vous savez que ce sont des branches de suivi à distance car elles sont préfixées par ' télécommandes / '. Ceux indiqués ici sont pour l'origine nommée à distance.

  • Ainsi, la deuxième ligne est le pointeur de branche actuel de l'origine . Télécommandes / origine: HEAD - pointe vers -> master. Cela montre que dans le référentiel distant, la branche actuelle est leur branche nommée master (à ne pas confondre avec notre branche locale nommée master ).

  • Les branches restantes ne se trouvent pas dans votre .git / refs / arborescence, mais vous les trouverez plutôt dans .git/packed-refs.

Lorsque nous git fetch nous téléchargeons les modifications du référentiel distant, dans notre référentiel de suivi à distance.

Lorsque nous fusionnons git, nous fusionnons les modifications de ce référentiel de suivi à distance local dans notre ou nos branches locales de travail, dans ce cas dans notre branche principale.

(Lorsque nous git pull, nous faisons ces deux étapes en une seule opération.)


Il est également intéressant de noter que ces UUID locaux et distants pour le maître pointent actuellement vers le même nœud (alias «commit»):

$ cat refs/heads/master                   # local         master
1ca409292272632f443733450313de5a82c54a9c

$ cat refs/remotes/origin/master          # remote origin master
1ca409292272632f443733450313de5a82c54a9c

Notre maître local pointe donc au même endroit que le maître d'origine de la télécommande:

[local] master = [remote] origin master

Enfin, je pense qu'il est également utile de jeter un œil à .git/packed-refs

$ cat packed-refs 
# pack-refs with: peeled fully-peeled 
3c1d4742e649fe9c8aed8c2817fe3e1f3364f298 refs/remotes/origin/aoo/aw080
e87c8b7922e9a73e0abb7f9a7a47c9ac3374a826 refs/remotes/origin/aoo/trunk
b70fdffb041c12f124dcc0822b61bf3450e53137 refs/remotes/origin/distro/capgemini/cg-4.1
5dbc3f1754809b9489faaf380b1a4bdbcfbb6205 refs/remotes/origin/distro/cib/libreoffice-5-0
cfdbc96ca47d68d6785fd21829a8d61f49d6e591 refs/remotes/origin/distro/cib/libreoffice-5-1
5189c8c47461ef09739086e55512fc6a10245273 refs/remotes/origin/distro/cib/libreoffice-5-2
3bee5917569ca8e6ee3b086458f5b1a917b88ca1 refs/remotes/origin/distro/cib/libreoffice-5-3
92fbe703f9ca480d3a2b8610d87e991c729edf77 refs/remotes/origin/distro/cib/libreoffice-5-4
05c0a5df66cc69d75280f05b804cf82f3387d42b refs/remotes/origin/distro/cib/libreoffice-6-0
7fe193e759b24b90852e6e327115b77114d7b119 refs/remotes/origin/distro/cib/libreoffice-6-1
8187f7aa413e7ef7b377eea2b057d336bf256867 refs/remotes/origin/distro/collabora/cd-5.3
7a6b608591e21ef61dc05cff9fc58da531035755 refs/remotes/origin/distro/collabora/cd-5.3-3.1
....

Cela laisse sans doute plus de questions que de réponses, mais je pense que cela peut commencer à vous aider à répondre à vos propres questions sur ce qui est quoi.

Vue elliptique
la source