Si las imágenes no funcionan, puedes intentar la versión sin-SVG de esta página.
Las imágenes SVG se han desactivado. (volver a habilitar SVG)
Esta página da una referencia breve y visual para los comandos más comunes en git. Una vez que conozcas un poco sobre la forma de trabajo de git, este sitio puede fortalecer tu entendimiento. Si estás interesado en cómo se creó este sitio, mirá mi repositorio de GitHub.
Los cuatro comandos de arriba copian archivos entre el directorio de trabajo, el stage (también llamado index), y la historia (en la forma de commits).
git add archivos copia archivos (en su
 estado actual) al stage.git commit guarda una snapshot del stage como un commit.git reset -- archivos quita archivos de stage; esto es,
 que copia archivos del último commit al stage. Usá este
 comando para "deshacer" un git add archivos. También podés usar
 git reset para quitar de stage todo lo que hayas agregado.git checkout -- archivos copia archivos desde 
 el stage al directorio de trabajo. Usá esto para descartar los cambios locales.Podés usar git reset -p, git checkout -p, o
 git add -p en lugar de (o en combinación con) especificar archivos
 particulares para elegir interactivamente qué partes copiar.
También es posible, además, saltarse el stage y hacer check-out de los archivos directamente desde los archivos de commit sin hacer primero el staging.
git commit -a  es equivalente a utilizar el comando git add 
 en todos los archivos que hubo en el último commit, y correr luego el comando
 git commit.git commit archivos crea un nuevo commit incluyendo
 los contenidos del último commit, además de un snapshot de archivos tomado 
 del directorio de trabajo. Adicionalmente, los archivos se copian 
 al stage.git checkout HEAD -- archivos copia archivos 
 del último commit a stage y al directorio de trabajo (a ambos)En el resto del documento, usaremos gráficos de la siguiente forma.
Los commits se muestran en verde como identificadores de 5 caracteres, y apuntan a sus padres. Los branch se muestran en naranja, y apuntan a un commit en particular. El branch actual se identifica por medio de una referencia especial HEAD, que es "adjuntada" al branch. En esta imagen, se muestran los cinco últimos commits, con ed489 siendo el más reciente. main (el branch actual) apunta a este commit, mientras que stable (otro branch) apunta a un antecesor del commit de main.
Hay varias formas de ver las diferencias entre commits. Debajo están algunos ejemplos comunes. Cualquiera de esos comandos pueden tomar opcionalmente como argumento nombres de archivos que limiten las diferencias a los archivos nombrados.
Cuando commiteás, git crea un nuevo objeto de commit utilizando los archivos del stage y establece el padre al commit actual. Entonces apunta el presente branch a este nuevo commit. En la imagen debajo, el branch actual es main. Antes de que se ejecutase el comando, main apuntaba a ed489. Luego, un nuevo commit, f0cec, se crea, con el padre ed489, y luego main se mueve al nuevo commit.
Este mismo proceso sucede aún cuando el branch actual es un ancestro de otro. Debajo, un commit ocurre en el branch stable, el cual fue un ancestro de main, resultando en 1800b. Luego, stable no es más un ancestro de main. Para reunir las dos historias, será necesario un merge (o rebase).
A veces pueden cometerse errores en un commit, pero son fáciles de corregir con
 git commit --amend. Cuando usás este comando, git crea un nuevo commit
 con el mismo padre que el commit actual. (El commit anterior será descartado
 si nada más lo referencia.)
Un cuarto caso es commitear con un HEAD detachado, como explicaremos después.
El comando checkout se usa para copiar archivos de los commits (o desde stage) al directorio de trabajo, y para opcionalmente intercambiar branches.
Cuando un nombre de archivo (y/o -p) se proporciona, git copia esos archivos
 desde el commit dado hacia stage y el directorio de trabajo. Por ejemplo,
 git checkout HEAD~ foo.c copia el archivo foo.c
 desde el commit llamado HEAD~ (el padre del commit actual) al
 directorio de trabajo, y además lo pasa a stage. (Si no se proporciona nombre de commit,
 los archivos se copiarán desde stage.) Notá que el branch actual no se cambia.
Cuando not se proporciona un nombre de archivo, pero la referencia es un branch (local), HEAD se mueve a ese branch (esto es, nosotros "cambiamos" ese branch), y entonces el stage y el directorio de trabajo se establecen para coincidir con los contenidos de ese commit. Cualquier archivo que existe en el nuevo commit (a47c3 debajo) se copia; cualquier archivo que exista en el anterior commit (ed489) pero no en el que está borrado; y cualquier archivo que exista será ignorado.
Cuando not se proporciona un nombre de archivo y la referencia no es
 un branch (local) — digamos, es un tag, un branch remoto, un identificador SHA-1, o
 algo como main~3 — obtenemos un branch anónimo, llamado
 un HEAD detachado. Esto es útil para saltar a través de la historia.
 Digamos que querés compilar la versión 1.6.6.1 de git. Podés hacer git checkout
 v1.6.6.1 (que es un tag, no un branch), compilar, instalar, y luego
 cambiar de nuevo a otro branch, digamos git checkout main.
 Sin embargo, commitear trabajos levemente diferentes con un HEAD detachado; esto es
 cubierto debajo.
Cuando el HEAD está detachado, commit trabaja como siempre, excepto que en un branch sin nombre. (Podés pensar en esto como un branch anónimo.)
Una vez que hacés un check-out de algo más, digamos main, el commit (supuestamente) no es referenciado más por nada, y se pierde. Notá que luego de ese comando, no hay nada referenciando 2eecb.
Si, por otro lado, querés guardar este estado, podés crear un nuevo
 branch con nombre usando git checkout -b nombre.
El comando reset mueve el branch actual a otra posición, y opcionalmente actualiza el stage y el directorio de trabajo. Además se usa para copiar archivos desde los commits a stage sin tocar el directorio de trabajo.
Si un commit se hace sin especificar nombres de archivos, el branch actual
 se mueve a ese commit, y luego el stage se actualiza para coincidir con ese commmit.
 Si se proporciona el parámetro --hard el directorio de trabajo también se
 actualiza. Si se proporciona el parámetro --soft ninguno se actualiza.
Si no se proporciona un commit, por defecto se refiere a HEAD. En este caso,
 el branch no se mueve, pero se pasa a stage (y opcionalmente al directorio de trabajo si
 se especifica el parámetro --hard) y reinicia a los contenidos del último commit.
Si se proporciona un nombre de archivo (y/o -p), entonces el comando trabaja
 en forma similar al checkout con un nombre de archivo, excepto que solo
 el stage (y no el directorio de trabajo) se actualice. (Además deberías especificar
 el commit del cual tomar los archivos, en lugar de HEAD.)
Un merge crea un nuevo commit que incorpora cambios de otros commit. Antes de mezclar, el stage debe coincidir con el commit actual. El caso trivial es si el otro commit es un ancestro del commit actual, en cuyo caso no se hace nada adicional. El siguiente más simple es si el commit actual es un ancestro del otro commit. Esto resulta en una mezcla fast-forward. La referencia simplemente se mueve, y luego al nuevo commit se le hace check out.
De otro modo, una mezcla "real" debe ocurrir. Podés elegir otras estrategias, pero por defecto se realiza una mezcla "recursive", la cual básicamente toma el commit actual (ed489 debajo), el otro commit (33104), y su ancestro común (b325c), y realiza una mezcla de tres vías. El resultado se guarda al directorio de trabajo y al stage, y luego ocurre un commit, con un padre adicional (33104) para el nuevo commit.
El comando cherry-pick "copia" un commit, creando un nuevo commit en el branch actual con el mismo mensaje y patch que otro commit.
Un rebase es una alternativa al merge para combinar múltiples branches. Mientras que un merge crea un solo commit con dos padres, dejando una historia no lineal, un rebase reproduce los commits del branch actual en otro, dejando una historia lineal. En esencia, esta es una forma automatizada de realizar muchas cherry-pick de una vez.
El comando de arriba toma todos los commits que existen en topic pero no en main (nombrados 169a6 y 2c33a), los reproduce dentro de main, y luego mueve el branch head al nuevo punto. Notá que los commits viejos serán recogidos por el recolector de basura si no son referenciados.
Para limitar qué tanto va hacia atrás, usá la opción --onto. El
 siguiente comando reproduce dentro de main el más reciente commit del
 branch actual desde 169a6 (exclusivo), concretamente 2c33a.
Además existe git rebase --interactive, que permite hacer
 cosas más complicadas que simplemente reproducir commits, descartar, reordenar,
 modificar o juntar commits. No hay una imagen obvia para graficar este concepto; ver git-rebase(1)
 para más detalles.
Los contenidos de los archivos no se almacenan en realidad en el índice (.git/index) o en objetos commit. En su lugar, cada archivo se almacena en el objeto database (.git/objects) como un blob, identificado por su hash SHA-1. El archivo de índice lista los nombres de los archivos junto con el identificador del blob asociado, así como otros datos. Para los commits, hay un tipo de dato adicional, un tree, también identificado por su hash. Los trees se corresponden con directorios del directorio de trabajo, y contienen una lista de trees y blobs que se corresponden a cada nombre de archivo dentro de ese directorio. Cada commit almacena el identificador de su tree de alto nivel, el cual a su vez contiene todos los blobs y otros trees asociados con ese commit.
Si hacés un commit usando un HEAD detachado, el último commit es el que se
 referencia por algo: el reflog para HEAD. Sin embargo, esto expirará
 luego de un tiempo, por eso el commit eventualmente será recogido por el garbage
 collector, de forma similar a los commits descartados con git commit --amend
 o git rebase.
Copyright © 2010, Mark Lodato. Spanish translation © 2012, Lucas Videla.
Este trabajo está licenciado bajo una Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License.