Saltar a contenido

Práctica 1.4: GitHub Básico

P4 - Ramas, stash y GitHub

Partimos del repositorio local de P3. Una rama permite trabajar en una línea separada y stash guarda temporalmente cambios sin confirmar. GitHub será el remoto; la autenticación SSH se estudiará con detalle en P7.

1. Objetivos

  • Crear, consultar, cambiar y fusionar ramas.
  • Resolver un conflicto sencillo sin eliminar cambios a ciegas.
  • Guardar y recuperar cambios con stash.
  • Crear un remoto en GitHub y sincronizarlo con la rama main.

2. Relación con RA1 y criterios de evaluación

Esta práctica apoya el RA1, sobre todo CE b y CE c, porque organiza el proyecto creado con el IDE. Git/GitHub son herramientas instrumentales y no se equiparan a criterios normativos adicionales.

3. Pasos a seguir

3.1. Trabajar con ramas

Consulta previamente la explicación de ramas en el libro de Git y de los procedimientos para ramificar y fusionar.

Ramas de un proyecto Git

La imagen representa una línea principal y una línea de trabajo separada. En la práctica, la rama desarrollo-ejercicios cumplirá ese papel antes de integrarse en main.

  1. Comprueba que el árbol de trabajo está limpio:

    git status
    

    Crea una nueva rama y cambia directamente a ella:

    git switch -c desarrollo-ejercicios
    

    Puedes comprobar la rama en la que te encuentras con:

    git branch
    
  2. Crea ejercicios1/prueba2.py:

    numero1 = int(input("Dame un número: "))
    numero2 = int(input("Dame otro número: "))
    print(f"{numero1} + {numero2} = {numero1 + numero2}")
    
  3. Ejecuta el programa, añade el archivo y confirma los cambios:

    git add ejercicios1/prueba2.py
    git commit -m "Crea el programa prueba2"
    
  4. Vuelve a main:

    git switch main
    

    Comprueba que ejercicios1/prueba2.py, creado en la otra rama, no aparece.

    Regresa después a:

    git switch desarrollo-ejercicios
    

    Antes de cambiar de rama es recomendable comprobar siempre:

    git status
    

    Si tienes cambios sin confirmar, Git puede impedir el cambio de rama o llevar esos cambios contigo a la nueva rama. En el siguiente apartado aprenderás a utilizar stash para guardarlos temporalmente cuando todavía no quieras crear un commit.

  5. Para incorporar el trabajo realizado en la rama desarrollo-ejercicios a main, sitúate primero en main y realiza la fusión:

    git switch main
    git merge desarrollo-ejercicios
    

    Comprueba el resultado:

    git status
    git log --oneline --graph --all
    
  6. Si durante una fusión aparece un conflicto, Git marcará en el archivo las partes que no ha podido resolver automáticamente mediante marcas como:

    <<<<<<<
    =======
    >>>>>>>
    

    Abre el archivo, decide qué contenido debe permanecer y elimina esos marcadores.

    Después añade el archivo resuelto y crea el commit:

    git add archivo-resuelto.py
    git commit -m "Resuelve el conflicto de fusion"
    

    Si prefieres cancelar una fusión antes de resolverla:

    git merge --abort
    

    No borres la rama hasta comprobar que la fusión se ha realizado correctamente. Después puedes eliminarla:

    git branch -d desarrollo-ejercicios
    

3.2. Guardar temporalmente cambios con stash

Mientras trabajamos en un proyecto podemos tener modificaciones que todavía no están terminadas y no queremos incluir en un commit.

Git dispone de stash para apartar temporalmente esos cambios sin confirmarlos, dejando limpio el directorio de trabajo. Posteriormente podemos recuperarlos y continuar trabajando desde donde lo dejamos.

Por ejemplo, puede resultar útil cuando:

  • Tenemos cambios a medias que todavía no queremos incluir en un commit.
  • Necesitamos cambiar de rama pero tenemos trabajo sin terminar.
  • Queremos dejar temporalmente limpio el proyecto para realizar otra tarea y después continuar con nuestros cambios.

El funcionamiento básico será:

Tengo cambios sin confirmar
        ↓
git stash push
        ↓
Git los guarda temporalmente
        ↓
el directorio de trabajo queda limpio
        ↓
realizo otra tarea
        ↓
git stash apply
        ↓
recupero mis cambios

Vamos a probarlo simulando que hemos comenzado una modificación del programa anterior, pero todavía no queremos crear un commit.

  1. Modifica el archivo ejercicios1/prueba2.py y añade al final una nueva operación:

    print(f"{numero1} - {numero2} = {numero1 - numero2}")
    

    No realices todavía git add ni git commit, ya que vamos a considerar que este cambio todavía está en desarrollo.

    Comprueba el estado:

    git status
    

    Git mostrará que ejercicios1/prueba2.py contiene cambios sin confirmar.

  2. Imagina ahora que necesitas apartar temporalmente este trabajo para realizar otra tarea antes de terminarlo.

    Guarda los cambios mediante:

    git stash push -m "Añade resta a prueba2"
    

    Comprueba de nuevo:

    git status
    

    El directorio de trabajo debería volver a estar limpio.

    Si abres ejercicios1/prueba2.py, comprobarás además que la línea de la resta ha desaparecido del archivo.

    No se ha perdido ni se ha creado ningún commit: Git ha guardado temporalmente la modificación en el stash.

  3. Consulta los cambios guardados:

    git stash list
    

    Obtendrás algo parecido a:

    stash@{0}: On main: Añade resta a prueba2
    

    Cada stash guardado tiene un identificador. stash@{0} corresponde normalmente al más reciente.

  4. Recupera ahora el trabajo que habíamos apartado:

    git stash apply "stash@{0}"
    

    Comprueba nuevamente:

    git status
    

    Abre también ejercicios1/prueba2.py. La línea que añadía la resta habrá vuelto a aparecer y podremos continuar trabajando con ella.

  5. git stash apply recupera los cambios, pero mantiene el stash guardado.

    Compruébalo:

    git stash list
    

    Cuando hayas comprobado que los cambios se han recuperado correctamente, elimina esa copia:

    git stash drop "stash@{0}"
    

    Comprueba finalmente:

    git stash list
    

El proceso completo ha sido:

Añadimos la resta a prueba2.py
        ↓
todavía no queremos hacer commit
        ↓
git stash push
        ↓
la modificación desaparece temporalmente
        ↓
directorio de trabajo limpio
        ↓
git stash apply "stash@{0}"
        ↓
la modificación vuelve a prueba2.py
        ↓
git stash drop "stash@{0}"
        ↓
eliminamos la copia temporal

También existe:

git stash pop

que recupera el stash más reciente y lo elimina de la lista si puede aplicarlo correctamente.

En esta práctica utilizaremos apply y drop por separado para poder comprobar primero que los cambios se han recuperado correctamente antes de eliminar el stash.

Importante: stash está pensado para apartar cambios de forma temporal, normalmente mientras realizamos otra tarea y los recuperamos poco después.

Los cambios guardados mediante stash permanecen únicamente en nuestro repositorio local. No se envían a GitHub mediante git push. Por tanto, no debemos utilizar stash para guardar trabajo durante largos periodos ni como copia de seguridad. Si perdiéramos el repositorio local por una avería del equipo o del disco, también podríamos perder esos cambios.

Recuerda la diferencia:

commit → guarda cambios en el historial local del proyecto
         ↓
         podemos publicarlos en GitHub mediante push

stash  → aparta cambios temporalmente en el repositorio local
         ↓
         no se publican en GitHub mediante push

Cuando el trabajo tenga un estado que queramos conservar como parte del proyecto, lo normal será crear un commit y, cuando corresponda, publicarlo en el repositorio remoto.

stash no sustituye a los commit ni es una copia de seguridad.

3.3. Conectar un repositorio local con GitHub

Hasta ahora hemos trabajado con un repositorio Git almacenado en nuestro equipo. Podemos conectarlo con un repositorio remoto de GitHub para publicar y sincronizar nuestro trabajo.

Git puede comunicarse con GitHub utilizando principalmente dos métodos:

HTTPS
https://github.com/TU_USUARIO/TU_REPOSITORIO.git

SSH
git@github.com:TU_USUARIO/TU_REPOSITORIO.git

Ambos permiten realizar operaciones como clone, pull, fetch o push. La diferencia está principalmente en el mecanismo utilizado para establecer la conexión y autenticarnos.

HTTPS

Utiliza una dirección como:

https://github.com/TU_USUARIO/TU_REPOSITORIO.git

En Windows, Git puede utilizar un gestor de credenciales para conservar la autenticación y evitar que tengamos que identificarnos continuamente.

Esto resulta cómodo en un equipo personal, pero debemos tener especial cuidado en ordenadores públicos o compartidos, ya que no queremos dejar una autenticación disponible para otros usuarios.

SSH

Utiliza una dirección como:

git@github.com:TU_USUARIO/TU_REPOSITORIO.git

La autenticación se realiza mediante las claves SSH que hemos configurado anteriormente. La clave privada permanece en nuestro equipo y GitHub tiene registrada nuestra clave pública.

Si la clave privada está protegida mediante una frase de paso, podemos utilizar ssh-agent para mantenerla temporalmente disponible durante nuestra sesión de trabajo.

En esta práctica utilizaremos principalmente SSH, aunque es importante conocer ambos métodos porque encontrarás repositorios y ejemplos que utilizan cualquiera de ellos.

3.4. Crear el repositorio remoto y configurar origin

  1. Crea un repositorio vacío en GitHub. Utiliza un nombre neutro como:

    prog-u1-practica
    

    Al crearlo vacío evitamos añadir inicialmente archivos que nuestro repositorio local todavía no tiene.

  2. Git necesita conocer la dirección del repositorio remoto con el que queremos trabajar.

    Añade el repositorio de GitHub utilizando su dirección SSH:

    git remote add origin git@github.com:TU_USUARIO/TU_REPOSITORIO.git
    

    En este comando:

    git remote add origin URL
                   │      │
                   │      └── dirección del repositorio en GitHub
                   │
                   └── nombre que damos a ese remoto
    

    origin es simplemente el nombre local que utilizamos normalmente para referirnos al repositorio remoto principal.

  3. Comprueba la configuración:

    git remote -v
    

    Deberías obtener algo similar a:

    origin  git@github.com:TU_USUARIO/TU_REPOSITORIO.git (fetch)
    origin  git@github.com:TU_USUARIO/TU_REPOSITORIO.git (push)
    

    Esto significa que cuando utilicemos origin, Git sabrá con qué repositorio remoto debe comunicarse.

  4. Publica la rama main por primera vez:

    git push -u origin main
    

    Podemos interpretar el comando así:

    git push -u origin main
                 │      │
                 │      └── rama que queremos publicar
                 │
                 └── repositorio remoto
    

    La opción -u establece además la relación de seguimiento entre nuestra rama local main y la rama main del remoto.

    Después de hacerlo por primera vez, normalmente podremos utilizar simplemente:

    git push
    

3.5. Sincronizar los cambios

Una vez conectado el repositorio local con GitHub, trabajaremos habitualmente con dos operaciones:

git pull
git push

De forma simplificada:

GitHub
   │
   │ git pull
   ▼
Repositorio local
   │
   │ trabajamos y hacemos commits
   │
   │ git push
   ▼
GitHub

git pull incorpora a nuestro repositorio local los cambios publicados en el remoto:

git pull

git push envía al remoto nuestros commits locales:

git push

Antes y después de sincronizar es recomendable comprobar:

git status

Si quieres indicar explícitamente el remoto y la rama también puedes utilizar:

git pull origin main
git push origin main

En esta primera aproximación utilizaremos el funcionamiento normal de pull. Más adelante, cuando sea necesario, podremos estudiar otras formas de integrar los cambios remotos.

3.6. Clonar un repositorio existente

El procedimiento anterior se utiliza cuando el proyecto ya existe en nuestro equipo y queremos conectarlo con un nuevo repositorio de GitHub.

Si el repositorio ya existe en GitHub y queremos descargarlo en otro equipo, normalmente utilizaremos git clone.

Con SSH:

git clone git@github.com:TU_USUARIO/TU_REPOSITORIO.git

También podríamos clonarlo mediante HTTPS:

git clone https://github.com/TU_USUARIO/TU_REPOSITORIO.git

git clone realiza automáticamente varias tareas:

Repositorio de GitHub
        ↓
git clone
        ↓
crea la carpeta del proyecto
        ↓
descarga el repositorio y su historial
        ↓
crea el repositorio Git local
        ↓
configura automáticamente el remoto origin

Por eso, después de utilizar git clone no necesitamos ejecutar:

git init
git remote add origin ...

Podemos comprobarlo entrando en el repositorio:

cd TU_REPOSITORIO
git remote -v
git status

4. Comprobaciones de finalización

  • main contiene los cambios fusionados desde la rama de trabajo.
  • Has comprobado cómo crear, cambiar, fusionar y eliminar una rama.
  • Has guardado temporalmente unos cambios con stash y los has recuperado correctamente.
  • Comprendes la diferencia básica entre utilizar HTTPS y SSH para conectar con GitHub.
  • git remote -v muestra correctamente el repositorio remoto configurado como origin.
  • El remoto utiliza principalmente una dirección SSH.
  • git push -u origin main publica correctamente la rama main.
  • Comprendes la diferencia entre conectar un repositorio local existente mediante git remote add y descargar uno existente mediante git clone.

5. Ejercicios y entregables

  1. Crea una rama para mejorar uno de los ejercicios anteriores y fusiónala posteriormente en main.
  2. Realiza una modificación sin confirmar, guárdala temporalmente mediante stash y recupérala después.
  3. Conecta el repositorio local con un repositorio vacío de GitHub utilizando SSH.
  4. Comprueba el remoto mediante:

    git remote -v
    
  5. Publica la rama main en GitHub y comprueba que los commits aparecen correctamente en el repositorio remoto.

  6. Clona el repositorio en otra ubicación y comprueba que origin se ha configurado automáticamente.

Entregables

  • URL del repositorio de GitHub.
  • Captura o salida de git log --oneline --graph --all.
  • Captura o salida de git remote -v.
  • Comprobación del stash guardado y posteriormente recuperado.

Fuentes y referencias