Capítulo 17 de 33 8 secciones 7 min

Publicar lo tuyo en GitHub

Del repositorio de tu máquina a una dirección que puedes compartir

<strong>Se crea el repositorio vacío en GitHub, se conecta con <code>git remote add origin</code> y se sube con <code>git push -u origin main</code>.</strong> Tres pasos y el último solo lleva <code>-u</code> la primera vez. Lo importante es lo que se decide antes: privado o público, porque esa pregunta aparece una sola vez y viene marcada en público. Si el push sale rechazado, casi siempre es porque en GitHub ya hay algo que tú no tienes.

Llevas once capítulos con un repositorio que solo existe en tu máquina. Hoy le damos dirección 🌎

Y empiezo por la decisión que la gente pasa de largo, porque la pantalla de GitHub la pone chiquita y ya viene marcada.

Privado o público, antes de nada

PrivadoPúblico
Quién lo veTú y quien invitesCualquiera, y Google
PrecioGratis, sin límite de repositoriosGratis
ParaTrabajo de clientes, datos, borradoresPortafolio, cosas que quieres compartir
Se puede cambiarSí, en SettingsSí, pero lo copiado no vuelve

Mi regla: privado siempre, y público cuando decides que sí. Pasar de privado a público es un clic; al revés no deshace nada.

Los tres pasos

En GitHub, New repository, le pones nombre y no marcas nada más:

  • Ni README
  • Ni licencia
  • Ni gitignore

Si marcas algo, GitHub crea un commit allá que tú no tienes aquí, y el primer push sale rechazado. Es el tropiezo más común del capítulo.

Después, en tu máquina, dos líneas. Para verlas ejecutadas usamos otra vez el servidor de práctica del capítulo 12:

mkdir ventas-miss-yera
cd ventas-miss-yera
git init -q
printf 'ciudad,monto\nLima,1200\nArequipa,890\n' > ventas.csv
printf '# Ventas Miss Yera\n' > README.md
git add .
git commit -q -m "Primeras ventas de Lima y Arequipa"
cd ..
git init -q --bare servidor.git
cd ventas-miss-yera
git remote add origin ../servidor.git
git push -u origin main
To ../servidor.git
 * [new branch]      main -> main
branch 'main' set up to track 'origin/main'.

Con GitHub de verdad la única diferencia es la dirección: git remote add origin git@github.com:tuusuario/ventas-miss-yera.git. El resto es idéntico ✅

Qué significa cada línea de la respuesta

Enumerating objects es Git contando qué tiene que mandar. Writing objects es la subida. [new branch] main -> main es "creé allá una rama main con lo de tu main". Y branch 'main' set up to track es lo que hizo el -u.

De ahora en adelante

printf 'Cusco,760\n' >> ventas.csv
git add ventas.csv
git commit -q -m "Entran las ventas de Cusco"
git push
To ../servidor.git
   5aa0e29..34101fe  main -> main

A secas. Esa es la rutina del resto de tu vida con ese proyecto: trabajas, haces commits, y cuando quieres dejarlo a salvo, git push 🔁

El rechazo que asusta

Un día vas a ver esto, y no es que se haya roto nada. Vamos a provocarlo: alguien (o tú desde otra máquina) subió algo que tú no tienes.

cd ..
git clone -q servidor.git otra-maquina
cd otra-maquina
printf 'canal,monto\nBodegas,4200\n' > canales.csv
git add canales.csv
git commit -q -m "Desde la otra maquina, entran los canales"
git push -q origin main
cd ../ventas-miss-yera
printf 'Piura,980\n' >> ventas.csv
git add ventas.csv
git commit -q -m "Entran las ventas de Piura"
git push
To ../servidor.git
 ! [rejected]        main -> main (fetch first)
error: failed to push some refs to '../servidor.git'
hint: Updates were rejected because the remote contains work that you do not
hint: have locally. This is usually caused by another repository pushing to
hint: the same ref. If you want to integrate the remote changes, use
hint: 'git pull' before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

Léelo entero, porque el propio Git te dice qué hacer: "Updates were rejected because the remote contains work that you do not have locally". Traducido: allá hay algo que aquí no está, y si subieras, lo borrarías.

La solución es traerlo primero:

git pull -q --no-rebase origin main
git log --oneline
cat ventas.csv
git push -q origin main
echo "ahora si"
e74a7f1 Merge branch 'main' of ../servidor
7ecfd6e Entran las ventas de Piura
6464ce0 Desde la otra maquina, entran los canales
34101fe Entran las ventas de Cusco
5aa0e29 Primeras ventas de Lima y Arequipa
ciudad,monto
Lima,1200
Arequipa,890
Cusco,760
Piura,980
ahora si

Los canales y Piura conviven. Bajar antes de subir es la costumbre que evita el 99% de los problemas de equipo 🤝

La trampa

Tu commit tenía un error de dedo en el mensaje, lo arreglas con --amend y al subir Git se queja. Le pones --force y listo.

$ git push --force origin main

+ 8a2b19c...3c1f80a main -> main (forced update)

# tres horas despues, en el chat del equipo:
# "oigan, se borraron mis dos commits de ayer"
Qué está mal

El --force no subió tu versión: reemplazó la de allá 💥

Ese + del principio y ese "forced update" son la señal: le dijiste a GitHub "lo que tengas ahí, bórralo, la verdad es la mía". Y lo que había eran los commits que subió tu compañera mientras tú arreglabas el mensaje.

Existe una versión con freno, --force-with-lease, que se niega si alguien subió algo desde la última vez que miraste. Hace lo mismo cuando es seguro y te salva cuando no.

Y en una rama donde trabaja más gente, la respuesta casi siempre es no forzar nada: se arregla hacia adelante, con un commit más.

Comprueba que se entendió

Comprueba que lo tienes

Tu git push sale rechazado con "remote contains work that you do not have locally". ¿Qué haces?

  • git push --force
  • git pull y después git push
  • Clonar de nuevo y copiar mis archivos encima
  • Esperar, seguro se arregla solo

Ejercicios

1. Prepara el proyecto de canales

Crea el repositorio con las ventas por canal y su primer commit.

cd ..
mkdir canales-venta
cd canales-venta
git init -q
printf 'canal,monto\nBodegas,4200\nHoreca,3100\n' > canales.csv
git add canales.csv
git commit -q -m "Ventas por canal de bodegas y horeca"
git log --oneline
0c460fb Ventas por canal de bodegas y horeca

Todavía no sabe que GitHub existe.

2. Conéctalo y súbelo

Crea el repositorio vacío del otro lado, conéctalo y haz el primer push.

cd ..
git init -q --bare canales-servidor.git
cd canales-venta
git remote add origin ../canales-servidor.git
git push -u origin main
To ../canales-servidor.git
 * [new branch]      main -> main
branch 'main' set up to track 'origin/main'.

El -u solo esta vez.

3. Sube un cambio sin escribir el destino

Agrega los mayoristas y súbelo con git push a secas.

printf 'Mayoristas,5600\n' >> canales.csv
git add canales.csv
git commit -q -m "Entra el canal mayorista"
git push
To ../canales-servidor.git
   0c460fb..e91e683  main -> main

Esa es la rutina: commit y push.

4. Comprueba qué hay del otro lado

Pregúntale al servidor qué ramas tiene y con qué hash.

git ls-remote origin
git log --oneline -1
e91e683ffa1ccaa8e49e108fd093ecb373068085	HEAD
e91e683ffa1ccaa8e49e108fd093ecb373068085	refs/heads/main
e91e683 Entra el canal mayorista

El mismo hash aquí y allá.

5. Provoca el rechazo

Sube algo desde otra copia y después intenta subir lo tuyo.

cd ..
git clone -q canales-servidor.git canales-otra
cd canales-otra
printf 'ciudad,monto\nLima,1200\n' > ciudades.csv
git add ciudades.csv
git commit -q -m "Desde la otra copia, entran las ciudades"
git push -q origin main
cd ../canales-venta
printf 'Farmacias,1800\n' >> canales.csv
git add canales.csv
git commit -q -m "Entra el canal farmacias"
git push
To ../canales-servidor.git
 ! [rejected]        main -> main (fetch first)
error: failed to push some refs to '../canales-servidor.git'
hint: Updates were rejected because the remote contains work that you do not
hint: have locally. This is usually caused by another repository pushing to
hint: the same ref. If you want to integrate the remote changes, use
hint: 'git pull' before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

El rechazo no es un castigo: es Git impidiendo que borres el trabajo de alguien 🛡️

6. Resuélvelo bajando primero

Trae lo de allá, comprueba que están los dos canales y sube.

git pull -q --no-rebase origin main
ls
git push -q origin main
git log --oneline
canales.csv
ciudades.csv
7a33a8b Merge branch 'main' of ../canales-servidor
8da6b0b Entra el canal farmacias
dbf5d37 Desde la otra copia, entran las ciudades
e91e683 Entra el canal mayorista
0c460fb Ventas por canal de bodegas y horeca

Las ciudades y las farmacias, las dos cosas. Nadie perdió nada.

7. Cambia la dirección del remoto

Si mueves el proyecto de sitio, no hay que clonar de nuevo.

cd ..
git init -q --bare canales-nuevo.git
cd canales-venta
git remote set-url origin ../canales-nuevo.git
git push -q -u origin main
git remote -v
origin	../canales-nuevo.git (fetch)
origin	../canales-nuevo.git (push)

set-url y listo. El repositorio ni se entera 🚚

Lo que te llevas

Crear vacío, conectar y subir. Y cuando el push sea rechazado, baja antes de subir en vez de forzar.

¿Tienes alguna duda o consulta?