POST

Chuleta de git

 

Sobre git y tipos de repositorios

Git es un software de control de versiones que permite llevar un seguimiento y registro de las diferentes modificaciones y ampliaciones realizados en un programa informático a lo largo de su proceso de creación por los diferentes desarrolladores. Permite que estos trabajen a la vez sobre un software de una manera sincronizada sin pisarse el trabajo.

Distinguimos entre 2 tipos de repositorios o almacenes de código:

  • Repositorio remoto. Es el repositorio central donde todos los desarrolladores subirán las modificaciones y ampliaciones desarrolladas. En él se guarda la copia válida y última, con todas las modificaciones realizadas hasta la fecha por cada miembro del equipo de desarrollo.
  • Repositorios local. Cada desarrollador tendrá una copia local actualizada del repositorio remoto en su ordenador de trabajo. Sobre esta copia local será sobre la que se trabaje. Cada vez que realice modificaciones válidas, deberá subir los cambios al repositorio remoto y así compartir su trabajo con el resto del equipo. Cada desarrollador deberá actualizar su repositorio local periódicamente para tener lo más actualizada posible su copia local, ya que el resto de sus compañeros habrán subido nuevas modificaciones al repositorio remoto.

Preparando el repositorio remoto

Un repositorio remoto es una carpeta cuyo nombre suele terminar en .git. En esta carpeta se guardarán todos los archivos junto con todas las versiones que se han ido creado de los mismos a lo largo del tiempo.

El repositorio remoto, a diferencia de los repositorios locales de trabajo, debe ser inicializado de una manera especial para que no se puedan realizar modificaciones del código desde él. Es decir, se crea un repositorio GIT sin directorio de trabajo, ya que no vamos a trabajar directamente sobre él. Recordemos que trabajaremos sobre los repositorios locales y, desde estos, subiremos los cambios al repositorio remoto; pero no trabajamos directamente en el repositorio remoto.

Inicializamos un respositorio git vacío en el servidor
1
2
cd /path_to_my_repos/myNewProject.git
git init --bare

Trabajando en nuestro ordenador

¿Copio repositorio remoto o creo un repositorio nuevo?

Si el proyecto ya está iniciado, es decir, existe código en el repositorio remoto y tenemos acceso ssh con usuario git a la máquina 202.122.234.090 y puerto 27 podemos …

Crear una copia del repositorio remoto en nuestro ordenador.
1
git clone ssh://git@202.122.234.090:27/~/repositorios/myNewProject.git

Si empezamos un proyecto nuevo, no será necesario crear una copia del repositorio remoto porque no tendrá nada. Eso sí, deberemos poner el código que estemos desarrollando en local bajo control de versiones. Desde el directorio de trabajo local:

Creamos un repositorio local nuevo en un directorio de nuestro ordenador de trabajo
1
git init

Estructura del repositorio local

Estructura repositorio git

El repositorio local esta formado por la siguiente elementos:

  • Directorio de trabajo: contiene los archivos sobre los que se trabaja. Podemos añadir nuevos archivos, eliminar o modificar los existentes.
  • INDEX: contiene una lista con los archivos vigilados del directorio de trabajo cuyas modificaciones serán empaquetadas en el siguiente “commit”. Contiene el conjunto de cambios relevantes para el siguiente “commit”. Es una manera de llevar a los archivos a estadio intermedio de “preparación” antes del “commit”.
  • HEAD: es un enlace simbólico al último “commit” realizado. Contiene por tanto la información de cómo estaba el directorio de trabajo en su punto de partida tras el último “commit” y antes de realizar ninguna modificación.
  • Commit: se puede entender como un “paquete” de cambios realizados en los archivos del directorio de trabajo que estaban bajo vigilancia. Cada “commit” tiene una numeración única en Git y marcan los estados de desarrollo del software.

Flujo de trabajo en local: add y commit.

Consulta del historial de commits
1
git log
Añado al INDEX (stage area) todos los archivos modificados como candidatos para el próximo commit
1
git add -A
Creo un nuevo commit con todos los cambios de los archivos registrados en INDEX. HEAD apuntará a este nuevo commit.
1
git commit -m "Descripción del commit"

Consulta de cambios realizados y vueltas atrás

Estado del directorio de trabajo desde el último commit (HEAD)
1
git status
Cambios del directorio de trabajo (que todavía no se les ha hecho add) con respecto al último commit.
1
git diff
Lo mismo pero resumido
1
git diff –stat
Muestra los cambios entre el directorio de trabajo y el último commit, ignorando el staging area.
1
git diff HEAD
Sacar cambios que se agregaron al staging area (se les hizo un add). Es un unstage.
1
git reset HEAD -- nombre_del_archivo
Deshace el último commit y vuelve los archivos al staging area. Permite hacer mas cambios y meterlos el mismo “commit”.
1
git reset --soft HEAD~
¡CUIDADO!: Vacía el staging area y deshace todos los cambios que se hayan hecho en el directorio de trabaja dejando todos los archivos como estaban tras el último commit.
1
git reset --hard HEAD
¡CUIDADO!: Reemplaza los cambios en tu directorio de trabajo con el último contenido de HEAD. Los cambios que ya han sido agregados al index, así como también los nuevos archivos, se mantendrán sin cambio.
1
git checkout -- nombre_archivo

Ramas

Las ramas son caminos alternativos de desarrollo. Se crean para desarrollar nuevas funcionalidades y se fusionan con la rama principal (rama máster por defecto) cuando se ha concluido el desarrollo.

Lista de ramas existentes.
1
git branch
Creo una rama nueva para una nueva funcionalidad y cambio a esa rama
1
git checkout -b funcionalidad_x
Vuelvo a la rama principal
1
git checkout master
Borro una rama
1
git branch -d funcionalidad_x
Consulta de los últimos commit en cada rama
1
git branch -v
Subo la nueva rama al repositorio remoto haciéndola disponible para todos
1
git push nombre_repo funcionalidad_x

Fusiones entre ramas

Estoy en la rama master y fusiono los cambios de otra rama.
1
git merge rama_que_se_quiere_fusionar

No siempre será posible realizar esta operación y se pueden producir conflictos. Es necesario resolverlos manualmente editando los archivos y después marcarlos como fusionados con:

1
git add nombre_archivo_con_conflictos
Diferencia de cambios entre ramas
1
git diff rama_fuente rama_objetivo

Stash, dejando los cambios en pausa.

Si has realizado modificaciones en el directorio de trabajo y/o en el index, no has realizado todavía un commit para guardar ese estado, y cambias de rama, todos lo cambios se perderán. Para evitar esto haremos uso de “stash”.

Stash permite almacenar todos los cambios realizados, tanto del directorio de trabajo como del index, en una lista y devuelve al directorio de trabajo al estado en el que estaba tras el último commit. Ahora ya se puede cambiar a otra rama. Cuando se vuelva a la rama actual nos bastará con aplicar los cambios guardados en la lista.

Guarda las modificaciones del directorio de trabajo y del index en una lista.
1
git stash

Nota: El último ítem agregado en el stash será referenciado por stash@{0} e incrementará a los que estén en una unidad. El último stash realizado siempre tendrá el número 0. Es una pila FIFO.

Lista de cambios guardaos temporalmente por stash.
1
git stash list
Aplica un paquete de cambios stash@{0}
1
git stash apply stash@{0}
Borro de la lista el paquete de cambios stash@{1}
1
git stash drop stash@{1}
Borro la lista completa
1
git stash clear

Conectando con el repositorio remoto

Hasta ahora hemos realizado una serie de cambios en nuestro código guardándolos en forma de commits en nuestro repositorio local. Para subir esos cambios al repositorio remoto es necesario conectar nuestro repositorio local con le repositorio remoto.

Ver todas las conexiones con repositorios remotos.
1
git remote -v
Añadir conexión “nombre_repo” a un repositorio remoto.
1
git remote add nombre_repo ssh://git@202.122.234.090:27/~/repositorios/myNewProject.git
Borrar conexión
1
git remote rm nombre_repo
Cambiar nombre de la conexión
1
git remote rename nombre_repo new_nombre_repo

Intercambio y actualización de proyectos con el repositorio remoto.

Existen en local unas ramas ocultas (espejo) que son las copias locales de las ramas remotas. Estas ramas ocultas o espejo del repositorio remoto tienen la siguiente sintaxis nombre_repo_remoto/nombre_rama.

Ver las ramas ocultas o espejo
1
git branch -a
Sincronizamos estas ramas ocultas locales con el repositorio remoto. Es decir, bajamos las actualizaciones.
1
git fetch nombre_repo_remoto
Fusión de una rama oculta, que es una copia local de la remota, a nuestra rama activa.
1
git merge nombre_repo_remoto/master
Combinación de los dos comandos anteriores en una sola sentencia.
1
git pull nombre_repo_remoto master
¡CUIDADO!: Deshacemos todos los cambios locales y commits. Traemos la última versión del servidor y apuntamos la copia local principal a ella.
1
2
git fetch nombre_repo_remoto
git reset --hard nombre_repo_remoto/master
Subir los últimos commits al repositorio remoto, en concreto, a la rama “master”.
1
git push nombre_repo master

Un problema frecuente es subir algún cambio a una rama que alguien actualizó antes. Git no dejará pisar la actualizaciones. Para solucionarlo es necesario actualizar la copia local con pull (fetch + merge) y luego hace push.