Menú de navegaciónMenú
Categorías

La mejor forma de Aprender Programación online y en español www.campusmvp.es

?id=15b5dcbe-1a86-4fad-9eaa-7ccb4ca54c83

Git: los conceptos de "main", "origin" y "HEAD"

A lo largo de los años he observado que muchos programadores, sobre todo cuando están empezando con el control de código fuente, tienden a confundir ciertos conceptos sencillos de esta herramienta.

Dentro de ésta existen 3 conceptos que son clave, muy sencillos y no podemos confundir, así que vamos a darles un repaso rápido.

main

Como sabes, los sistemas de control de código fuente como Git trabajan con el concepto de ramas (o branches en inglés). Dicho de manera rápida y básica, una rama no es más que un nombre que se da a un commit, a partir del cual se empieza a trabajar de manera independiente y con el que se van a enlazar nuevos commits de esa misma rama. Las ramas pueden mezclarse de modo que todo el trabajo hecho en una de ellas pase a formar parte de otra.

Por si no lo tienes claro, un commit es un conjunto de cambios en los archivos que hemos dado por buenos y que queremos almacenar como una instantánea de cara al futuro. Los commits se relacionan unos con otros en una o varias secuencias para poder ir viendo la historia de un determinado archivo a lo largo del tiempo. Es el concepto central de todo sistema de control de código.

Existe una rama predeterminada que se crea automáticamente cuando se crea un repositorio que se llama rama main.

Actualización posterior: en realidad, hasta mediados del año 2020 esta rama se llamaba "master" y no "main". Pero por aquel entonces, aunque existen diversas teorías sobre el origen de ese nombre, se decidió que era una referencia al esclavismo ("master" de "amo", frente a "slave" de "esclavo. Otras teorías hablan, con más lógica IMHO, de que viene de "master copy" o copia maestra o principal) y que había que renombrarla. Así que ahora es "main" y no "master".

Por regla general a main se la considera la rama principal y la raíz de la mayoría de las demás ramas. Lo más habitual es que en main se encuentre el "código definitivo", que luego va a producción, y es la rama en la que se mezclan todas las demás tarde o temprano para dar por finalizada una tarea e incorporarla al producto final:

Figura que ilustra la rama máster y algunas otras como develop o ramas para el desarrollo de características concretas, y como luego se mezclan entre sí

Esta manera de trabajar con ramas nos permite llevar en paralelo varios desarrollos relacionados sin importar que cada uno de ellos termine en momentos muy diferentes, ya que no interfieren, pudiendo mezclarlos todos al final.

Lo más habitual es que para poder mezclar otra rama cualquiera con main haya que pedir permiso y que alguien lo revise todo antes de permitirlo. Es lo que se denomina un "pull request". O simplemente que la rama main se encuentre protegida de modo que solo si se pasan todos los test y aseguramos que el producto funciona, sea posible mezclarse con ella. De este modo impedimos que cualquiera pueda llevar al producto final código que no cumple unos mínimos de calidad.

origin

Como seguramente sabrás Git es un sistema de control de código distribuido. Esto quiere decir que, aunque todos los desarrolladores tienen una copia exacta del mismo repositorio en su disco duro, existen uno o más repositorios remotos contra los que trabajamos, y que son los que almacenan el estado final del producto. Estos repositorios remotos se suelen llamar simplemente "remotos", y no todo el mundo tiene permiso para enviar commits hacia ellos (lo que se llama hacer un push).

Bien, pues origin es simplemente el nombre predeterminado que recibe el repositorio remoto principal contra el que trabajamos. Cuando clonamos un repositorio por primera vez desde GitHub o cualquier otro sistema remoto, el nombre que se le da a ese repositorio "maestro" es precisamente origin.

De todos modos ese nombre se puede cambiar, y se pueden crear más remotos contra los que hacer push. Pero en un porcentaje muy alto de los casos, como ese nombre por omisión no se cambia, puedes asumir que vas a enviar la información a origin.

HEAD

El concepto de HEAD es muy simple: se refiere al commit en el que está tu repositorio posicionado en cada momento. Por regla general HEAD suele coincidir con el último commit de la rama en la que estés, ya que habitualmente estás trabajando en lo último. Pero si te mueves hacia cualquier otro commit anterior entonces el HEAD estará más atrás.

De hecho, si tienes el repositorio actualizado (te has traído los últimos cambios de origin) y estás trabajando en la rama main lo más habitual es que coincidan las tres cosas.

Por ejemplo, este es el log, mostrando las ramas, del repositorio de un proyecto Open Source en el que participo. El HEAD local se muestra como un punto con borde azul. Como se puede observar, en el momento en el que saqué la captura tenía en local la rama master (hoy en día sería main) y estaba ubicado en el último commit (cuyo hash identificador comienza por bdf09f20) y coincide con el último commit en el origen:

Imagen que muestra en un mismo commit (el último) el HEAD local, el del origen y la rama master en ambos

Si por el contrario me muevo a otra rama o a un commit anterior, o si el repositorio de origen en la misma rama va por delante de lo que yo tengo en local, ninguno de los tres tiene por qué coincidir. Por ejemplo, me he movido a un commit anterior (el 6068a1c8): y ahora mismo mi HEAD local está 5 commits por detrás (es la que está en negrita con un punto de borde azul), mientras que la rama máster (que replica a la misma en el origen) está 5 commits por delante. El HEAD del repositorio remoto (origen) está en el último commit:

La imagen muestra como mi HEAD local está varios commits por detrás del HEAD remoto, dentro de la rama máster

En resumen

Aunque se trata de conceptos sencillos no siempre están claros para todo el mundo. De hecho, tanto main como origin son nombres sobre los que existe una convención en cuanto a su uso, pero no tienen por qué existir ya que la rama principal puede llamarse de otra manera cualquiera, y el origen principal también puede tener otro nombre (aunque estos dos sean los más habituales).

Sin embargo, HEAD es un nombre constante y un concepto que no tiene discusión, refiriéndose siempre al commit en el que tenemos posicionado el repositorio en el momento actual. Independientemente de la rama en la que estemos, de cómo se llame la rama principal o el repositorio principal remoto.

Espero que te haya servido para aclarar estos 3 conceptos si no los tenías controlados del todo 😊

Fecha de publicación:
José Manuel Alarcón Fundador de campusMVP, es ingeniero industrial y especialista en consultoría de empresa. Ha escrito diversos libros, habiendo publicado hasta la fecha cientos de artículos sobre informática e ingeniería en publicaciones especializadas. Microsoft lo ha reconocido como MVP (Most Valuable Professional) en desarrollo web desde el año 2004 hasta la actualidad. Puedes seguirlo en Twitter en @jm_alarcon o leer sus blog técnico o personal. Ver todos los posts de José Manuel Alarcón
Archivado en: Herramientas

Boletín campusMVP.es

Solo cosas útiles. Una vez al mes.

🚀 Únete a miles de desarrolladores

DATE DE ALTA

x No me interesa | x Ya soy suscriptor

La mejor formación online para desarrolladores como tú

Comentarios (7) -

Muy clara la explicación, una pregunta que programa Git GUI utilizaste para los ejemplos, estan muy buenos los graficos de las ramas.

Responder

José Manuel Alarcón
José Manuel Alarcón

Hola Juan:

Pues concretamente las gráficas de ramas son de la extensión Git Graph de Visual Studio Code: marketplace.visualstudio.com/items

Muy útil para verlas visualmente y también gestionarlas.

Saludos.

Responder

Me ha gustado mucho la explicación. Faltaría actualizar un concepto. Ya no existe la rama "master", ahora se llama "main". GitHub cambió el nombre de "master" por "main" por el tema de la esclavitud.

Aquí está la info:
https://github.com/github/renaming

Un saludo.

Responder

José Manuel Alarcón
José Manuel Alarcón

Hola Nacho:

Sí, es cierto que lo renombraron. Si te fijas, este artículo lo escribí antes de ese cambio que se realizó en aras de la corrección política.

Lo actualizaré, ya que estamos...

Saludos!

Responder

Luis Hernandez
Luis Hernandez

Tenía dudas con estos términos, pero gracias a su explicación me quedaron ampliamente aclaradas.

Responder

Muy clara la explicación, me sirvió ya que si tenia dudas sobre esos conceptos, solo no me queda claro aún ¿cómo es que se cambia uno de commit (HEAD)?

Gracias

Responder

José Manuel Alarcón
José Manuel Alarcón

Hola:

Si te refieres a cómo puedes posicionarte en un commit concreto que te interese (lo que se llama en estado detached head)) simplemente con un:

git checkout abcde

siendo "abcde" los primeros caracteres del commit que te interese.

También puedes moverte hacia atrás un número determinado de commits desde HEAD usando:

git checkout HEAD~3

que te movería 3 commits hacia atrás.

Atrévete a aprender bien Git con nuestra formación específica: www.campusmvp.es/.../...ara-programadores_245.aspx

Saludos!

Responder

Agregar comentario

Los datos anteriores se utilizarán exclusivamente para permitirte hacer el comentario y, si lo seleccionas, notificarte de nuevos comentarios en este artículo, pero no se procesarán ni se utilizarán para ningún otro propósito. Lee nuestra política de privacidad.