IronWoods.es

Desarrollo web

Blog / Git / Comandos más habituales

Esta es una recopilación de comandos para trabajar en Git mediante la terminal. La página es una actualización, más extensa y mejor presentada, de una versión anterior, disponible aquí.

Nota: aunque en la descripción de las operaciones me suelo referir a ficheros, sobre lo que se trabaja es sobre modificaciones en los ficheros.

Contenidos:

1. INICIAR REPOSITORIOS



Iniciar un repositorio local


Ir al directorio donde se va a inicial el repositorio

cd d:/xampp/htdocs/repo-x


Tip: al abrir la consola en el directorio donde vamos a trabajar no habrá que escribir la ruta.


Iniciar repositorio

git init


Configurar repositorio

git config --global user.name 'Moises Alcocer'

git config --global user.email 'mi_mail@hgo.es'


Crear fichero .gitignore

echo > .gitignore

Fichero con los nombres de los ficheros, las extensiones y los subdirectorios que no deben ser incluidos en el repositorio. Lo abriremos con un editor de texto y añadimos lo necesario.

Tip: Podemos buscar plantillas según el tipo de desarrollo para no partir de 0, p.e. si empezamos un proyecto con Yii2, buscar "gitignore Yii2". En este fichero aparecen, los añadidos por IDEs, editores, etc. que deben ser ignorados.


Crear fichero README.md

echo > readme.md

Fichero de texto plano con información del repositorio. Necesario en GitHub, donde se muestra a los visitantes del repo.


Subíndice
1. Iniciar repositorios


Iniciar un repositorio remoto


Creamos un repositorio remoto Git en un sitio web especializado (BitBucket, GitHub, etc.) siguiendo sus instrucciones.


Crear un repositorio local (si no existe) y hacer un primer commit

git init

git add README.md

git commit -m 'primer commit'


Sincroniza el repo local con el remoto, por ejemplo:

git remote add origin http://github.com/oricis/nombre-repo.git


Enviar el contenido del repo local (PUSH)

git push -u origin master


Subíndice
1. Iniciar repositorios


Clonar un repositorio remoto


Este procedimiento nos permite obtener un repositorio local con el contenido de uno remoto: ficheros, commits, mensajes de logs...


En el directorio donde se alojará el repositorio, comando:

git clone http://github.com/oricis/nombre-repo.git


Nota: un repositorio privado requiere nombre usuario / contraseña.


Al finalizar tenemos una copia de "casi" todo el contenido del repositorio: faltarían contenidos del proyecto no incluidos por el autor, como logs, imágenes, librerías de terceros... y quizás el fichero, ".gitignore" que tendremos que añadir si es el caso, así como las dependencias necesarias si las hay, que deberían estar reflejado en la documentación del repositorio y ficheros de configuración (package.json, composer.json, etc.).

Si el repo es nuestro, es decir, lo subimos desde otra máquina, podemos traernos lo necesario manualmente.


Subíndice
1. Iniciar repositorios

Índice de contenidos

2. CAMBIAR DE REPOSITORIO REMOTO

Conectar el repositorio local con un nuevo repositorio remoto


Pueden dejar de enviarse las actualizaciones del repositorio local al remoto desvinculándolos y vincular un repositorio remoto diferente. Por ejemplo, se cambia el vínculo del repo http://xhub.com/user/skeleton.git a http://xhub.com/user/xna.git


Ver el repositorio remoto al que está vinculado el local

git remote show origin


Desvincular repositorio local del remoto

Después de ejecutar el siguiente comando, el anterior debería dejar de darnos información (hemos desvinculado el repositorio local)

git remote remove origin


Vincular el repo local con uno remoto

git remote add origin http://github.com/oricis/nombre-repo.git


Cambiar vinculación entre repo local y remoto

Las dos acciones anteriores, secuencialmente permiten cambiar de repositorio remoto, es decir, primero se desvincula el original y luego se vincula el nuevo. Con un sólo comando:

git remote set-url origin http://github.com/oricis/nombre-repo.git


Enviar el contenido del repo local (PUSH)

git push -u origin master

Índice de contenidos

3. DESHACIENDO COSAS


Descartar cambios en un fichero desde el último commit

git checkout -- fichero.ext


Si aun aparecen los ficheros como modificados: añadirlos al stage y volver a descartar cambios

git add --all

git checkout -f


Subíndice
3. Deshaciendo cosas

Mover ficheros del stage al working area


Sacar todos los ficheros del stage al working area

git reset

git reset HEAD


Sacar un fichero del stage al working area

git reset HEAD fichero.xy


Sacar un directorio completo del stage al working area

git reset HEAD -- path_to/directorio/


Subíndice
3. Deshaciendo cosas

Deshacer un PULL (o volver al estado anterior a un PULL)


PULL es la acción por la que traemos al repositorio local el contenido de un repositorio remoto. Podemos restaurar el estado del repositorio local al momento anterior a un PULL

git reset --hard


Subíndice
3. Deshaciendo cosas

Limpiar el working area


Si tenemos ficheros como modificados, pero un 'git diff' no muestra cambios, para limpiarlos usamos el comando

git checkout -f


Subíndice
3. Deshaciendo cosas

Añadir ficheros al último commit


Podemos incluir ficheros olvidados en el último commit realizado. Primero tenemos que añadir el fichero o ficheros al 'stage area'

git add fichero_olvidado.xxx


Seguidamente usamos el comando

git commit --amend


Se abrirá el editor (Vim, por defecto. Se sale con ZZ)


Subíndice
3. Deshaciendo cosas

Modificar mensajes de los commits


Cambiar el mensaje del último commit

Modificar mensaje del último commit en el editor

git commit --amend


Corregir mensaje del último commit de forma directa

git commit -m "Mensaje corregido" --amend


Cambiar el mensaje de un commit anterior

Este procedimiento es algo más complicado que el anterior, por lo que le he dedicado una entrada: Git - Reescribiendo la historia.


Subíndice
3. Deshaciendo cosas

Descartar commits


Descartar último commit perdiendo las modificaciones (CUIDADO)

git reset --hard HEAD

o bien

git reset --hard HEAD~1 #Indica núm. de commits a desechar


Descartar último commit conservando las modificaciones

Los ficheros van al working area

git reset HEAD~1 #Indica núm. de commits a desechar


Descartar último commit conservando las modificaciones

Los ficheros van al stage area

git reset --soft HEAD~1 #Indica núm. de commits a desechar


Subíndice
3. Deshaciendo cosas

Índice de contenidos

4. VIENDO CAMBIOS - COMMITS REALIZADOS

Ver histórico de commits: hash, autor, fecha y mensaje

git log


Ver histórico de commits: hash, autor, fecha y mensaje de un fichero

git log -- path/file.ext


Ver histórico de commits: hash, autor, fecha y mensaje para los ficheros de un directorio

git log -- directory_path/*


Ver últimos commits: hash, autor, fecha y mensaje

El núm. indica cuantos commits mostrar desde el último que se llevó a cabo

git log -2


Ver histórico de commits: hash, autor, fecha, mensaje, ficheros incluidos y tipo cambios de cada uno (líneas borradas y/o añadidas)

Ver todos los ficheros incluidos en un repositorio

git log --stat


Ver últimos 2 commits con diff

El núm. indica cuantos commits mostrar desde el último que se llevó a cabo

git log -p -2


Ver histórico de commits: hash, autor, fecha y mensaje

Realizados desde hace un tiempo determinado

git log --since=2.weeks #En las últimas 2 semanas

git log --since=3.days #En los últimos 3 días


Ver histórico de commits: hash, autor, fecha y mensaje + diff, realizados desde hace un tiempo determinado

git log --since=2.weeks -p #En las últimas 2 semanas

git log --since=3.days -p #En los últimos 3 días


Ver histórico de todos los commits que afectan a un fichero

git log -- path/file.ext

git log --pretty=oneline --branches -- path/file.ext # Una fila por commit


Mostrar una única fila por commit

git log --pretty=oneline --branches # En todas las ramas

git log --pretty=oneline # En la rama actual



Ver histórico de commits con mejoras visuales (origen)

git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit


Incluidos los ficheros de cada commit

git log --stat --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit


Configurando un alias (solo una vez)

git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"


Ahora la llamada será:

git lg

Índice de contenidos

5. VIENDO CAMBIOS - FICHEROS COMMITEADOS

Ver los cambios de los ficheros con sus versiones anteriores


Cuando un fichero se guarda en el repositorio (después de ser añadido a un commit), pasa a estar bajo el control de versiones. Una vez versionado un fichero podremos ver cada cambio que le afecta desde su primer commit.


Ver cambios de los ficheros en el 'working area'

git diff


Ver cambios de los ficheros en el 'stage area'

git diff --staged



Tip: podemos usar filtros, para operar sobre archivos o grupos concretos


Ficheros de tipo .xx, del directorio raíz, en el 'working area'

git diff *.xx


Todos los ficheros .php y .less, en el 'working area'

git diff -- '*.php' '*.less'


Nombres de los ficheros modificados desde un commit concreto

git diff --name-only <commit-hash> HEAD


Nombres de los ficheros modificados desde un commit concreto, de cierto tipo, p.e. .php:

git diff --name-only <commit-hash> HEAD -- '*.php'


Nota: La cantidad de caracteres mínima para identificar un hash es siete.

Índice de contenidos

6. OPERACIONES BÁSICAS


Ver cambios en los ficheros del proyecto


Ver ficheros del 'stage area' así como modificados, creados, eliminados... en el 'working area'

git status


Cuando hay muchos cambios podemos añadir filtros al comando anterior

git status | grep deleted: # Sólo eliminados


git status | grep modified: # Sólo modificados


Subíndice
6. Operaciones básicas

Añadiendo ficheros al 'stage' (mover ficheros del working al stage area)


git add . # Todos los ficheros

git add --all # Todos los ficheros, incluso lo que se ha eliminado



Añadiendo ficheros al 'stage'. Aplicando filtros


git add fichero.in # Un fichero concreto

git add fichero.in xxx.txt # Dos ficheros concretos

git add app/*.php # Ficheros .php del directorio app/ (NO de subdirectorios)

git add app/*/*.php # Ficheros .php del directorio app/ y de subdirectorios

git add app/* # Todos los ficheros del directorio app/ y de los subdirectorios



Añadiendo ficheros al 'stage'. Procedimientos específicos


Añadir todos los ficheros salvo los untracked (no en seguimiento), es decir no añade los nuevos ficheros

git add -u


Añadir todos los ficheros excepto un archivo

Se realiza en dos pasos. Primero se añaden todos los ficheros y seguidamente, se devuelve al área de trabajo el fichero en cuestión

git add --all

git reset -- path/fichero.php


Añadir todos los ficheros excepto los de un directorio

Se realiza en dos pasos. Primero se añaden todos los ficheros y seguidamente, se devuelve al área de trabajo los ficheros del directorio en cuestión

git add --all

git reset -- path/*


Subíndice
6. Operaciones básicas


Realizar commits


El flujo habitual de trabajo será: crear / modificar un fichero, añadirlo al 'stage', crear / modificar otro fichero, añadirlo al 'stage'... guardar los ficheros del 'stage area' en el repositorio (commit).


Commit con el contenido del 'stage area'

git commit -m 'mensaje "info" del commit'



Commit directo desde del 'working area' (saltándose el stage)


Commit de todos los ficheros

git commit -a -m 'mensaje "info" del commit'

git commit --all -m 'mensaje "info" del commit'


Commit de un fichero concreto

git commit */file.ext -m 'mensaje info del commit'

git commit fichero.ess 'mensaje info del commit'



¡Atención: cuidado con las comillas!

Abrir / cerrar el mensaje siempre con comillas simples u usarlas dobles en el interior del mismo


Subíndice
6. Operaciones básicas

Sincronizar cambios entre repositorios (local-remoto)


Enviar contenido commiteado al repositorio remoto

git push


Forzando la reescritura de su contenido (cuidado)

git push --force


Traer contenido commiteado desde repositorio remoto

git pull


Subíndice
6. Operaciones básicas

Índice de contenidos

7. TRABAJO CON RAMAS


Ver listado de ramas existentes


Listar todas las ramas disponibles

git branch


Listar las ramas disponibles viendo última confirmación de cambios en cada rama

git branch -v


Listar las ramas que fueron fusionadas con la rama activa

Recomendable antes de eliminar una rama para asegurarnos de no perder el trabajo

git branch --merged


Listar las ramas que no fueron fusionadas con la rama activa

git branch --no-merged


Subíndice
7. Trabajo con ramas

Crear ramas


Crear una nueva rama (sólo se crea, no nos movemos de la actual)

git branch nombre-rama


Crear una nueva rama y saltar a ella (mueve el apuntador HEAD)

git checkout -b otra-rama #Usa la opción -b


La instrucción anterior equivaldría a hacer

git branch otra-rama

git checkout otra-rama


Subíndice
7. Trabajo con ramas

Cambiar de rama


Saltar a otra rama (mueve el apuntador HEAD)

git checkout nombre-rama

git checkout -f nombre-rama #Forzar el salto


Subíndice
7. Trabajo con ramas

Borrar ramas


Debemos encontrarnos en otra rama diferente a la que queremos borrar

git branch -d otra-rama

Si contiene cambios sin fusionar nos da un mensaje de error


Elimina la rama, aunque tenga cambios NO fusionados con la rama activa

git branch -D otra-rama


Borrar ramas remotas

git push origin --delete nombre-rama

git remote prune origin // Eliminar referencia


Subíndice
7. Trabajo con ramas

Fundir ramas


Incorporar el trabajo de una rama a la rama master

git checkout master #Vamos a la rama master si estamos en otra

git merge otra-rama # Fusionamos la rama

git branch -d otra-rama # Borramos la rama fusionada


Subíndice
7. Trabajo con ramas

Limpiar el historial de ramas


git remote prune origin


Subíndice
7. Trabajo con ramas

Índice de contenidos

8. SUBMÓDULOS

Se puede tener un repositorio de Git dentro de otro repositorio de Git y guardar los commits de manera independiente

https://git-scm.com/book/en/v2/Git-Tools-Submodules


Este sería el mecanismo "correcto" para por ejemplo casos como el siguiente:

Estamos montando un sitio web que versionamos. Dentro, desarrollamos a su vez una librería, que tiene a su vez su control de versiones, por lo que queremos que los cambios de la librería se guarden en su propio repositorio, pero no aparezcan en el del sitio web que la incluye.


El sistema de submódulos me parece una complicación.

Si se añade el directorio de la librería al '.gitignore' del proyecto que la contiene se trabaja con ambos repositorios de forma independiente.

Índice de contenidos

9. VARIOS

Comandos para VIM


'Vim' es una cosa infernal para los que entramos en contacto con él por primera vez. Cuando hacemos algo que lo abre, sólo nos queda la opción de cerrar la consola de comandos a lo bruto.

Con unos comandos básicos podremos por lo menos cerrar este editor de la forma "correcta".


Salir de 'Vim' guardando cambios (si se editó contenido)

ZZ

ESC + ZZ


Ahora que hemos conseguido salir, lo mejor será alejarnos de las puertas del infierno para siempre. Esta aplicación fue una maravilla en el pleistoceno medio, por suerte podemos cambiar el editor de texto de 'Git' (ver abajo).

Otros comandos de Git


Cambiar editor de texto de la consola Git

Editor instalado en el equipo (Sublime):

git config --global core.editor "\"c:\Program Files\Sublime Text 3\sublime_text.exe\""

Editor incluido en la terminal de Git (Nano):

git config --global core.editor nano


Ver configuración global de Git

git config --list

Más sobre la configuración de Git en: https://git-scm.com/docs/git-config


Desplazarse por el contenido de un diff / log

Usar las teclas de dirección para movernos arriba y abajo.


Salir de un diff / log

Finalizar la revisión y volver al "modo normal" de la terminal pulsando:

Q


Ignorar ficheros del directorio de trabajo

No realizar seguimiento del archivo, pero mantenerlo en el directorio de trabajo

Útil si se olvida añadir archivos al '.gitignore' antes de crear el repositorio y ya se agregaron al repositorio.

Añadir el fichero / directorio al '.gitignore' y ejecutar:

git rm --cached mi_archivo.xxx


Ver URL asociada a un repositorio remoto:

git remote -v


Recuperar control de la línea de comandos

Para recuperar el control de la terminal, y poder introducir otro comando, por ejemplo, después de un git log, podemos usar una combinación de teclas, que detiene la ejecución del comando:

Ctrl + z


O mejor, la combinación, que cancela el comando en curso y nos devuelve el control de la terminal, incluso cuando un comando no responde y perdemos el control de la misma:

Ctrl + c

Operaciones Sobre Ficheros


Eliminar un fichero

git rm fichero.txt


Cambiar el nombre de un fichero

git mv nombre_actual nombre_nuevo

Índice de contenidos



(Actualizado 16-09-2020)