Git
Chapters ▾ 2nd Edition

6.3 GitHub - Mantenimiento de un proyecto

Mantenimiento de un proyecto

Ahora que ya sabes cómo ayudar a un proyecto, veamos el otro lado: cómo puedes crear, administrar y mantener tu propio proyecto.

Creación de un repositorio

Vamos a crear un nuevo repositorio para compartir nuestro código en él. Comienza pulsando el botón “New repository” en el lado derecho de tu página principal, o bien desde el botón + en la barra de botones cercano a tu nombre de usuario, tal como se ve en Desplegable “New repository”..

La zona ``Your repositories''.
Figure 110. La zona “Your repositories”.
Desplegable ``New repository''.
Figure 111. Desplegable “New repository”.

Esto te llevará al formulario para crear un nuevo repositorio:

Formulario para crear repositorio.
Figure 112. Formulario para crear repositorio.

Todo lo que tienes que hacer aquí es darle un nombre al proyecto; el resto de campos es totalmente opcional. Por ahora, pulsa en el botón “Create Repository” y listo: se habrá creado el repositorio en GitHub, con el nombre <usuario>/<proyecto>

Dado que no tiene todavía contenido, GitHub te mostrará instrucciones para crear el repositorio Git, o para conectarlo a un proyecto Git existente. No entraremos aquí en esto; si necesitas refrescarlo, revisa el capítulo Fundamentos de Git.

Ahora que el proyecto está alojado en GitHub, puedes dar la URL a cualquiera con quien quieras compartirlo. Cada proyecto en GitHub es accesible mediante HTTP como https://github.com/<usuario>/<proyecto>, y también con SSH con la dirección git@github.com:<usuario>/<proyecto>. Git puede obtener y enviar cambios en ambas URL, ya que tienen control de acceso basado en las credenciales del usuario.

Note

Suele ser preferible compartir la URL de tipo HTTP de los proyectos públicos, puesto que así el usuario no necesitará una cuenta GitHub para clonar el proyecto. Si das la dirección SSH, los usuarios necesitarán una cuenta GitHub y subir una clave SSH para acceder. Además, la URL HTTP es exactamente la misma que usamos para ver la página web del proyecto.

Añadir colaboradores

Si estás trabajando con otras personas y quieres darle acceso de escritura, necesitarás añadirlas como “colaboradores”. Si Ben, Jeff y Louise se crean cuentas en GitHub, y quieres darles acceso de escritura a tu repositorio, los tienes que añadir al proyecto. Al hacerlo le darás permiso de “push”, que significa que tendrán tanto acceso de lectura como de escritura en el proyecto y en el repositorio Git.

Enlace a ajustes del repositorio.
Figure 113. Enlace a ajustes del repositorio.

Selecciona “Collaborators” del menú del lado izquierdo. Simplemente, teclea el usuario en la caja y pulsa en “Add collaborator.” Puedes repetir esto las veces que necesites para dar acceso a otras personas. Recuerda que si el proyecto está en un repositorio privado gratuito, solo podrás dar accesos a tres colaboradores. Si necesitas quitar un acceso, pulsa en la “X” del lado derecho del usuario.

Colaboradores del repositorio.
Figure 114. Colaboradores del repositorio.

Gestión de los Pull Requests

Ahora que tienes un proyecto con algo de código, y probablemente algunos colaboradores con acceso de escritura, veamos qué pasa cuando alguien te hace un Pull Request.

Los Pull Requests pueden venir de una rama en una bifurcación del repositorio, o pueden venir de una rama del mismo repositorio. La única diferencia es que, en el primer caso procede de gente que no tiene acceso de escritura a tu proyecto y quiere integrar en el tuyo cambios interesantes, mientras que en el segundo caso procede de gente con acceso de escritura al repositorio.

En los siguientes ejemplos, supondremos que eres “tonychacon” y has creado un nuevo proyecto para Arduino llamado “fade”.

Notificaciones por correo electrónico

Cuando alguien realiza un cambio en el código y te crea un Pull Request, debes recibir una notificación por correo electrónico avisándote, con un aspecto similar a Notificación por correo de nuevo Pull Request..

Notificación por correo de nuevo Pull Request
Figure 115. Notificación por correo de nuevo Pull Request.

Hay algunas cosas a destacar en este correo. En primer lugar, te dará un pequeño diffstat (es decir, una lista de archivos cambiados y en qué medida). Además, trae un enlace al Pull Request y algunas URL que puedes usar desde la línea de comandos.

Si observas la línea que dice git pull <url> patch-1, es una forma simple de fusionar una rama remota sin tener que añadirla localmente. Lo vimos esto rápidamente en Recuperando ramas remotas. Si lo deseas, puedes crear y cambiar a una rama y luego ejecutar el comando para fusionar los cambios del Pull Request.

Las otras URL interesantes son las de .diff y .patch, que como su nombre lo indica, proporcionan “diff unificados” y formatos de parche del Pull Request. Técnicamente, podrías fusionar con algo como:

$ curl http://github.com/tonychacon/fade/pull/1.patch | git am

Colaboración en el Pull Request

Como hemos visto en El Flujo de Trabajo en GitHub, puedes participar en una discusión con la persona que generó el Pull Request. Puedes comentar líneas concretas de código, comentar commits completos o comentar el Pull Request en sí mismo, utilizando donde quieras el formato Markdown.

Cada vez que alguien comenta, recibirás nuevas notificaciones por correo, lo que te permite vigilar todo lo que pasa. Cada correo tendrá un enlace a la actividad que ha tenido lugar y, además, puedes responder al comentario simplemente contestando al correo.

Respuesta a correo-e
Figure 116. Las respuestas a correos se incluyen en el hilo de discusión.

Una vez que el código está como quieres y deseas fusionarlo, puedes copiar el código y fusionarlo localmente, mediante la sintaxis ya conocida de git pull <url> <branch>, o bien añadiendo el fork como nuevo remoto, bajándotelo y luego fusionándolo.

Si la fusión es trivial, también puedes pulsar el botón “Merge” en GitHub. Esto realizará una fusión “sin avance rápido”, creando un commit de fusión incluso si era posible una fusión con avance rápido. Esto significa que cada vez que pulses el botón Merge, se creará un commit de fusión. Como verás en Botón Merge e instrucciones para fusionar manualmente un Pull Request., GitHub te da toda esta información si pulsas en el enlace de ayuda.

Botón Merge
Figure 117. Botón Merge e instrucciones para fusionar manualmente un Pull Request.

Si decides que no quieres fusionar, también puedes cerrar el Pull Request y la persona que lo creó será notificada.

Referencias de Pull Request

Si tienes muchos Pull Request y no quieres añadir un montón de remotos o hacer muchos cada vez, hay un pequeño truco que GitHub te permite. Es un poco avanzado y lo veremos en detalle después en Las especificaciones para hacer referencia a…​ (refspec), pero puede ser bastante útil.

En GitHub tenemos que las ramas de Pull Request son una especie de pseudo-ramas del servidor. De forma predeterminada no las obtendrás cuando hagas un clonado, pero hay una forma algo oscura de acceder a ellos.

Para demostrarlo, usaremos un comando de bajo nivel (conocido como de “fontanería”, sabremos más sobre esto en Fontanería y porcelana) llamado ls-remote. Este comando no se suele usar en el día a día de Git pero es útil para ver las referencias presentes en el servidor.

Si ejecutamos este comando sobre el repositorio “blink” que hemos estado usando antes, obtendremos una lista de ramas, etiquetas y otras referencias del repositorio.

$ git ls-remote https://github.com/schacon/blink
10d539600d86723087810ec636870a504f4fee4d	HEAD
10d539600d86723087810ec636870a504f4fee4d	refs/heads/master
6a83107c62950be9453aac297bb0193fd743cd6e	refs/pull/1/head
afe83c2d1a70674c9505cc1d8b7d380d5e076ed3	refs/pull/1/merge
3c8d735ee16296c242be7a9742ebfbc2665adec1	refs/pull/2/head
15c9f4f80973a2758462ab2066b6ad9fe8dcf03d	refs/pull/2/merge
a5a7751a33b7e86c5e9bb07b26001bb17d775d1a	refs/pull/4/head
31a45fc257e8433c8d8804e3e848cf61c9d3166c	refs/pull/4/merge

Por supuesto, si estás en tu repositorio y tecleas git ls-remote origin podrás ver algo similar pero para el remoto etiquetado como origin.

Si el repositorio está en GitHub y tienes Pull Requests abiertos, tendrás estas referencias con el prefijo refs/pull. Básicamente, son ramas, pero ya que no están bajo refs/heads/, no las obtendrás normalmente cuando clonas o te bajas el repositorio del servidor, ya que el proceso de obtención las ignora.

Hay dos referencias por cada Pull Request, la que termina en /head apunta exactamente al último commit de la rama del Pull Request. Así si alguien abre un Pull Request en el repositorio y su rama se llama bug-fix apuntando al commit a5a775, en nuestro repositorio no tendremos una rama bug-fix (puesto que está en el fork) pero tendremos el pull/<pr#>/head apuntando a a5a775. Esto significa que podemos obtener fácilmente cada Pull Request sin tener que añadir un montón de remotos.

Ahora puedes obtenerlo directamente.

$ git fetch origin refs/pull/958/head
From https://github.com/libgit2/libgit2
 * branch            refs/pull/958/head -> FETCH_HEAD

Esto dice a Git, “Conecta al remoto origin y descarga la referencia llamada refs/pull/958/head.” Git obedece y descarga todo lo necesario para construir esa referencia, y deja un puntero al commit que quieres bajo .git/FETCH_HEAD. Puedes realizar operaciones como git merge FETCH_HEAD aunque el mensaje del commit será un poco confuso. Además, si estás revisando un montón de Pull Requests, se convertirá en algo tedioso.

Hay también una forma de obtener todos los Pull Requests, y mantenerlos actualizados cada vez que conectas al remoto. Para ello abre el archivo .git/config y busca la línea origin. Será similar a esto:

[remote "origin"]
    url = https://github.com/libgit2/libgit2
    fetch = +refs/heads/*:refs/remotes/origin/*

La línea que comienza con fetch = es un “refspec.” Es una forma de mapear nombres del remoto con nombres de tu copia local. Este caso concreto dice a Git, que "las cosas en el remoto bajo refs/heads deben ir en mi repositorio bajo refs/remotes/origin." Puedes modificar esta sección añadiendo otra refspec:

[remote "origin"]
    url = https://github.com/libgit2/libgit2.git
    fetch = +refs/heads/*:refs/remotes/origin/*
    fetch = +refs/pull/*/head:refs/remotes/origin/pr/*

Con esta última línea decimos a Git, “Todas las referencias del tipo refs/pull/123/head deben guardarse localmente como refs/remotes/origin/pr/123.” Ahora, si guardas el archivo y ejecutas un git fetch tendremos:

$ git fetch
# …
 * [new ref]         refs/pull/1/head -> origin/pr/1
 * [new ref]         refs/pull/2/head -> origin/pr/2
 * [new ref]         refs/pull/4/head -> origin/pr/4
# …

Ya tienes todos los Pull Request en local de forma parecida a las ramas; son solo-lectura y se actualizan cada vez que haces un fetch. Pero hace muy fácil probar el código de un Pull Request en local:

$ git checkout pr/2
Checking out files: 100% (3769/3769), done.
Branch pr/2 set up to track remote branch pr/2 from origin.
Switched to a new branch 'pr/2'

La referencia refs/pull/#/merge de GitHub representa el “commit” que resultaría si pulsamos el botón “merge”. Esto te permite probar la fusión del Pull Request sin llegar a pulsar dicho botón.

Pull Requests sobre Pull Requests

No solamente se puede abrir Pull Requests en la rama master, también se pueden abrir sobre cualquier rama de la red. De hecho, puedes poner como objetivo otro Pull Request.

Si ves que un Pull Request va en la buena dirección y tienes una idea para hacer un cambio que depende de él, o bien no estás seguro de que sea una buena idea, o no tienes acceso de escritura en la rama objetivo, puedes abrir un Pull Request directamente.

Cuando vas a abrir el Pull Request, hay una caja en la parte superior de la página que especifica qué rama quieres usar y desde qué rama quieres hacer la petición. Si pulsas el botón “Edit” en el lado derecho de la caja, puedes cambiar no solo las ramas sino también la bifurcación.

objetivos de PR
Figure 118. Cambio manual de la rama o del fork en un pull request.

Aquí puedes fácilmente especificar la fusión de tu nueva rama en otro Pull Request o en otrá bifurcación del proyecto.

Menciones y notificaciones

GitHub tiene un sistema de notificaciones que resulta útil cuando necesitas pedir ayuda, o necesitas la opinión de otros usuarios o equipos concretos.

En cualquier comentario, si comienzas una palabra anteponiendo el carácter @, intentará auto-completar nombres de usuario de personas que sean colaboradores o responsables en el proyecto.

Menciones
Figure 119. Empieza tecleando @ para mencionar a alguien.

También puedes mencionar a un usuario que no esté en la lista desplegable, pero normalmente el autocompletado lo hará más rápido.

Una vez que envías un comentario con mención a un usuario, el usuario citado recibirá una notificación. Es decir, es una forma de implicar más gente en una conversación. Esto es muy común en los Pull Requests para invitar a terceros a que participen en la revisión de una incidencia o un Pull Request.

Si alguien es mencionado en un Pull Request o incidencia, quedará además “suscrito” y recibirá desde este momento las notificaciones que genere su actividad. Del mismo modo, el usuario que crea la incidencia o el Pull Request queda automáticamente “suscrito” para recibir las notificaciones, disponiendo todos de un botón “Unsubscribe” para dejar de recibirlas.

Quitar suscripción
Figure 120. Quitar suscripción de un pull request o incidencia.

Página de notificaciones

Cuando decimos “notificaciones”, nos referimos a una forma por la que GitHub intenta contactar contigo cuando tienen lugar eventos, y éstas pueden ser configuradas de diferentes formas. Si te vas al enlace “Notification center” de la página de ajustes, verás las diferentes opciones disponibles.

Notification center
Figure 121. Opciones de Notification center.

Para cada tipo, puedes elegir tener notificaciones de “Email” o de “Web”, y puedes elegir tener una de ellas, ambas o ninguna.

Notificaciones Web

Las notificaciones web se muestran en la página de Github. Si las tienes activas verás un pequeño punto azul sobre el icono de Notificaciones en la parte superior de la pantalla, en Centro de notificaciones..

Centro de notificaciones
Figure 122. Centro de notificaciones.

Si pulsas en él, verás una lista de todos los elementos sobre los que se te notifica, agrupados por proyecto. Puedes filtrar para un proyecto específico pulsando en su nombre en el lado izquierdo. También puedes reconocer (marcar como leída) una notificación pulsando en el icono de check en una notificación, o reconocerlas todas pulsando en el icono de check de todo el grupo. Hay también un botón “mute” para silenciarlas, que puedes pulsar para no recibir nuevas notificaciones de ese elemento en el futuro.

Todas estas características son útiles para manejar un gran número de notificaciones. Muchos usuarios avanzados de GitHub suelen desactivar las notificaciones por correo y manejarlas todas mediante esta pantalla.

Notificaciones por correo

Las notificaciones por correo electrónico son la otra manera de gestionar notificaciones con GitHub. Si las tienes activas, recibirás los correos de cada notificación. Vimos ya algún ejemplo en Comentarios enviados en notificaciones de correo y Notificación por correo de nuevo Pull Request.. Los correos también serán agrupados correctamente en conversaciones, con lo que estará bien que uses un cliente de correo que maneje las conversaciones.

En las cabeceras de estos correos se incluyen también algunos metadatos, que serán útiles para crear filtros y reglas adecuados.

Por ejemplo, si miramos las cabeceras de los correos enviados a Tony en el correo visto en Notificación por correo de nuevo Pull Request., veremos que se envió la siguiente información:

To: tonychacon/fade <fade@noreply.github.com>
Message-ID: <tonychacon/fade/pull/1@github.com>
Subject: [fade] Wait longer to see the dimming effect better (#1)
X-GitHub-Recipient: tonychacon
List-ID: tonychacon/fade <fade.tonychacon.github.com>
List-Archive: https://github.com/tonychacon/fade
List-Post: <mailto:reply+i-4XXX@reply.github.com>
List-Unsubscribe: <mailto:unsub+i-XXX@reply.github.com>,...
X-GitHub-Recipient-Address: tchacon@example.com

Vemos en primer lugar que la información de la cabecera Message-Id nos da los datos que necesitamos para identificar usuario, proyecto y demás en formato <usuario>/<proyecto>/<tipo>/<id>. Si se tratase de una incidencia, la palabra “pull” habría sido reemplazada por “issues”.

Las cabeceras List-Post y List-Unsubscribe permiten a clientes de correo capaces de interpretarlas, ayudarnos a solicitar dejar de recibir nuevas notificaciones de ese tema. Esto es similar a pulsar el botón “mute” que vimos en la versión web, o en “Unsubscribe” en la página de la incidencia o el Pull Request.

También merece la pena señalar que si tienes activadas las notificaciones tanto en la web como por correo, y marcas como leído el correo en la web también se marcará como leído, siempre que permitas las imágenes en el cliente de correo.

Archivos especiales

Hay dos archivos especiales que GitHub detecta y maneja si están presentes en el repositorio.

README

En primer lugar tenemos el archivo README, que puede estar en varios formatos. Puede estar con el nombre README, README.md, README.asciidoc y alguno más. Cuando GitHub detecta su presencia en el proyecto, lo muestra en la página principal, con el renderizado que corresponda a su formato.

En muchos casos este archivo se usa para mostrar información relevante a cualquiera que sea nuevo en el proyecto o repositorio. Esto incluye normalmente cosas como:

  • Para qué es el proyecto

  • Cómo se configura y se instala

  • Ejemplo de uso

  • Licencia del código del proyecto

  • Cómo participar en su desarrollo

Puesto que GitHub hace un renderizado del archivo, puedes incluir imágenes o enlaces en él para facilitar su comprensión.

CONTRIBUTING

El otro archivo que GitHub reconoce es CONTRIBUTING. Si tienes un archivo con ese nombre y cualquier extensión, GitHub mostrará algo como Apertura de un Pull Request cuando existe el archivo CONTRIBUTING. cuando se intente abrir un Pull Request.

Nota sobre cómo participar
Figure 123. Apertura de un Pull Request cuando existe el archivo CONTRIBUTING.

La idea es que indiques cosas a considerar a la hora de recibir un Pull Request. La gente lo debe leer a modo de guía sobre cómo abrir la petición.

Administración del proyecto

Por lo general, no hay muchas cosas que administrar en un proyecto concreto, pero sí un par de cosas que pueden ser interesantes.

Cambiar la rama predeterminada

Si usas como rama predeterminada una que no sea “master”, por ejemplo para que sea objetivo de los Pull Requests, puedes cambiarla en las opciones de configuración del repositorio, en donde pone “Options”.

Rama predeterminada
Figure 124. Cambio de la rama predeterminada del proyecto.

Simplemente cambia la rama predeterminada en la lista desplegable, y ésta será la elegida para la mayoría de las operaciones, así mismo será la que sea visible al principio (“checked-out”) cuando alguien clona el repositorio.

Transferencia de un proyecto

Si quieres transferir la propiedad de un proyecto a otro usuario u organización en GitHub, hay una opción para ello al final de “Options” llamada “Transfer ownership”.

Transferir
Figure 125. Transferir propiedad de un proyecto.

Esto es útil si vas a abandonar el proyecto y quieres que alguien continúe, o bien se ha vuelto muy grande y prefieres que se gestione desde una organización.

Esta transferencia, supone un cambio de URL. Para evitar que nadie se pierda, genera una redirección web en la URL antigua. Esta redirección funciona también con las operaciones de clonado o de copia desde Git.