El comando git push se usa para cargar contenido del repositorio local a un repositorio remoto. El envío es la forma de transferir commits desde tu repositorio local a un repositorio remoto. Es el equivalente de git fetch, pero en lugar de descargar importaciones de commits en ramas locales, envía exportaciones de commits a ramas remotas. Las ramas remotas se configuran mediante el comando git remote. Los envíos tienen la capacidad de sobrescribir cambios, por lo que se debe tener cuidado a la hora de realizarlos. Estos problemas se describen a continuación.

Uso de git push

git push <remote> <branch>

Envía la rama especificada a una , junto con todos los commits y objetos internos necesarios. De este modo se crea una rama local en el repositorio de destino. Para evitar que se sobrescriban los commits, Git no te permitirá enviarlos cuando el resultado en el repositorio de destino sea una fusión sin avance rápido.

git push <remote> --force

Es igual que el comando anterior, pero fuerza el envío incluso si el resultado es una fusión sin avance rápido. No uses la marca --force a menos de que tengas absoluta certeza de lo que estás haciendo.

git push <remote> --all

Envía todas tus ramas locales a una rama remota especificada.

git push <remote> --tags

Las etiquetas no se envían automáticamente cuando envías una rama o usas la opción --all. La marca --tags envía todas las etiquetas locales a un repositorio remoto.

Análisis de git push

git push se suele usar para publicar y cargar cambios locales a un repositorio central. Después de modificar el repositorio local, se ejecuta un comando push para compartir las modificaciones con miembros remotos del equipo.

Uso de git push para publicar cambios

El diagrama anterior muestra lo que pasa cuando el progreso de tu rama master local ha sobrepasado a la rama master del repositorio central y publicas los cambios mediante la ejecución de un comando git push origin master. Fíjate en que ejecutar git push es similar en su esencia a ejecutar git merge master desde el repositorio remoto.

Git push y la sincronización

git push es uno de los muchos componentes que se usan en el proceso general de sincronización de Git. Los comandos de sincronización funcionan en ramas remotas que se configuran mediante el comando git remote. git push se puede considerar un comando de carga, mientras que git fetch y git pull se conciben como comandos de descarga. Una vez que los conjuntos de cambios se han trasladado mediante una descarga o una carga, se puede ejecutar un comando git merge en el destino para integrar dichos cambios.

Envíos a repositorios bare

Una práctica de Git moderna y que se usa muy a menudo consiste en contar con un repositorio --bare alojado de forma remota que actúa como un repositorio de origen central. Este repositorio de origen se suele alojar fuera de las instalaciones en un tercero fiable, por ejemplo, Bitbucket. Como los envíos interfieren en la estructura de la rama remota, lo más seguro y común es enviar repositorios que se han creado con la marca --bare. Los repositorios bare no tienen un directorio en funcionamiento, por lo que un envío no alterará el trabajo en curso sobre el contenido de un directorio en funcionamiento. Para obtener más información sobre la creación de repositorios bare, consulta la sección sobre git init.

Envío forzado

Git evita que sobrescribas el historial del repositorio central al negarse a enviar solicitudes cuando el resultado es una fusión sin avance rápido. De este modo, si el historial remoto difiere de tu historial, tendrás que incorporar una rama remota y fusionarla con la local para después intentar enviarla de nuevo. Este proceso es similar a la forma en la que SVN realiza la sincronización con el repositorio central mediante el comando svn update antes de confirmar un conjunto de cambios.

La marca --force sobrescribe este comportamiento y hace que la rama del repositorio remoto coincida con la local, además de que elimina todos los cambios de nivel superior que se hayan producido desde que realizaste la última incorporación. La única situación en la que deberías requerir un envío forzado es cuando te das cuenta de que los commits que acabas de compartir no están del todo bien y los corriges con un comando git commit --amend o con una reorganización interactiva. No obstante, debes estar absolutamente seguro de que ninguno de tus compañeros de equipo ha incorporado esos commits antes de usar la opción --force.

Ejemplos

Comando git push predeterminado

El siguiente ejemplo describe uno de los métodos estándar para publicar contribuciones locales al repositorio central. En primer lugar, se asegura de que tu rama maestra local está actualizada al recuperar la copia del repositorio central y reorganizar tus cambios sobre esa base. La reorganización interactiva también constituye una buena oportunidad para limpiar tus commits antes de compartirlos. A continuación, el comando git push envía todos los commits de tu rama maestra local al repositorio central.

git checkout master
git fetch origin master
git rebase -i origin/master
# Squash commits, fix up commit messages etc.
git push origin master

Como ya nos hemos asegurado de que la rama maestra local está actualizada, esta acción debería generar una fusión con avance rápido, y el comando git push no debería realizar ningún bloqueo debido a los problemas de la falta de avance rápido analizados anteriormente.

Envío forzado corregido

El comando git commit admite una opción --amend que actualizará el commit anterior. Un commit se suele corregir para actualizar el mensaje que contiene o añadir cambios nuevos. Una vez que un commit se corrige, git push da un fallo porque Git ve el commit corregido y el remoto como contenido divergente. Debe usarse la opción --force para enviar un commit corregido.

# make changes to a repo and git add
git commit --amend
# update the existing commit message
git push --force origin master

El ejemplo anterior asume que se está ejecutando en un repositorio existente con un historial de commits. git commit --amend se usa para actualizar el commit anterior. A continuación, el commit corregido se envía de forma forzada mediante la opción --force.

Eliminación de una rama o etiqueta remotas

En ocasiones, se deben limpiar las ramas por motivos de organización y mantenimiento de registros. Para eliminar una rama por completo, se debe eliminar tanto de forma local como de forma remota.

git branch -D branch_name
git push origin :branch_name

La opción anterior eliminará la rama remota denominada branch_name al pasar un nombre de rama con dos puntos como prefijo por el comando git push.