Ramificación de Git: maestro vs. origen / maestro vs. controles remotos / origen / maestro

201

Creo que estoy en el camino correcto para entender los conceptos básicos de git.

Ya he configurado y clonado un repositorio remoto. También creé un repositorio vacío del lado del servidor, y vinculé mi repositorio local.

Mi problema es que no entiendo la diferencia entre:

  • origen / maestro vs control remoto / origen / maestro

Por lo que he entendido, master es una rama local, y remotes / origin / master es remota.

Pero, ¿qué es exactamente origen / maestro ?

John Rumpel
fuente
1
@ChristopherWallace: provocó dos preguntas sobre meta con su edición: " ¿Realmente necesitamos una etiqueta [origen]? " Y " ¿Cuál es el verdadero [Maestro]? ".
Deduplicador
@Deduplicator ¿Eso es un problema?
nbro
@ChristopherWallace: Bueno, muchos parecen pensar que ambas etiquetas (la que usted creó y la que acaba de agregar) son malas. Estoy de acuerdo, pero quizás tenga algo que agregar a la discusión vinculada que no se consideró. Si no, parece que sí.
Deduplicador el
Pregunta de seguimiento: ¿Por qué .git/refs/origin/masteralguna vez derivaría .git/refs/remotes/origin/master? Esto me está sucediendo a mí ahora y me estoy desanimando.
Paul

Respuestas:

219

Tome un clon de un repositorio remoto y ejecútelo git branch -a(para mostrar todas las ramas que Git conoce). Probablemente se verá más o menos así:

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

Aquí, masterhay una rama en el repositorio local. remotes/origin/masteres una rama nombrada masteren el remoto llamado origin. Puede referirse a esto como cualquiera origin/master, como en:

git diff origin/master..master

También puede referirse a él como remotes/origin/master:

git diff remotes/origin/master..master

Estas son solo dos formas diferentes de referirse a la misma cosa (por cierto, ambos comandos significan "muéstreme los cambios entre la masterrama remota y mi masterrama").

remotes/origin/HEADes default branchpara el remoto llamado origin. Esto te permite simplemente decir en originlugar de origin/master.

larsks
fuente
55
Buena respuesta. Creo que git branch -amostrar la rama remota como remotes/origin/masteres en parte porque la referencia subyacente está almacenada .git/refs/remotes/origin(si no se ha empaquetado). En mi opinión, la salida de git branch -apodría ser mucho más clara, quizás separando el nombre del control remoto del nombre de la rama con algo más que una barra oblicua.
Matt Hurne
14
También tenga en cuenta que git branch -r, que es solo para mostrar ramas remotas, mostrará la rama solo origin/masterporque el remotes/prefijo no es necesario.
Matt Hurne
3
@misterbiscuit: eso es cierto. El resultado es más confuso que clarificador. Muchas gracias, una gran respuesta a mi pregunta que me dio las pistas correctas
John Rumpel
Si miro git logveo commit fa9sd8jasdf98 (HEAD -> master), ¿qué significa esto? ¿Qué es HEAD en este caso? Pensé que actualmente era "maestro" y me estaba comprometiendo origin/master. Creo que tengo algo mezclado, ¿alguien podría ayudar a calmar? EDITAR ACTUALIZACIÓN: Creo que lo entendí, ¿es correcto suponer que HEAD actualmente está apuntando a la rama maestra, lo que significa que actualmente estoy en el proceso de comprometerme a dominar?
Sebastian Nielsen
@SebastianNielsen sí, tienes razón, la parte HEAD -> master significa que estás actualmente en la rama master.
iRestMyCaseYourHonor
108

Respuesta corta para tontos como yo (robado de Torek):

  • origin / master es "donde master estuvo allí la última vez que revisé"
  • master es "donde está master aquí por lo que he estado haciendo"
ErichBSchulz
fuente
9
origin / master = copia de seguridad de la máquina remota, actualizada la última vez que revisó master = su copia de origin / master
sakurashinken
40

Técnicamente, en realidad no hay ninguna cosa "remota" en absoluto 1 en su repositorio de Git, solo hay nombres locales que deberían corresponder a los nombres de otro repositorio diferente. Los nombrados origin/whateverinicialmente coincidirán con los del repositorio desde el que clonó:

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

hace una copia local del otro repositorio. En el camino, anota todas las ramas que estaban allí, y los commits a los que se refieren, y los pega en su repositorio local bajo los nombres refs/remotes/origin/.

Dependiendo de cuánto tiempo git fetchpases antes de ti o de un equivalente para actualizar "mi copia de lo que está en algún lugar, donde esté", pueden cambiar sus ramas, crear otras nuevas y eliminar algunas. Cuando realice su git fetch(o git pullque realmente es buscar más combinar), su repositorio hará copias de su nuevo trabajo y cambiará todas las refs/remotes/origin/<name>entradas según sea necesario. Es ese momento de fetching que hace que todo coincida (bueno, eso y el clon inicial, y algunos casos de pushing también, básicamente cada vez que Git tiene la oportunidad de verificar, pero vea la advertencia a continuación).

Git normalmente te hace referirte a los tuyos refs/heads/<name>como justos <name>, y a los remotos como origin/<name>, y todo funciona porque es obvio cuál es cuál. A veces es posible crear sus propios nombres de sucursal que no lo hacen obvio, pero no se preocupe por eso hasta que suceda. :-) Solo dale a Git el nombre más corto que lo haga obvio, e irá desde allí: origin/masteres "donde el maestro estuvo allí la última vez que lo verifiqué", y masteres "dónde está el maestro aquí según lo que he estado haciendo" . Ejecute git fetchpara actualizar Git en "donde está el maestro allí", según sea necesario.


Advertencia: en versiones de Git anteriores a 1.8.4, git fetchtiene algunos modos que no se actualizan "donde está el maestro allí" (más precisamente, modos que no actualizan ninguna rama de seguimiento remoto). Ejecutando git fetch origin, o git fetch --all, o simplemente git fetch, se actualiza. Correr git fetch origin master no lo hace . Desafortunadamente, este modo "no se actualiza" es activado por ordinario git pull. (Esto es principalmente una molestia menor y se soluciona en Git 1.8.4 y versiones posteriores).


1 Bueno, hay una cosa que se llama "remoto". ¡Pero eso también es local! El nombre origines lo que Git llama "un control remoto". Básicamente es solo un nombre corto para la URL que usaste cuando hiciste el clon. Es también donde el originen origin/masterviene. El nombre origin/masterse denomina rama de seguimiento remoto , que a veces se acorta a "rama remota", especialmente en documentación anterior o más informal.

torek
fuente
2
Excelente descripción para un novato como yo, ¡gracias! Aclaró por qué puso la origin/masterpegatina en el localgráfico del repositorio, y no en la etiqueta remote(recomiendo de todo corazón la presentación "Git Happens" de Jessica Kerr para personas nuevas en git: vimeo.com/46010208 . Me rascaba la cabeza entre las 30:00 y las 30: 19.)
élder elder
11

Intentaría simplificar la respuesta de @ ErichBSchulz para principiantes:

  • origen / maestro es el estado de la rama maestra en el repositorio remoto
  • maestro es el estado de la rama maestra en el repositorio local
MKJ
fuente
1
buen intento pero en mi humilde opinión last time I've checked, pierde un punto importante
Alexei Martianov
6
  1. origen : este es un nombre personalizado y más común para señalar a remoto.

$ git remote add origin https://github.com/git/git.git--- Ejecutará este comando para vincular su proyecto github al origen. Aquí el origen está definido por el usuario. Puedes cambiarle el nombre por$ git remote rename old-name new-name


  1. master : el nombre de rama predeterminado en Git es master. Para computadora remota y local.

  1. origen / maestro : este es solo un puntero para referir la rama maestra en el repositorio remoto. Recuerda que dije que el origen apunta al control remoto.

$ git fetch origin- Descarga objetos y referencias del repositorio remoto a su computadora local [origen / maestro]. Eso significa que no afectará a su rama maestra local a menos que las combine usando$ git merge origin/master . Recuerde verificar la rama correcta donde necesita fusionarse antes de ejecutar este comando

Nota: El contenido recuperado se representa como una rama remota. Fetch le brinda la oportunidad de revisar los cambios antes de integrarlos en su copia del proyecto. Para mostrar los cambios entre los suyos y los remotos$git diff master..origin/master

Gnanasekar S
fuente
5

Una aclaración (y un punto que me confundió):

"remotes / origin / HEAD es la rama predeterminada" no es realmente correcto.

remotes / origin / master era la rama predeterminada en el repositorio remoto (la última vez que verificó). HEAD no es una rama, solo apunta a una rama.

Piense en HEAD como su área de trabajo. Cuando lo piensa de esta manera, 'git checkout branchname' tiene sentido con respecto a cambiar los archivos de su área de trabajo para que sean los de una rama en particular. Usted "paga" los archivos de ramificación en su área de trabajo. HEAD a todos los efectos prácticos es lo que usted puede ver en su área de trabajo.

almiar
fuente
Más precisamente, HEADes un "puntero a una rama" (el archivo real en su repositorio local a menudo contiene la cadena ref: refs/heads/master, por ejemplo ... a menos que esté "separado", que es otra cosa completamente diferente). Sin embargo, hay una especie de error en la forma en que cloneinterpreta la "CABEZA remota": los protocolos de transferencia no pueden enviar una rama indirecta en absoluto, solo un SHA-1 sin procesar, por lo que git tiene un error que hace que esto "funcione principalmente". Sin embargo, de vez en cuando alguien tropieza con un caso extraño. Desearía que git no creara remotes/origin/HEADnada, especialmente cuando sale mal ...
torek
2

Creo que esta notación de git slash probablemente se entienda mejor mirando dentro de su .gitcarpeta.


Por ejemplo, aquí hay un árbol abreviado de mi .git para la base de origen de LibreOffice.

En Linux sudo apt-get install tree es útil para ver esto.
En Windows , creo que el treecomando aún podría funcionar.

Desplácese hacia abajo y eche un vistazo a las referencias (también conocidas como 'referencias') en la parte inferior:

$ 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

Podría haber sido menos confuso si se presentara así, pero no fue así:

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

Tenemos tres tipos básicos de referencias: cabezas , controles remotos y etiquetas .

  • .git / refs / heads tiene nuestro maestro local .

  • .git / refs / remotes puede contener varios controles remotos, aunque por el momento solo tenemos origen en él.

  • .git / refs / tags (se discute en otra parte).

origen , por lo tanto, es nuestro único y remoto. Tiene origen / maestro .


Encontramos que tenemos 2 HEADS (punteros a las sucursales actuales), uno local y otro remoto:

$ 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 enumeras tus sucursales :

$ 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 primera rama listada ( maestra ) es la única que no es remota. Entonces, en este caso tenemos una sucursal local. Aquí es donde comenzaremos nuestro propio trabajo, para nuestras propias nuevas sucursales y compromisos posteriores.

A continuación, puede tener muchas sucursales de seguimiento remoto, y nosotros las tenemos aquí. Usted sabe que estas son ramas de seguimiento remoto porque tienen el prefijo ' remotes / '. Los que se muestran aquí son para el origen con nombre remoto.

  • Entonces, la segunda línea es el puntero de rama actual del origen . Mandos a distancia / origen: CABEZA - señala a -> maestro. Esto muestra que en el repositorio remoto, la rama actual es su rama llamada master , (no debe confundirse con nuestra rama local llamada master ).

  • Las ramas restantes no se encuentran en su .git / refs / tree, sino que las encontrará en .git/packed-refs.

Cuando vamos a buscar , descargamos los cambios desde el repositorio remoto a nuestro repositorio de seguimiento remoto.

Cuando nos fusionamos , fusionamos los cambios en este repositorio de seguimiento local y remoto en nuestra sucursal o sucursales locales de trabajo, en este caso en nuestra sucursal maestra.

(Cuando hacemos git pull hacemos los dos pasos en una sola operación).


También es interesante observar que estos UUID remotos y locales para el maestro actualmente apuntan al mismo nodo (también conocido como 'commit'):

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

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

Entonces, nuestro maestro local apunta al mismo lugar que el maestro de origen del control remoto:

[local] master = [remote] origin master

Finalmente, creo que también es útil echar un vistazo a .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
....

Sin duda, esto deja más preguntas que respuestas, pero creo que puede comenzar a ayudarlo a responder sus propias preguntas sobre qué es qué.

Vista elíptica
fuente