Git: control de versiones

Git permite a grupos de personas trabajar en los mismos documentos o código al mismo tiempo sin pisarse unos a otros. Al igual que CVS o Subversion es un control de versiones aunque en este caso es distribuido permitiendo que cada usuario tenga una copia local del repositorio.

Configuración e inicialización

Para inicializar un nuevo directorio para funcionar con git.

# crear un directorio
mkdir mi_directorio

# entrar en el directorio
cd mi_directorio

# inicializar git
git init

Para asignar un usuario global y un email para el usuario

git config --global user.name usuario@mail.net

git config --global user.email usuario@mail.net

Si queremos que sea en un usuario local

git config --local user.name usuario@mail.net

git config --local user.email usuario@mail.net

Nota: Para incluir en la configuración de sistema usaremos —system

También podemos añadir ciertos alias para simplificar la escritura de comandos.

git config --global alias.co checkout

O configurar colores en la salida de datos

git config --global color.ui auto

Es muy útil poder guardar las credenciales en el credential.helper

# Guardar las credenciales localmente
git config credential.helper store

# Guardar las credenciales Globalmente
git config --global credential.helper store

Consultar estado y logs

Consultar el estado de los archivos, si no se han añadido, si estan en el espacio de stage, etc.

git status

Si es muy extensa la salida usar -p

git -p status

Consultar se puede consultar el log de diferentes formas

# log normal
git log

# log en una linea
git log --oneline

# log en una linea y con un solo nivel
git log --oneline --first-parent

Incluir/excluir archivos en git, commit y subirlos al servidor

Tras crear un archivo hay que añadirlo al indice para su seguimiento, para ello

git add archivo.ext

Esto añade el archivo al área de Staging

Si queremos añadir todos los archivos del directorio actual

git add .

Si queremos sacar el archivo del área de staging

git reset mi_archivo

Una vez que los cambios se han concluido añadimos a git y al log con un mensaje

git commit -m "mi mensaje"

Pero esto solo lo agrega localmente, si queremos subir los cambios a un servidor necesitamos hacer un push

git push

También podemos ver diferencias entre los archivos

# Para ver las diferencias de un archivo con lo que hay en stage
git diff

# Para ver las diferencias de un archivo que esta en stage pero no comiteado
git diff --staged

Consultar y cambiar de rama

# Consultar ramas
git branch

# Consultar ramas remotas
git branch --remote
git branch -r

# Crea una rama con el nombre dado
git branch nombre_rama

# Cambiar a una rama
git switch

# Checkout una rama creada
git checkout

# Checkout y con creacion de rama
git checkout -b nombre_rama

Checkout nos permite también quitar los cambios de un archivo usando

git checkout -- archivo.ext

# si queremos quitar todos los cambios
git checkout -- .

Compartir un repositorio

Para empezar a compartir los cambios con otros es necesario sincronizar con el repositorio remoto.

# Añadir un repositorio remoto
git remote add origin https://github.com/githubuser/MiRepositorio.git

# Para enviar un commit al master
git push -u origin master

# Una vez seteado se puede hacer con
git push

# ver ramas existentes en remoto
git branch --remote
git branch -r

# para renombrar una rama
git branch -m nuevo_nombre
# o para forzar el cambio de nombre
git branch -M nuevo_nombre # -M equivale a -m --force

Stash, guardar cambios para mas tarde

# Añadir una serie de cambios a un stash para usarlos luego se hace con
git stash
# con -u añadirias también las que no estén traceadas

# lista los archivos que están en el stag
git stash list

# devuelve los cambios que estaban en el stash a la rama de trabajo, y los borra del stash
git stash pop

# devuelve los cambios que estaban en el stash a la rama de trabajo sin borrarlos del stash
git stash apply

# también puedo listar los stash y obtener el identificador para aplicarlo
git stash apply stash@{2}

# descarta los cambios de la parte de arriba de la pila, elimina los datos del stash
git stash drop

Traer datos del repositorio remoto

# Obtener todas la ramas del repositorio remoto
git fetch

# Si ademas de obtener queremos borrar la informacion de las ramas que se borraron en el remoto, pasamos el parametro prune
git fecth -p

# Para obtener todos los commits de una rama
git pull

# esto varia en el caso de que queramos hacer un rebase de esos datos en nuestro local
git pull --rebase
git pull -r

Combina ramas y reseteo de cambios

# mergea la rama indicada con la rama actual
git merge <branch>

# Otra opcion pero en lugar de hacer un merge hace un rebase
git rebase <branch>

# quita los cambios de stage, y vuelve la rama al estado del commit indicado
git reset --hard <commit>

Traqueando cambios en el path (Tracking path changes)

# borrar el archivo del proyecto y poner en el stage los cambios para commit
git rm <archivo>

# cambiar el archivo del path y meter el cambio en el área de stage
git mv [existing-path] [new-path]

# mostrar el log de todos los cambios comiteados con cambios de path
git log --stat -M

Si queremos quitar un archivo o archivos ya comiteados (ej.- .idea)

#comprobamos si existen con
git ls-files .idea

# si existen y los queremos eliminar
git rm -r --cached .idea

Después se realizará el commit para eliminarlos del servidor

Cambiar nombre de rama

Se ha creado una rama:

git checkout -b rama-nombre-inicial

y queremos cambiar el nombre

En local

si estamos en la rama

git checkout -m rama-nombre-nuevo

desde una rama diferente

git branch -m rama-nombre-inicial rama-nombre-nuevo

En remoto

Si la rama ya está en el repo, sería subir la nueva rama creada en local

git push origin -u rama-nombre-nuevo

y eliminamos la antigua

git push origin --delete rama-nombre-inicial

.gitignore e ignorar patrones

Si queremos ignorar ciertos archivos, podemos crear un archivo gitignore

touch .gitignore

Se edita el archivo y se añaden los archivos a ignorar

Forzar añadir una archivo

git add ruta_archivo/archivo.txt --force

# o también

git add ruta_archivo/archivo.txt --force

# la siguiente linea evita el ignorado
git add ruta_archivo/archivo.txt -u

Squash

Hacer un squas de una rama con rebase

git rebase -i 070e0e8d4304f953092a7375f0fdf39e41d1c6ac

# el comimt indicado es justo antes del que se quiere hacer el squash

Crear alias

git config --global alias.slog "log --graph --all --topo-order --pretty='format:%h %ai %s%d (%an)'"
git config --local alias.st "status"
git config --local alias.l "log --oneline"

Rebase

Regla memotécnica rebase == ponme en esta rama lo que hay en develop

  1. Actualizamos develop con los cambios del repositorio

    git checkout develop && git pull

    Si todo va correcto, se mostrará

    Switched to branch 'develop' Your branch is up to date with 'origin/develop'. Already up to date.

  2. Ahora vamos a la rama rama-a-actualizar y nos aseguramos de tenerla actualizada

    git checkout rama-a-actualizar && git pull

    Switched to branch 'rama-a-actualizar' Your branch is up to date with 'origin/rama-a-actualizar'. Already up to date.

  3. Hacemos el rebase con develop

    git rebase develop

  4. Y por último el push al repositorio

    git push , indicar --force de ser necesario

cherry pick

Permite llevar commits de una rama a otra, se realiza desde el commit más antiguo al nuevo desde la rama a la que quiero añadir los commits

git cherry-pick 4150415^..952015

en el ejemplo se realizaría desde el 4150415 al 952015

Configuración

Autoconfiguración de ramas remotas, si tu rama local no está conectada o es una rama nueva, puedes autoconfigurar el “—set-upstream” automáticamente en la configuración con:

git config --global push.autoSetupRemote true

Correcciones de email usuario

Si por alguna razón necesitas cambiar el email del usuario en el historial del log, la siguiente consulta realizará esa tarea

git rebase -r <commit-hash> \
    --exec 'if [ "$(git log -n 1 --format="%ae")" = "youremail@something.com" ]; then git commit --amend --no-edit --reset-author --date="$(git log -n 1 --format=%aD)"; fi'

Hay que indicar el correo que quieres buscar para cambiar y el hash desde el cual quieres hacer la gestión, también mantendrá la fecha que se creó en el commit.

Referencias

Atlassian Git español (es) Atlassian Git inglés (en)