Este es un repositorio con una lista de comandos para escribir en el terminal de Git. Los conceptos no se explican demasiado, se debe considerar más como una "cheat sheet".
Todos los comandos deben ejecutarse desde el directorio raíz del repositorio. Las palabras entre <> se deben reemplazar por el nombre del elemento que describen.
Git permite:
- Guardar sólo los cambios realizados a muchos archivos.
- Permitir que múltiples personas modifiquen el mismo archivo sin que se pierda el trabajo de ninguno.
- Saber qué persona cometió algún error.
- Revertir los cambios a una versión anterior.
Se debe descargar el instalador desde el sitio web oficial. Para asegurarse de que se instaló correctamente, se puede usar el siguiente comando.
git --version
-
Directorio de trabajo: Entorno de desarrollo personal, lo que se ve en el explorador de archivos, también conocidos como
untracked
. -
Área de preparación o
staging
: Espacio en la RAM donde se almacenan los archivos que rastrea Git, también conocidos comotracked
. Se añaden archivos a este espacio usandogit add
. -
Repositorio local: Archivos en la base de datos que se encuentra en la carpeta .git. Al usar
git commit
, se mueven todos los cambios enstaging
al repositorio local. -
Repositorio remoto: Repositorio almacenado en un servidor en internet. Se puede descargar como repositorio local usando
git clone
. Los cambios del repositorio local se mueven a él usandogit push
. Se pueden recibir los cambios usandogit fetch
+git merge
o usandogit pull
. -
HEAD
: Es el lugar donde se está trabajando en el momento actual. -
master
: -
origin
: Es el nombre del repositorio remoto por defecto, que aparece al usargit clone
.
git
git help <comando>
Esto abrirá la documentación sobre el comando en el navegador predefinido.
git <comando> --help
Para poder realizar commits, Git necesita que su usuario registre su nombre y correo.
git config --global user.name "<nombre>"
git config --global user.email "<correo>"
git config user.name
git config user.email
Existen 2 formas de hacerlo:
git config -l
git config --list
git config --list --show-origin
gitk
git init
Por defecto, este repositorio se iniciará con la rama master
.
Se crea un área staging
en la memoria RAM.
Se crea el repositorio en la carpeta .git
.
Por defecto, todos los archivos al momento de inicializar serán untracked
.
git init <ruta>
git init -b <rama>
git config --global init.defaultBranch <rama>
Esto cambiará el nombre de la rama creada al usar git init
.
Un ejemplo de uso es para cambiar el valor por defecto master
a main
, ya que gran parte de la comunidad de Git ha empezado a migrar a este nuevo nombre.
git clone <url>
La copia se almacenará en la carpeta actual.
git clone <usuario>@<host>:<ruta>
Usando HTTPS o SSH
git clone <url> <carpeta>
git clone <usuario>@<host>:<ruta> <carpeta>
git config --local user.name "<nombre>"
git config --local user.email "<correo>"
Esta configuración se guardará como local y sobreescribe la configuración global (sólo para los repositorios donde se haya configurado).
git add <archivo>
Los archivos añadidos con git add
se vuelven tracked
y se mueven a staged
.
Para confirmarlos, se usa el comando git commit
, que se explica más adelante.
git add <directorio>
No se pueden agregar directorios vacíos. Git sólo registra cambios hechos a archivos y añade directorios sólo cuando tienen archivos dentro de ellos.
Existen 2 formas de hacerlo.
git add .
git add --all
Se agregan todos los archivos de la carpeta actual.
git reset
Estos cambios se marcarán como untracked
.
git reset <archivo>
git reset --soft
git reset --hard
git commit -m "<mensaje del commit>"
El commit confirma todos los cambios staged
al momento de realizarlo.
Los cambios confirmados se mueven a la carpeta .git
.
El mensaje debería describir en qué consistió el cambio.
git commit
En realidad, no se puede hacer un commit si un mensaje. Git mostrará un mensaje por defecto indicando que el usuario debe escribir el mensaje del commit y le pedirá que lo ingrese. Se pedirá escribir el mensaje utilizando el editor Vim.
Para comenzar a escribir texto se debe pulsar Escape + I, con lo cual se cambia al modo INSERTAR
.
Para salir de esta pantalla se debe pulsar Escape, escribir :wq
y pulsar Enter, lo cual guarda el archivo y realiza el commit.
Si se deja el mensaje del commit en blanco, se aborta la realización del commit.
git log
Si Git tiene demasiada información que mostrar con comandos como git log
, entonces no podrá mostrarla toda en pantalla al mismo tiempo.
Se puede pulsar Intro para mostrar la próxima línea, siempre que no aparezca (END)
al final.
También se pueden usar las flechas para moverse por el archivo.
Para salir, se debe escribir q
en el terminal.
git log --oneline
Esto reducirá los detalles que se muestran sobre cada commit.
git log <archivo>
git log --stat
git status
El estado mostrará la rama actual y su estado al compararla con la rama remota, si esta existe.
Luego mostrará los cambios que tiene la base de datos, los cuales se separan en los cambios a archivos en staged
, los archivos que han recibido cambios pero todavía no están en staged
y los archivos nuevos, que todavía no son parte del repositorio.
git show
git add *.<extensión>
git add "*.<extensión>"
git restore --staged <archivo>
git add -i
Esto inicia un menú para manejar los cambios.
Existen 2 formas de hacerlo. No es necesario usar git add
de antemano.
git commit -am "<mensaje del commit>"
git commit --all -m "<mensaje del commit>"
Con "archivos conocidos" se refiere a los archivos que ya eran parte del repositorio en el último commit realizado y que tuvieron cambios desde la realización de éste. En otras palabras, los archivos nuevos serán ignorados en este commit.
git diff
Para los archivos binarios sólo se indica que difieren, ya que las diferencias son incomprensibles comparadas con el texto plano.
git diff --staged
git reset --soft HEAD^
git reset --hard HEAD^
git reset --hard HEAD^^
git add <archivo>
git commit --amend -m "<mensaje nuevo>"
El mensaje anterior se sobreescribirá.
git add <archivo>
git commit --amend
Esto permite mantener el mensaje original o cambiarlo si se quiere.
git blame <archivo>
git rm <archivo>
Esto sólo funciona con los archivos que están presentes en el último commit realizado.
Se debe crear el siguiente archivo en la carpeta raíz o donde están los archivos que se quieren ignorar.
.gitignore
El archivo se modifica con cualquier editor de texto y los nombres de archivos o directorios dentro de él serán ignorados por Git.
Por ejemplo, para hacer que Git ignore el archivo archivo.txt
y todos los archivos de la carpeta test
, el .gitignore debe tener el siguiente contenido.
archivo.txt
test
También se puede usar el hash #
para escribir comentarios en el .gitignore.
# Este es un comentario
Se puede utilizar el símbolo de exclamación !
para indicar algo que no se debe ignorar dentro de un directorio ignorado.
content
!content/README.md
También se puede utilizar el wildcard para aceptar todos los archivos que cumplan cierto patrón. El siguiente ejemplo ignora todos los archivos de extensión .png.
*.png
Generalmente, se usa .gitignore para ignorar los siguientes tipos de archivos:
- Documentos que no son escritos como texto plano
- Archivos binarios como imágenes, sonidos o videos
- Archivos con contraseñas o llaves de APIs, SSH, etc
- Configuraciones del entorno de ejecución
- Archivos compilados o usados sólo durante el proceso de compilación
- Archivos externos
- Logs o trazas
- Archivos que genera el sistema operativo
- Archivos que pueden contener información personal
- Archivos comprimidos como por ejemplo .zip, .tar.gz, .7z o .rar
git add -f <archivo>
git rm --cached <archivo>
Con archivo ignorado se refiere a los que aparecen en .gitignore
, pero tenían una versión guardada en el último commit.
Al igual que git add
, esta operación será confirmada en el próximo commit.
git branch <rama>
La rama creada será igual a la de origen y no estará activa.
git checkout <rama>
Esto cambiará los archivos del directorio a los de la rama especificada.
git checkout -b <rama>
Básicamente es lo mismo que git branch
seguido de git checkout
.
git branch
La rama activa se mostrará en verde.
git branch -r
git branch -a
git branch -d <rama>
Si se tienen commits sin fusionar, se mostrarán errores.
git branch -D <rama>
Esto ignorará cualquier error. Se debe tener cuidado al momento de usarlo.
git branch -m <nombre nuevo>
git diff <rama de origen> <rama de destino>
git merge <rama>
Los commits siempre irán desde la rama escrita a la rama activa.
Los cambios se reciben en un nuevo commit, el cual también debe tener un mensaje.
Es por este motivo que al usar git merge
, se abrirá el editor Vim.
Sin embargo, en la mayoría de los casos el mensaje por defecto es suficiente.
Después de fusionar, se añade el nuevo commit a la rama activa y se traen todos los commits nuevos de la rama especificada.
Git nunca borra nada.
En caso de que ocurra un conflicto, por ejemplo cuando 2 commits en 2 ramas distintas modifiquen la misma línea del código, este conflicto deberá ser gestionado manualmente.
La rama activa pasará a ser una rama temporal con el nombre <rama activa>|MERGING
para indicar que la operación git merge
no se pudo completar.
<<<<<<<< HEAD
<línea en la rama actual>
========
<línea en la rama que se quiere fusionar>
>>>>>>>> <rama que se quiere fusionar>
En los conflictos, <<<<<<<<
indica el commit de la rama actual, >>>>>>>>
indica el commit de la rama que se quiere fusionar y ========
actúa como un separador entre ambas versiones.
git status
El comando git status
que se mencionó anteriormente también indica los conflictos solucionados y los no solucionados.
Los conflictos deben solucionarse editando los archivos manualmente, decidiendo qué cambios se dejan.
Se debe realizar un commit para confirmar la fusión, los cambios deben volver a añadirse usando git add
.
Cuando se solucione el conflicto, la rama activa pasa de ser <rama activa>|MERGING
a <rama activa>
y la rama temporal se borra.
git merge --abort
git diff <hash del commit origen> <hash del commit destino>
El hash del commit es el que aparece al usar git log
.
Se puede usar el hash corto o el hash largo, pero se recomienda usar el largo si es posible.
Los cambios mostrados son los cambios que se harían para ir del commit origen al commit destino.
git checkout <hash del commit>
En este estado, no se pueden hacer commits.
git checkout -b <rama> <hash del commit>
Esto permite hacer commits en una rama nueva que tendrá como último commit el del hash que se le entregó.
git remote add origin <url>
Las ramas remotas tendrán el nombre origin/<rama>
.
git remote show origin
git branch -r
git push
git log --all
git log --all --graph
git log --all --graph --decorate --oneline
git tag <etiqueta> <hash del commit>
Las etiquetas generalmente se usan para marcar versiones.
git tag -a <etiqueta> -m "<mensaje>" <hash del commit>
git tag
git show-ref --tags
Son distintas a las referencias del commit que marcan.
git checkout <etiqueta>
git checkout <hash del commit> <archivo>
git checkout <rama> <archivo>
git checkout <etiqueta> <archivo>
git checkout <hash del commit> <archivo>
git add <archivo>
git commit -m "<mensaje>"
git remote add origin <url>
El nombre origin
es el más usado, pero se puede cambiar a lo que se desee.
Paso 1: Inicializar el repositorio local.
git init
git add .
git commit -m "<commit inicial>"
git branch -m main
En GitHub, main es el nombre por defecto de la rama principal, en vez de master.
Paso 2: Crear el repositorio en GitHub/GitLab y copiar su URL.
Paso 3: Añadir el repositorio remoto y subir los cambios.
git remote add origin <url>
git push -u origin main
Paso 4: Iniciar sesión en los logon que aparecerán.
Existen muchos métodos, pero el más seguro es usar SSH.
Paso 1: Generar una nueva clave SSH en base al correo electrónico.
ssh-keygen -t ed25519 -C "<correo del usuario>"
Se debe pulsar Intro cuando pregunte donde guardarlo para que se guarde en la ubicación por defecto. Después, se ingresa la passphrase que actuará como una contraseña. Es importante no olvidar la passphrase.
Paso 2: Copiar el siguiente texto y guardarlo como un archivo de nombre .profile
en la carpeta raíz de tu usuario del sistema operativo.
env=~/.ssh/agent.env
agent_load_env () { test -f "$env" && . "$env" >| /dev/null ; }
agent_start () {
(umask 077; ssh-agent >| "$env")
. "$env" >| /dev/null ; }
agent_load_env
# agent_run_state: 0=agent running w/ key; 1=agent w/o key; 2= agent not running
agent_run_state=$(ssh-add -l >| /dev/null 2>&1; echo $?)
if [ ! "$SSH_AUTH_SOCK" ] || [ $agent_run_state = 2 ]; then
agent_start
ssh-add
elif [ "$SSH_AUTH_SOCK" ] && [ $agent_run_state = 1 ]; then
ssh-add
fi
unset env
Paso 3: Volver a iniciar Git Bash e ingresar la passphrase que se registró anteriormente.
Paso 4: Copiar la clave SSH.
clip < ~/.ssh/id_ed25519.pub
Paso 5 (GitHub): Ir a GitHub > Settings > SSH and GPG keys > New SSH key y pegar la clave SSH.
Paso 5 (GitLab): Ir a GitLab > Preferences > SSH Keys > pegar la clave SSH y Add key.
Es importante recordar que esta clave es muy importante, ya que añade otro nivel de seguridad. No se debe compartir con nadie. Se pedirá esta clave regularmente.
Se debe ingresar a la carpeta home del usuario actual. En caso de usar Windows, se recomienda hacer todo este proceso desde Git Bash.
ssh-keygen -t <algoritmo> -b <grado de encriptación> -C "<email>"
En este ejemplo se usará el algoritmo de encriptación RSA.
ssh-keygen -t rsa -b 4096 -C "<email>"
Después, pedirá la ubicación donde se guardará. Se recomienda dejar la ubicación por defecto. Luego pide un passphrase, como una capa de seguridad adicional. Una passphrase es una contraseña que acepta espacios dentro de ella. El archivo sin extensión es la llave privada y el archivo .pub es la llave pública.
Después se debe añadir la llave, para que el sistema operativo la reconozca. El nombre del archivo varía dependiendo del método de encriptación empleado.
ssh-add ~/.ssh/id_rsa
Se debe añadir la clave privada, no la pública. Es importante crear una clave privada para cada equipo y cada usuario. Importante: NO SE DEBE MOVER NI COPIAR DE UNO A OTRO.
Copiar la llave pública SSH.
clip < ~/.ssh/id_rsa.pub
Se puede usar para pasar de HTTP a SSH o viceversa.
git remote set-url origin <url nueva>
git fetch
Cualquier conflicto que se encuentre deberá ser solucionado usando git add
.
git pull
Los conflictos se solucionarán automáticamente, pero puede causar errores.
Básicamente es un git fetch
seguido de un git merge
.
git pull <repositorio> <rama> --allow-unrelated-histories
Esto sirve para casos en los que el repositorio remoto se inició con otros archivos, como por ejemplo un README.md
o un .gitignore
.
git push -u
Esto hará que se suban los cambios locales y hace que se relacionen las ramas locales con las remotas automáticamente.
Se recomienda usar git fetch
o git pull
antes de git push
, especialmente si se está trabajando con otras personas.
git push
Este cambio sólo subirá los cambios de la rama activa.
Si es la primera vez que se suben cambios, se recomienda usar git push -u
.
git push --tags
git push --all
git tag -d <etiqueta>
git push origin :refs/tags/<etiqueta>
git reset --hard <hash del commit>
Esto eliminará todos los cambios locales. No se debe usar si todavía se tiene trabajo que se quiere mantener.
git revert <hash del commit>
Esto hará un commit que deshace los cambios.
git revert <hash del commit 1> <hash del commit 2> ...
Cada hash proporcionado creará su propio commit de reversión.
git revert --no-commit <hash del commit 1> <hash del commit 2> ...
git commit -m "<mensaje del commit>"
Esto permite juntar muchos git revert
en un mismo commit.
git remote add <nombre del repositorio> <url>
Al usar comandos como git clone
, el repositorio remoto creado por defecto se llama origin
.
Por este motivo, se acostumbra que el primer repositorio remoto tenga ese nombre.
Sin embargo, no es obligatorio.
Perfectamente, se pueden tener 2 repositorios remotos llamados github
y gitlab
.
git remote -v
git push <repositorio remoto> <rama>
git push <repositorio remoto 1> <rama 1> && git push <repositorio remoto 2> <rama 2>
git push origin :<rama>
git push -u <repositorio remoto> <rama>
Esto permite usar git push
para enviar todos los cambios que se hagan en el futuro, en vez de tener que escribir el repositorio y la rama otra vez.
git show-branch
git show-branch --all
git stash
Los cambios se almacenarán como un WIP (work in progress). Esto permite revisar otras versiones del repositorio sin perder los cambios que se estaban realizando antes y sin necesidad de tener que guardarlos en un commit incompleto.
git stash list
git checkout <rama donde se hizo el stash>
git stash pop
Esto elimina el stash de la lista.
git stash branch <rama nueva>
Esto elimina el stash de la lista.
git stash drop
Esto elimina el stash de la lista.
git clean
En realidad, este comando no hace nada, ya que es muy peligroso y por ese motivo requiere una confirmación.
git clean --dry-run
El comando git clean
ignorará los siguientes archivos:
- Las carpetas, sin importar que tengan archivos o no.
- Los archivos que están en el
.gitignore
.
Se recomienda revisar los archivos que se borrarán antes de utilizar este comando.
git clean -f
Git Flow es un programa distinto de Git, pero que funciona de manera muy similar.
git flow init
Esto permite seleccionar los nombres de las ramas master
, develop
, feature
, release
, bugfix
, hotfix
y support
.
En general, se recomienda mantener los nombres por defecto.
Se crearán las ramas master
y develop
.
git flow feature start <rama de característica>
Una rama de característica se usa para añadir una nueva funcionalidad al programa.
Estas ramas tendrán el prefijo feature/
por defecto.
Se basan en los commits que se tenían en develop
al momento de usar el comando.
git flow feature finish <rama de característica>
Esto realiza 3 cosas: une los cambios a develop
, cambia a esa rama y borra la rama de característica.
git log --oneline --decorate --all --graph
git log --decorate --all --graph
git checkout feature/<rama de característica>
git merge develop
git flow release start <rama de lanzamiento>
Una rama de lanzamiento es una versión casi terminada de develop
.
Estas ramas tendrán el prefijo release/
por defecto.
Se basan en los commits que se tenían en develop
al momento de usar el comando.
git flow release finish <rama de lanzamiento>
Esto realiza 3 cosas: une los cambios a develop
, cambia a esa rama y borra la rama de lanzamiento.
git flow bugfix start <rama de bugfix>
Una rama de bugfix
es una rama de correción de errores de una rama de release
.
Estas ramas tendrán el prefijo bugfix/
por defecto.
Se basan en los commits que se tenían en develop
al momento de usar el comando.
git flow bugfix finish <rama de bugfix>
Esto realiza 3 cosas: une los cambios a develop
, cambia a esa rama y borra la rama de bugfix.
git flow hotfix start <rama de hotfix>
Una rama de hotfix
es una rama de correción de errores de master
.
Estas ramas tendrán el prefijo hotfix/
por defecto.
Se basan en los commits que se tenían en develop
al momento de usar el comando.
git flow hotfix finish <rama de hotfix>
Esto realiza 3 cosas: une los cambios a develop
, cambia a esa rama y borra la rama de hotfix.
git flow feature publish <rama de característica>
git flow feature pull origin
git flow feature finish -F <rama de característica>
git flow bugfix pull origin
git flow bugfix finish -F <rama de característica>
git flow hotfix pull origin
git flow hotfix finish -F <rama de característica>
Esto cambia el commit de origen de la rama experimental por el último commit en la final. Básicamente, hace como que la rama experimental nunca existió y como que todos los cambios fueron realizados en la rama final.
git checkout <rama experimental>
git rebase <rama final>
git checkout <rama final>
git rebase <rama experimental>
Esto es una muy mala práctica si se usa en repositorios remotos. Para cambios locales su uso es aceptable. En general, su uso debería ser muy limitado, como por ejemplo para experimentos pequeños. También se debe tomar en cuenta que esto modifica la historia, así que en un futuro puede parecer que el orden de los cambios realizados no tiene sentido.
git cherry-pick <hash del commit>
Al momento de fusionar la rama con git merge
, podría aparecer algún conflicto, el cual debería ser fácil de solucionar en la mayoría de los casos.
Sin embargo, cherry-pick es considerado como una mala práctica, ya que al utilizarlo se está alterando la historia del repositorio.
git reflog
Este comando es muy útil cuando por algún motivo todo el repositorio se arruinó y se quiere regresar a un estado anterior del repositorio completo.
git reset --hard <hash del HEAD>
El hash del HEAD fue el que se obtuvo usando git reflog
.
Se debe tener en cuenta que el uso de este comando es muy peligroso.
El uso de este comando también se considera una mala práctica porque cambia la historia del repositorio.
git grep "<palabra>"
Esto indica los archivos y el texto donde se encuentra la palabra.
git grep -n "<palabra>"
Esto indica los archivos, los números de línea y el texto donde se encuentra la palabra.
git grep -c "<palabra>"
Esto indica los archivos y la cantidad de veces que se usa la palabra en cada archivo.
git log -S "<palabra>"
Muestra todos los commits donde se usó la palabra indicada.
git shortlog
git shortlog -sn
git shortlog -sn --all
Ver la cantidad de commits que ha hecho cada miembro del equipo, incluyendo los borrados e ignorando los merges
git shortlog -sn --all --no-merges
git config --global alias.<alias> "<comando>"
Esto permite utilizar comandos largos escribiendo pocas palabras.
Tanto el alias como el comando no deben incluir la palabra git
que se usa para iniciar todos los comandos relacionados con Git.
git blame -c <archivo>
git blame -L<inicio>,<final> <archivo
Donde inicio y final son los números de línea límites de la sección que se quiere revisar.