Cada vez que necesito hacer algo un poco más avanzado con Git — un shallow clone para ahorrar tiempo, un rebase interactivo para limpiar commits, o simplemente recordar cómo revertir un archivo sin perder cambios — acabo buscando en Google y copiando comandos que no termino de entender del todo. El problema no es que Git no tenga la funcionalidad, es que la documentación oficial está tan dispersa que terminas con 15 pestañas abiertas y todavía no sabes cuál es la flag correcta.
Este post nació de esa frustración. No es un tutorial de Git desde cero (para eso tengo guías más específicas), sino un ** diccionario consolidado** de todos los comandos y flags que uso en el día a día, organizados por contexto. Si necesitas hacer algo con Git, aquí encontrarás la respuesta rápida sin tener que bucear en la documentación oficial. Cada sección explica qué hace, cuándo usarlo y un ejemplo real para que no tengas que adivinar.
1. Clonado y Configuración (Obtener proyectos)
Clonar e iniciar repos
-
git clone:--depth <N>: Shallow clone. Solo descarga los últimos N commits (ideal para ahorrar espacio y tiempo).--shallow-since=<fecha>: Shallow clone con commits desde una fecha específica.--branch <nombre>(-b): Clona una rama específica.--single-branch: Descarga solo la rama indicada y no el resto de ramas del servidor.--filter=blob:none: Blobless clone. Baja el historial pero no el contenido de archivos viejos hasta que los pidas.--recurse-submodules: Clona el repo y todos sus submódulos automáticamente.--sparse: Habilita el checkout parcial (para ver solo ciertas carpetas en monorepos).--origin <nombre>(-o): Nombre del remote principal (por defectoorigin).--no-tags: No descarga ningún tag asociado.--reference=<repo>(--reference-if-able): Usa un repo local como referencia para ahorrar ancho de banda.--reference-if-ableno falla si falta el repo de referencia.--server-option=<opción>: Envía opciones al servidor (si lo soporta).--verbose(-v): Salida detallada.--progress: Muestra el progreso (forzado incluso si stdout no es terminal).--jobs=<N>(-j): Número de subprocesos para fetch paralelo.
-
git init:--bare: Crea un repositorio sin working directory (para servidores centrales).--template=<ruta>: Usa una plantilla de archivos iniciales (hooks, config).--separate-git-dir=<ruta>: Guarda la carpeta.giten una ubicación externa.-b <nombre>: Define el nombre de la rama inicial (ej.mainen lugar demaster).
Configuración global y local
git config:--global: Configura para todo el usuario (nombre, email, editor).--local(default): Configura solo para el proyecto actual.--list(-l): Muestra toda la configuración activa (combina global + local).--get <clave>: Consulta el valor de una clave concreta.--unset <clave>: Elimina una clave de la configuración.--edit(-e): Abre el archivo de configuración en el editor por defecto.--add <clave> <valor>: Añade un valor adicional a una clave multivalor.--show-origin: Muestra de qué archivo viene cada valor de configuración.
2. Gestión de Cambios (El día a día)
Estado del repositorio
-
git status:-s(--short): Formato compacto de dos columnas.XYdondeXes el stage yYel working tree (Mmodificado,Aañadido,Deliminado,?no rastreado,!ignorado,Rrenombrado).-b(--branch): Muestra la rama actual y su relación con el remoto (ahead/behind) incluso en modo--short.--porcelain[=<v1|v2>]: Salida estable y parseable por máquinas.v2es más detallada quev1. Ideal para scripts.-u [<modo>](--untracked-files): Controla cómo se muestran los archivos no rastreados. Modos:no(ocultarlos),normal(solo nombres),all(nombres + subdirectorios individuales).--ignored: Muestra los archivos ignorados (los que están en.gitignore). Por defecto no se muestran.-v(--verbose): Muestra el diff completo de los cambios sin staging además del estado.--column[=<opciones>]: Muestra los archivos en columnas en lugar de una lista vertical.--ahead-behind/--no-ahead-behind: Muestra u oculta el número de commits ahead/behind del remoto.--renames: Detecta renombrados aunque no se haya usadogit mv(experimental).--find-renames=<n>: Umbral de similitud para detectar renombrados (de 0 a 100).--porcelain: no muestra el?para archivos no rastreados si se combina con--untracked-files=no.-z: Termina las entradas con NUL en lugar de newline (seguro para nombres con espacios).
Ejemplos de uso:
# Resumen compacto de una línea por archivo git status -s # Solo archivos modificados (ocultar untracked e ignorados) git status -s -uno # Salida para scripts (fácil de parsear con awk/cut) git status --porcelain # Mostrar archivos ignorados (qué excluye .gitignore) git status --ignored -s # Estado completo con la rama ahead/behind git status -sb
Preparar y gestionar archivos
-
git add:-A(--all): Añade todos los cambios (nuevos, modificados y eliminados) de todo el repo.-u(--update): Añade solo archivos ya rastreados que hayan sido modificados o eliminados (no incluye archivos nuevos).-p(--patch): Revisa interactivamente cada cambio del archivo y te deja elegir qué partes incluir (imprescindible para commits limpios).-n(--dry-run): Simula qué se añadiría sin hacer nada realmente.-i(--interactive): Modo interactivo con subcomandos (status, update, revert, add untracked, patch, diff).--intent-to-add(-N): Registra el archivo como rastreado pero vacío, útil para ver diffs de archivos nuevos.--refresh: Actualiza el índice sin añadir nada nuevo; útil tras cambiar permisos.--ignore-removal: Ignora archivos eliminados del working tree (no los saca del index).--renormalize: Reaplica el tratamiento de finales de línea (core.autocrlf) a todos los archivos.--chmod=(+|-)(x|r): Cambia los permisos de ejecución directamente en el stage.--verbose(-v): Muestra el diff completo de lo que se añade al stage.
-
git rm:--cached: Elimina el archivo del control de versiones pero lo deja en el disco (deja de rastrearlo). Útil para archivos que deberían estar en.gitignore.-r: Elimina carpetas recursivamente.-n(--dry-run): Simula la eliminación.--ignore-unmatch: No da error si el archivo no existe.--sparse: Permite eliminar archivos dentro de áreas sparse-checkout.
-
git mv:-f(--force): Fuerza el movimiento aunque exista un archivo en el destino.-k: Salta archivos fuente que no existen (sin error).-n(--dry-run): Simula el movimiento.
-
git restore:--staged(-S): Saca archivos del stage (deshace ungit add).--worktree(-W): Restaura archivos en el working directory (descarta cambios locales).--source=<árbol>(-s): Restaura desde un commit, rama o tag específico.-p(--patch): Elige interactivamente qué partes restaurar.--ours/--theirs: En conflictos de merge, elige nuestra versión o la de ellos.
Commits y diferencias
-
git commit:-m "mensaje": Añade el mensaje sin abrir el editor de texto.-a(--all): Stage automático de archivos modificados/borrados (no incluye nuevos).--amend: Edita el último commit (cambia el mensaje o añade archivos olvidados).--no-verify: Salta los checks automáticos (hooks) de pre-commit.--reset-author: Cambia la autoría del commit corregido al usuario actual.--date="now": Actualiza la marca de tiempo del commit.--fixup=<commit>: Crea un commit marcado comofixup!que se emparejará automáticamente con<commit>al hacergit rebase -i --autosquash. Ideal para corregir un commit anterior sin ensuciar el historial.--squash=<commit>: Crea un commit marcado comosquash!que se fusionará con<commit>al hacergit rebase -i --autosquash. Útil para añadir cambios que deben integrarse en un commit anterior.--allow-empty: Permite crear un commit sin cambios (útil para triggers de CI o marcadores).--allow-empty-message: Crea un commit sin mensaje (no recomendado, pero existe).--template=<archivo>: Usa un archivo como plantilla del mensaje de commit.--cleanup=<modo>: Controla la limpieza del mensaje (strip,whitespace,verbatim,scissors,default).--status: Incluye el diff del stage en el editor al redactar el mensaje (por defecto).--no-status: Omite el diff del stage en el editor.--signoff(-s): AñadeSigned-off-byal final del mensaje (para DCO).--trailer <clave>=<valor>: Añade un trailer personalizado al mensaje (ej.--trailer "Fixes:#123").--gpg-sign[=<id>](-S): Firma el commit con GPG.
-
git diff:--stagedo--cached: Compara el stage contra el último commit.--stat: Resumen numérico de líneas cambiadas por archivo.--name-only: Muestra únicamente los nombres de los archivos afectados.-w: Ignora cambios de espacios en blanco al comparar.--check: Busca conflictos de espacios en blanco (tabs/espacios, trailing whitespace).--submodule: Compara el estado de los submódulos.--color-words: Compara palabra por palabra en lugar de línea por línea.--indent-heuristic: Activa el algoritmo experimental que mejora la legibilidad de los diffs, agrupando líneas por indentación en lugar de por orden secuencial.--histogram: Algoritmo de diff más preciso que el默认 (myers). Más lento pero genera parches más legibles.--patience: Algoritmo patience diff, mejor para detectar movimientos de código.--minimal: Gasta más tiempo generando el parche más pequeño posible.--function-context(-W): Muestra contexto completo de la función alrededor de cada cambio.--anchored=<texto>: Ancla el diff a una línea específica para evitar que se mueva en el resultado.--diff-algorithm=<algoritmo>: Elige algoritmo:myers,minimal,patience,histogram.--cached: alias de--staged.<rama>..<otra>: Compara dos ramas entre sí.<commit>...<commit>: Compara los cambios desde el ancestro común (merge base).--no-index: Compara dos archivos fuera de un repositorio Git (como diff normal pero con sintaxis Git).--ignore-cr-at-eol: Ignora retornos de carro (\r) al final de línea.--inter-hunk-context=<N>: Número de líneas de contexto extra entre hunks separados.--output=<archivo>: Guarda el diff en un archivo en lugar de stdout.
-
git difftool/git mergetool: Abren herramientas visuales para comparar y fusionar archivos.difftool: Abre un diff visual (ej. vimdiff, meld, Beyond Compare) en lugar del diff textual. Configurable congit config diff.tool <herramienta>.difftool --tool-help: Lista las herramientas de diff disponibles.mergetool: Abre una herramienta visual para resolver conflictos de merge.mergetool --tool-help: Lista las herramientas de merge disponibles.--tool=<herramienta>: Fuerza una herramienta específica (vimdiff,meld,kdiff3,Beyond Compare,p4merge).--prompt: Pide confirmación antes de abrir cada herramienta.-y(--no-prompt): Abre directamente sin preguntar.--gui: Usa la herramienta configurada endiff.guitool/merge.guitool.
-
git stash(Guardado temporal):push -m "nombre": Guarda cambios actuales en una pila temporal.push --keep-index: Guarda solo los cambios del working tree que no están en el stage (deja el stage intacto). Ideal para commits parciales.push --staged: Guarda solo los cambios que están en el stage. Útil para mover trabajo entre ramas sin arrastrar cambios sin staging.push -p(--patch): Elige interactivamente qué partes guardar.pop: Recupera los cambios y los elimina de la pila.apply: Aplica los cambios pero los mantiene en la pila.list: Muestra todo lo guardado en el “limbo”.-u(--include-untracked): Guarda también los archivos nuevos no rastreados.-a(--all): Guarda todos los archivos, incluidos los ignorados por.gitignore.drop [<stash>]: Elimina un stash específico de la pila.clear: Vacía toda la pila de stashes.branch <rama> [<stash>]: Crea una rama desde el commit del stash y aplica los cambios ahí.show [-p] [<stash>]: Muestra los cambios del stash (con-pmuestra el diff completo).create: Crea un stash como objeto (sin tocarlo). Devuelve el nombre del commit objeto. Para scripting.store: Guarda un stash creado concreateen la pila de stashes.
3. Sincronización y Remotos
Subir, bajar y fusionar
-
git push/git pull:-u(--set-upstream): Vincula tu rama local con la remota.-f(--force): Sobrescribe el historial remoto (peligroso).--force-with-lease: Versión segura de force; no sobrescribe si hay cambios ajenos.--rebase(en pull): Aplica tus cambios encima de los remotos (evita commits de merge).--all(push): Sube todas las ramas locales al remoto.--prune(push): Elimina del remoto las ramas que ya no existen en local.--tags(push): Sube también todas las etiquetas.--delete <rama>(push): Elimina una rama del remoto directamente.--mirror(push): Refleja exactamente el estado local en el remoto (borra lo que sobre).--dry-run(push): Muestra qué se subiría sin hacerlo realmente.--no-verify(push): Salta los hooks de pre-push.--atomic(push): Sube todos los refs de forma atómica. Si uno falla, ninguno se sube. Esencial para evitar estados inconsistentes al pushear múltiples ramas o tags.--signed[=<true|if-asked|never>](push): Firma el push con GPG. El servidor puede verificar que tú autorizas la publicación.--receive-pack=<ruta>(push): Especifica un receptor remoto alternativo.--force-with-lease=<ref>:<expect>(push): Versión aún más segura de--force-with-lease: especifica el valor exacto esperado del ref remoto.--negotiation-tip=<commit>(pull): Especifica qué commit usar como base de negociación.--ff-only(pull): Solo avance rápido; aborta si requiere merge.--squash(pull): Fusiona los cambios remotos como un único commit local.--autostash(pull): Stash automático antes del pull y pop después.--rebase=interactive(pull): Rebase interactivo al hacer pull (permite reordenar/squash antes de aplicar).--no-rebase(pull): Usa merge en lugar de rebase (sobrescribepull.rebase).--no-verify(pull): Salta los hooks de pre-merge/pre-rebase.
-
git remote:-v(--verbose): Muestra las URLs de conexión.prune <nombre>: Limpia ramas locales “fantasma” que ya no existen en el servidor.rename <viejo> <nuevo>: Renombra un remote.add <nombre> <url>: Añade un nuevo remote.remove <nombre>(rm): Elimina un remote.set-url <nombre> <url>: Cambia la URL de un remote existente.show <nombre>: Muestra información detallada del remote.get-url <nombre>: Muestra la URL de un remote (resuelveinsteadOf).set-head <nombre> <rama>: Establece la rama por defecto del remote.set-branches <nombre> <rama>...: Restringe las ramas que fetch obtiene del remote.
Cambio rápido de SSH a HTTPS —
git remote set-urlmodifica el archivo.git/config, reemplazando la URL que Git usa para comunicarse con el servidor remoto. No descarga nada ni modifica el historial; solo cambia la dirección de conexión.Por ejemplo, si tu
.git/configtiene:[remote "origin"] url = git@github.com:usuario/repo.gitAl ejecutar
git remote set-url origin https://github.com/usuario/repo.git, Git reemplaza esa línea por la nueva URL. A partir de ese momento,git pushygit pullusan HTTPS en lugar de SSH.# Ver la URL actual git remote -v # origin git@github.com:usuario/repo.git (fetch) # origin git@github.com:usuario/repo.git (push) # Cambiar a HTTPS git remote set-url origin https://github.com/usuario/repo.git # Verificar el cambio git remote -v # origin https://github.com/usuario/repo.git (fetch) # origin https://github.com/usuario/repo.git (push) # Ahora funciona sin clave SSH git pushPara volver a SSH:
git remote set-url origin git@github.com:usuario/repo.git
-
git fetch:--all: Obtiene datos de todos los remotos configurados.--prune: Elimina las referencias remotas locales que ya no existen en el servidor.--tags: Descarga también todas las etiquetas.--prune-tags: Elimina tags locales que ya no existen en el remoto.--depth <N>: Fetch limitado a N commits (shallow).--unshallow: Convierte un clon superficial a completo.--dry-run: Muestra qué se traería sin descargarlo.-p/--prune: Sinónimo de--prune.--refmap=<refspec>: Mapeo personalizado de refspec. Permite controlar exactamente cómo se mapean las ramas remotas a locales. Avanzado.--no-tags: No descarga tags asociados a los commits recibidos.--recurse-submodules[=<on-demand|yes|no>]: Fetch también en submódulos.--set-upstream: Configura el upstream para la rama actual tras el fetch.--stdin: Lee lista de refs a fetchear desde la entrada estándar (para scripting).
-
git merge:--no-ff: Fuerza un commit de merge aunque el avance sea rápido (Fast-Forward). Crea un nodo visible en el historial.--ff-only: Solo hace merge si puede ser Fast-Forward; si no, aborta.--squash: Fusiona los cambios de la rama entrante como un único commit en la rama actual (sin historial).--abort: Cancela el merge en curso y vuelve al estado anterior.--continue: Continúa el merge tras resolver conflictos.-m "<mensaje>": Mensaje personalizado para el commit de merge.--strategy=<estrategia>: Algoritmo de merge (recursive,ours,octopus,ort— el nuevo default).--strategy-option=<opción>: Opciones de la estrategia (ours,theirs,patience,diff-algorithm=histogram).--no-commit: Realiza el merge pero no crea el commit automático (para inspeccionar antes).--verify/--no-verify: Controla si se ejecutan los hooks pre-merge.--rerere-autoupdate: Si rerere está activado, reaplica resoluciones conocidas.--overwrite-ignore: Sobrescribe cambios locales en archivos ignorados (por defecto los preserva).
-
git submodule:add <url> [<ruta>]: Añade un submódulo al proyecto (clona y registra en.gitmodules).init: Inicializa los submódulos registrados (descarga la config de.gitmodules).update --init --recursive: Descarga/clona todos los submódulos (y sus submódulos anidados).status: Muestra el estado de cada submódulo (commit actual, cambios pendientes).summary: Muestra un resumen de los cambios en submódulos (parecido agit diffpero para submódulos).foreach "<comando>": Ejecuta un comando en cada submódulo (útil paragit pullmasivo).deinit [-f] <ruta>: Desregistra un submódulo (opcional: borra su working tree).sync: Sincroniza las URLs del submódulo con los cambios en.gitmodules.absorbgitdirs: Mueve los.gitde submódulos al superproyecto.set-branch -b <rama> <ruta>: Cambia la rama de seguimiento de un submódulo.set-url <ruta> <url>: Cambia la URL de un submódulo existente.--remote: Actualiza submódulos al último commit de su rama remota (en lugar del commit registrado).--force(-f): Fuerza la actualización incluso si hay cambios locales.--merge: Fusión con 3-bandas en lugar de checkout directo.--checkout: Checkout del commit registrado en el superproyecto (por defecto).--rebase: Rebase en lugar de merge al incorporar cambios.
4. Navegación e Historial
Explorar el historial
-
git log:--oneline: Resumen de un commit por línea.--graph: Dibuja el árbol visual de ramas.--all: Muestra el historial de todas las ramas.-p(--patch): Muestra el código exacto que cambió.-S "<texto>": Busca texto específico dentro del código histórico.-G "<regex>": Busca por expresión regular en el código (más potente que-S).-L :<función>:<archivo>: Rastrea la evolución de una función específica.--author="<nombre>": Filtra por autor.--committer="<nombre>": Filtra por committer (quien aplicó el commit).--no-merges: Oculta los commits de fusión.--first-parent: Solo sigue el primer padre en merges (ignora ramas secundarias). Útil para ver la línea principal limpia.--since=<fecha>/--after=<fecha>: Commits desde una fecha (ej."2024-01-01","2 weeks ago").--until=<fecha>/--before=<fecha>: Commits hasta una fecha.--max-count=<N>(-<N>): Limita a N commits.git log -5muestra los últimos 5.--skip=<N>: Salta los primeros N commits (para paginación).--grep=<patrón>: Filtra commits cuyo mensaje coincida con el patrón.--all-match: Todas las expresiones--grepdeben coincidir (AND lógico).--invert-grep: Muestra commits que no coinciden con--grep.--diff-filter=<ACDMRTUXB>: Filtra por tipo de cambio (A=Added, C=Copy, D=Deleted, M=Modified, R=Renamed).--follow: Sigue renombrados de un archivo a través del historial.--format="<formato>": Formato personalizado con placeholders (--pretty=format:y--formatson equivalentes). Placeholders más útiles:- Hash:
%H(completo),%h(abreviado). - Árbol:
%T(tree completo),%t(abreviado). - Autor:
%an(nombre),%ae(email),%aL(email local),%aN(nombre respetando .mailmap). - Committer:
%cn,%ce,%cN,%cE(análogos a autor). - Fechas autor:
%aI(ISO 8601 estricta),%aD(RFC2822),%ar(relativa: “2 weeks ago”),%at(timestamp UNIX),%ai(ISO 8601 estándar). - Fechas committer:
%cI,%cD,%cr,%ct,%ci(análogas). - Referencias:
%d(refs decoradas:(HEAD -> main, tag: v1.0)),%D(sin paréntesis),%S(nombre corto de la ref),%(describe)(descripción legible). - Mensaje:
%s(subject),%b(body),%B(subject + body),%f(subject sanitizado para filename). - Metadata:
%N(notas Git),%G?(estado GPG: G=bueno, B=malo, U=sin firmar, X=expirado),%GS(emisor GPG),%GK(clave GPG),%GF(fingerprint),%GP(policy). - Colores:
%C(<color>)(ej.%C(red)) y%C(auto)para colores automáticos por tipo de ref. - Padding:
%<(100)(alinear a izquierda 100 chars),%>(10)(derecha),%><(20)(centro),%<|(50)(alinear a columna 50). - Separadores:
%n(newline),%x00(byte hex),%%(literal%). - Trailers:
%(trailers:key=<clave>)(extrae un trailer específico del mensaje).
- Hash:
--pretty=<formato>: Atajo para--format. Valores predefinidos:oneline,short,medium,full,fuller,reference,email,raw,format:<string>,tformat:<string>.--simplify-by-decoration: Solo commits con tags/ramas (ideal para ver hitos).--branches[=<patrón>]: Muestra commits de ramas específicas (ej.--branches=feature/*).--tags[=<patrón>]: Muestra commits de tags específicos.--remotes[=<patrón>]: Muestra commits de remotos específicos.--ignore-missing: En combinación con--since/--until, no da error si no hay commits en el rango.--use-mailmap: Respeta.mailmappara normalizar nombres y emails.
-
git checkout/git switch:-b/-c: Crea una rama nueva y salta a ella.-C: Fuerza la creación/sobrescritura de la rama.-: Vuelve a la rama anterior.-d/--detach: Salta a un commit específico sin estar en ninguna rama.--discard-changes: Cambia de rama borrando cambios locales sucios.--orphan <rama>: Crea una rama huérfana sin historial (útil para reiniciar documentación, gh-pages, etc.).--guess: Si el nombre no es una rama local, busca una rama remota con el mismo nombre y la checkout automáticamente.--overlay: Modo overlay — no elimina archivos del working tree que no están en la rama destino.--conflict=<estilo>: Estilo de marcadores de conflicto:merge(por defecto) odiff3(muestra la base común además de ours/theirs).--ignore-other-worktrees: Ignora que otra instancia de Git tenga el checkout de la rama.--recurse-submodules: Actualiza submódulos al hacer checkout.--progress: Muestra el progreso (forzado).
-
git branch:-d <rama>: Elimina la rama (solo si está fusionada).-D <rama>: Fuerza la eliminación aunque no esté fusionada.-m <viejo> <nuevo>: Renombra la rama.-M <viejo> <nuevo>: Fuerza el renombrado aunque exista el nuevo nombre.-a(--all): Lista todas las ramas (locales + remotas).-r(--remotes): Lista solo las ramas remotas.--merged/--no-merged: Filtra ramas fusionadas o no fusionadas contra la actual.--sort=<clave>: Ordena el listado por-committerdate,authorname, etc.-v(--verbose): Muestra el último commit de cada rama.--show-current: Muestra el nombre de la rama actual.--set-upstream-to=<remote>/<rama>: Vincula la rama local al upstream.--edit-description: Edita la descripción de la rama (visible en interfaces web).
-
git tag:-a <nombre>(--annotated): Crea una etiqueta con metadatos (autor, fecha, mensaje).-m "<mensaje>": Mensaje para la etiqueta anotada.-s <nombre>(--sign): Firma la etiqueta con GPG.-d <nombre>(--delete): Elimina una etiqueta local.-l/--list: Lista etiquetas (acepta patrones comov1.*).--sort=<clave>: Ordena el listado (-v:refnamepara orden semántico de versiones).--contains <commit>: Muestra etiquetas que contienen un commit específico.--merged/--no-merged: Filtra etiquetas fusionadas o no.--points-at <objeto>: Lista etiquetas que apuntan a un commit específico.--format="%(refname) %(subject)": Formato personalizado de salida.
-
git show:--stat: Resumen de archivos cambiados y líneas añadidas/eliminadas.--name-only: Solo nombres de archivos afectados.--name-status: Nombres de archivos con estado (A/M/D).-s(--no-patch): Omite el diff, solo muestra metadatos del commit.--pretty=<formato>: Formato de salida (oneline,short,full,fuller,format:...).-q(--quiet): Suprime el mensaje del diff.--no-notes: No muestra notas asociadas al commit.--show-notes: Muestra las notas (por defecto si existen).- Sin argumentos: muestra el último commit (
HEAD).
-
git show-branch: Muestra la relación entre ramas visualmente. Ideal para ver cómo divergen las ramas sin un grafo completo.- Sin argumentos: compara las ramas locales entre sí.
--all: Incluye ramas remotas y tags.--more=<N>: Muestra N commits adicionales por rama.--list: Lista las ramas sin mostrar commits.--current: Muestra la rama actual resaltada con!.--reflog: Muestra las entradas del reflog en lugar de ramas.--merge-base: Muestra el commit base común entre las ramas.--topics: Muestra solo las ramas que no están fusionadas.--no-name: Omite los nombres en los commits.--sha1-name: Muestra nombres de commits como hashes abreviados.--date=<formato>: Formato de fecha.<rama> <otra>...: Muestra la comparación entre ramas específicas.
-
git shortlog:-s(--summary): Solo el número de commits por autor, sin listar los mensajes.-n(--numbered): Ordena por número de commits (descendente) en lugar de alfabéticamente.--since=<fecha>/--after=<fecha>: Commits desde una fecha.--until=<fecha>/--before=<fecha>: Commits hasta una fecha.--all: Cuenta commits de todas las ramas.--no-merges: Excluye commits de merge del recuento.-e(--email): Muestra el email junto al nombre del autor.--format: Formato personalizado (útil para changelogs).
-
git describe:--tags: Usa cualquier etiqueta (no solo las anotadas).--all: Usa cualquier referencia (ramas, tags, HEAD).--abbrev=<N>: Número de dígitos del hash abreviado (por defecto 7).--dirty[=<marca>]: Añade-dirty(o la marca que elijas) si el working tree está sucio.--match=<patrón>: Solo considera etiquetas que coincidan con el patrón glob.--always: Muestra el hash abreviado si no hay etiquetas disponibles.
-
git notes:add [-m "<texto>"] <commit>: Añade una nota de texto a un commit sin modificar el commit original.edit <commit>: Edita la nota existente de un commit.show <commit>: Muestra la nota de un commit.remove <commit>(-d): Elimina la nota de un commit.list: Lista todos los commits que tienen notas asociadas.prune: Elimina notas de commits que ya no existen en el repositorio.get-ref: Muestra la referencia actual de las notas (por defectorefs/notes/commits).--ref <refname>: Usa una referencia de notas personalizada (permite múltiples “categorías” de notas).--allow-empty: Permite añadir una nota vacía.--separator=<carácter>: Separador entre múltiples notas.
Para qué sirve:
git notesañade metadatos a un commit sin cambiar su hash. Útil para auditorías, revisiones, añadir contexto póstumo, o enlazar issues sin modificar el commit original. -
git rev-list: Lista objetos commit en orden cronológico inverso. El motor interno degit log, útil para scripting.--max-count=<N>: Limita a N commits.--skip=<N>: Salta N commits.--all: Todas las refs.--branches[=<patrón>],--tags[=<patrón>],--remotes[=<patrón>]: Filtra por tipo de ref.--author=<patrón>,--committer=<patrón>: Filtra por autor/committer.--grep=<patrón>: Filtra por mensaje.--since=<fecha>,--until=<fecha>: Rango de fechas.--first-parent: Solo el primer padre en merges.--merges/--no-merges: Filtra commits de merge.--count: Devuelve el número de commits en lugar de los hashes.--pretty=<formato>: Formato de salida (igual quegit log).--left-right: Marca commits como<o>según qué lado del rango...pertenecen.--graph: Dibuja el grafo (igual quegit log --graph).--objects: Lista también los objetos (árboles, blobs) asociados a cada commit.
-
git rev-parse: El comodín del parsing Git. Resuelve cualquier referencia a su hash SHA-1 subyacente.--verify <ref>: Verifica que una referencia es válida y devuelve su hash (sin mostrarlo si es inválido).--abbrev-ref <ref>: Devuelve el nombre corto de una referencia (ej.mainen lugar derefs/heads/main).--show-toplevel: Muestra la ruta absoluta de la raíz del repositorio.--git-dir: Muestra la ruta al directorio.git.--git-common-dir: Muestra la ruta al directorio común de Git (para worktrees).--absolute-git-dir: Ruta absoluta al.git.--is-inside-work-tree: Devuelvetruesi estás dentro del working tree (útil en scripts).--is-inside-git-dir: Devuelvetruesi estás dentro del directorio.git.--is-bare-repository: Devuelvetruesi el repo es bare.--short[=<N>]: Hash corto con N dígitos (por defecto 7).--symbolic-full-name <ref>: Nombre completo de la referencia (refs/heads/main).--parseopt: Modo de parsing de opciones para scripts avanzados.--sq-quote: Escapa el argumento para shell con comillas simples.--all: Lista todos los objetos reachables.- Sin flags: resuelve HEAD a su hash.
Ejemplos:
git rev-parse --show-toplevel # /home/user/proyecto git rev-parse --abbrev-ref HEAD # main git rev-parse --short HEAD # a1b2c3d git rev-parse --verify v1.0.0 # 1a2b3c4d5e6... -
git ls-files: Lista archivos del índice (stage) con varios filtros.--cached: Lista los archivos que están en el stage (por defecto).--modified(-m): Solo archivos modificados en el working tree.--deleted(-d): Solo archivos eliminados del working tree.--others(-o): Solo archivos no rastreados (untracked). El pan de cada día para scripts.--ignored(-i): Solo archivos ignorados por.gitignore.--stage(-s): Muestra el modo, hash, y número de stage (0=normal, 1=base, 2=ours, 3=theirs) de cada archivo. Esencial para entender conflictos de merge.--unmerged(-u): Solo archivos en conflicto (stage 1, 2, 3).--killed: Archivos eliminados por checkout de otra rama.--directory: Muestra directorios en lugar de expandirlos (para untracked).--no-empty-directory: Omite directorios vacíos.--exclude-standard: Aplica reglas de.gitignore(estándar).--exclude-from=<archivo>: Excluye usando patrones de un archivo adicional.--exclude-per-directory=<archivo>: Excluye usando archivos por directorio.--full-name: Muestra rutas desde la raíz del repo.-z: Termina con NUL en lugar de newline (seguro para scripting).--error-unmatch: Lanza error si algún patrón no coincide con archivos rastreados.--with-tree=<árbol>: Muestra el stage como si el working tree estuviera en el estado<árbol>.
Ejemplos:
git ls-files --others --exclude-standard # Untracked files (los que muestra git status) git ls-files --unmerged # Archivos en conflicto git ls-files -s | grep "^100644" # Archivos normales del repositorio git ls-files '*.py' # Todos los Python del repo -
git cat-file: Muestra el contenido de un objeto Git (blob, tree, commit, tag) dado su hash. El comando más básico para inspeccionar el almacenamiento interno.-p(--pretty): Muestra el contenido del objeto formateado según su tipo (el más usado).-t(--type): Muestra el tipo del objeto (blob,tree,commit,tag).-s(--size): Muestra el tamaño del objeto en bytes.--batch[=<formato>]: Lee hashes desde stdin y muestra su info. Ideal para procesar muchos objetos.--batch-check[=<formato>]: Como--batchpero solo muestra metadatos, no el contenido.--follow-symlinks: Sigue enlaces simbólicos dentro de trees.
Ejemplos:
git cat-file -p HEAD # Contenido del commit apuntado por HEAD git cat-file -t a1b2c3d # Tipo del objeto git cat-file --batch < objetos.txt # Info de múltiples objetos -
git hash-object: Calcula el hash SHA-1 de un archivo y opcionalmente lo guarda en el almacén de objetos. Base degit add.-w: Escribe el objeto en el almacén de objetos (.git/objects/).--stdin: Lee el contenido desde stdin en lugar de un archivo.--path=<ruta>: Usa la ruta para determinar el tipo de objeto (normalmente blob).--no-filters: No aplica filtros (core.autocrlf, smudge) al contenido.- Devuelve el hash SHA-1 del objeto.
Ejemplos:
git hash-object archivo.txt # Hash de archivo.txt echo "contenido" | git hash-object --stdin -w # Guarda y muestra hash -
git ls-tree: Lista el contenido de un tree object (directorio). Comolspero para el árbol de Git.-r(--recursive): Lista recursivamente subdirectorios.-t: Muestra también los objetos tree intermedios (no solo blobs).-l(--long): Muestra el tamaño del objeto.--name-only: Solo nombres de archivo, sin modo ni hash.--full-name: Rutas completas desde la raíz del tree.--abbrev[=<N>]: Hash abreviado.<tree-ish>: El tree a listar (commit, tag, tree). Por defecto HEAD.
Ejemplo:
git ls-tree -r HEAD --name-only # Todos los archivos del repo -
git for-each-ref: Itera sobre referencias (ramas, tags, stashes) con formato de salida totalmente personalizable. El comando definitivo para scripting avanzado.--format=<formato>: Salida personalizada. Placeholders:%(refname),%(objectname),%(objecttype),%(tree),%(parent),%(numparent),%(objectsize),%(deltabase),%(authorname),%(authoremail),%(authordate),%(committerdate),%(committeremail),%(subject),%(body),%(contents),%(upstream),%(HEAD),%(color:<color>),%(align:<ancho>)...%(end).--sort=<clave>: Ordena por campo (-creatordatepara descendente,refnamepara alfabético,version:refnamepara semver).--count=<N>: Limita a N referencias.--merged[=<commit>]: Solo refs fusionadas en<commit>(o HEAD si no se especifica).--no-merged[=<commit>]: Solo refs NO fusionadas.--contains[=<commit>]: Solo refs que contienen<commit>.--no-contains[=<commit>]: Solo refs que NO contienen<commit>.--ignore-case: Ordenación/agrupación sin distinción de mayúsculas.--shell,--perl,--python,--tcl: Formatea la salida como array en el lenguaje indicado (seguro para scripting).--points-at=<objeto>: Solo refs que apuntan a un objeto específico.
Ejemplos:
# Listar ramas con su último commit git for-each-ref --sort=-committerdate --format='%(refname:short) | %(authorname) | %(committerdate:relative)' refs/heads/ # Top 10 autores por número de commits git shortlog -s -n | head -10 # Tag más reciente git for-each-ref --sort=-creatordate --count=1 --format='%(refname:short)' refs/tags/ -
git show-ref: Lista referencias (ramas, tags, etc.) con sus hashes. Comando de referencia para scripting.--head: Incluye HEAD en la salida.--heads: Solo ramas (refs/heads/).--tags: Solo tags (refs/tags/).-d(--dereference): Muestra también el objeto apuntado por tags anotados (con^{}).--verify <ref>: Verifica que una referencia existe y muestra su hash. Código de salida 0 si existe.--abbrev[=<N>]: Hash abreviado.--quiet: No muestra salida; solo código de salida.--exclude-existing[=<patrón>]: Lee refs desde stdin y excluye las que existen.
-
git symbolic-ref: Lee y modifica referencias simbólicas (como HEAD que apunta arefs/heads/main).<nombre>: Lee el valor de la referencia simbólica.--delete <nombre>: Elimina la referencia simbólica.--short: Muestra el nombre corto (ej.mainen lugar derefs/heads/main).-q(--quiet): Suprime mensajes de error.--recurse: Si la referencia apunta a otra symref, la sigue hasta el destino final.
Búsqueda en el historial
git grep:-n(--line-number): Muestra el número de línea de cada coincidencia.-i(--ignore-case): Búsqueda insensible a mayúsculas/minúsculas.-w(--word-regexp): Coincidencia solo de palabras completas.-c(--count): Muestra el número de coincidencias por archivo.-l(--files-with-matches): Solo los nombres de archivo que contienen el patrón.-L(--files-without-match): Archivos que no contienen el patrón.-p(--show-function): Muestra el nombre de la función que contiene la coincidencia.--and/--or/--not: Operadores lógicos entre patrones.--cached: Busca en el stage (índice).--no-index: Busca fuera de un repositorio Git (como grep normal pero con sintaxis Git).--break(-B): Muestra una línea separadora entre resultados de distintos archivos.--heading: Muestra el nombre del archivo como cabecera antes de cada grupo de resultados.--color[=<when>]: Colorea las coincidencias (always,never,auto).--column: Muestra el número de columna de la coincidencia (no solo la línea).
5. Reescritura y Recuperación (Avanzado)
Reorganizar commits
git rebase:-i(--interactive): Interfaz para unir, renombrar, reordenar o borrar commits.--continue/--skip: Continúa tras resolver conflictos o salta un commit problemático.--abort: Cancela el rebase y vuelve al estado anterior.--onto <base> <desde> <hasta>: Rebase avanzado que cambia la base de un rango de commits a otra rama.--rebase-merges: Preserva los merges creados manualmente durante el rebase.--autosquash: Busca commits confixup!/squash!en el mensaje y los empareja automáticamente.--committer-date-is-author-date: Conserva la fecha original del autor.-X theirs/-X ours: En conflictos, prefiere siempre la versión de la rama que rebasas o la tuya.--update-refs: Actualiza las ramas que apuntan a commits rebasados.--empty=<drop|keep|ask>: Controla cómo manejar commits que quedan vacíos tras el rebase.droplos elimina,keeplos conserva,askpregunta (default:drop).--no-ff: Fuerza la recreación de todos los commits aunque el rebase sea fast-forward. Útil para garantizar que todos los commits tengan nuevos hashes.--rerere-autoupdate: Si tienes rerere activado, resuelve conflictos conocidos automáticamente.--reschedule-failed-exec: Vuelve a programar pasosexecfallidos al final del rebase en lugar de abortar.
Cambiar la fecha de un commit antiguo
Método 1: Para el ÚLTIMO commit (rápido):
# Cambiar solo la fecha del autor
git commit --amend --date="2026-08-01T10:30:00"
# Cambiar fecha del autor Y del committer
GIT_AUTHOR_DATE="2026-08-01T10:30:00" GIT_COMMITTER_DATE="2026-08-01T10:30:00" git commit --amend --no-edit
Método 2: Para commits ANTERIORES (rebase interactivo):
# 1. Abre rebase interactivo desde el commit ANTERIOR al que quieres cambiar
git rebase -i HEAD~3 # Para los últimos 3 commits
# 2. En el editor, cambia "pick" por "edit" en el commit que quieres modificar
# pick abc1234 commit viejo
# pick def5678 otro commit
# 3. Guarda y sal del editor. Git se pausa en ese commit.
# 4. Cambia la fecha del autor
git commit --amend --date="2026-08-01T10:30:00" --no-edit
# 5. Cambia también la fecha del committer (opcional pero recomendado)
GIT_COMMITTER_DATE="2026-08-01T10:30:00" git commit --amend --no-edit
# 6. Continúa el rebase
git rebase --continue
Método 3: Para MÚLTIPLES commits de golpe:
# Script que cambia la fecha de todos los commits de un rango
git rebase -i HEAD~5 --exec '
GIT_AUTHOR_DATE="2026-08-01T10:00:00" \
GIT_COMMITTER_DATE="2026-08-01T10:00:00" \
git commit --amend --no-edit --date="2026-08-01T10:00:00"
'
Método 4: Usar filter-repo (para TODO el historial):
# Cambiar TODAS las fechas de autor de un autor específico
git filter-repo --mailmap '
Antiguo Nombre <antiguo@email.com> => Nuevo Nombre <nuevo@email.com>
'
Formatos de fecha aceptados:
# ISO 8601
git commit --amend --date="2026-08-01T10:30:00+02:00"
git commit --amend --date="2026-08-01T10:30:00"
# Relativo
git commit --amend --date="2 days ago"
git commit --amend --date="yesterday"
# RFC 2822
git commit --amend --date="Fri, 1 Aug 2026 10:30:00 +0200"
Verificar que la fecha cambió:
git log --format='%h %ai %s' -5 # Formato ISO
git log --format='%h %ar %s' -5 # Formato relativo
git log --format='%h %ad %s' --date=short -5 # Formato corto
-
git range-diff:--creation-factor=<N>: Ajusta la sensibilidad para detectar commits nuevos (default 60).--no-dual-color: Desactiva el coloreado dual (solo rojo/verde normal).--notes: Incluye notas en la comparación.- Uso:
git range-diff <rama1>...<rama2>ogit range-diff <a1>..<a2> <b1>..<b2>.
-
git format-patch:-1,-2…: Número de commits a exportar (desde HEAD hacia atrás).--stdout: Imprime en stdout en lugar de archivos.--output-directory=<dir>: Carpeta de destino para los parches.--signoff: AñadeSigned-off-byal final del mensaje.--cover-letter: Genera un parche0000-cover-letter.patchcon resumen.--thread: Añade headers de threading para hilos de email.
-
git am:--continue: Continúa tras resolver conflictos.--skip: Salta el parche actual y continúa con el siguiente.--abort: Cancela la aplicación de parches.--signoff: AñadeSigned-off-by(comogit format-patch --signoff).-3(--3way): Intenta fusión a 3 bandas si el parche falla.--reject: Guarda las partes fallidas como.rejen lugar de abortar.
Deshacer y navegar en el tiempo
git reset:--soft: Mueve HEAD pero mantiene cambios en el Stage.--mixed(Default): Mueve HEAD y saca archivos del Stage al Directorio.--hard: Borra todo. Vuelve al estado exacto del commit indicado.-p: Reset interactivo para elegir partes específicas del archivo.--keep: Mantiene los archivos con cambios sin seguimiento; aborta si hay conflicto.--merge: Resetea solo archivos con conflictos o cambios en stage; aborta si hay cambios en working tree sin stage.--recurse-submodules: Resetea también los submódulos al estado del commit destino.
Recuperación
-
git reflog: El historial de movimientos local para recuperar ramas o commits borrados. Cada vez que HEAD se mueve (commit, reset, checkout, rebase, merge), reflog guarda una entrada.show [<ref>]: Muestra el reflog de una referencia específica (por defecto HEAD).-n <N>(--max-count): Limita a N entradas.--all: Muestra el reflog de todas las referencias.--date=<formato>: Formato de fecha (relative,iso,rfc2822,short,raw).--pretty=<formato>: Formato de salida personalizado.
Cada entrada del reflog muestra:
a1b2c3d HEAD@{0}: commit: mi último commit e4f5g6h HEAD@{1}: reset: moving to HEAD~3 i7j8k9l HEAD@{2}: merge feature/branch: MergeCasos de uso prácticos:
# Recuperar un commit borrado con reset --hard git reflog # Busca el hash del commit perdido git checkout a1b2c3d # Accede al commit git branch rama-recuperada # Crea una rama desde ahí # Recuperar una rama borrada git reflog # Busca la última entrada de la rama git checkout -b rama-recuperada HEAD@{5} # Recrea la rama # Deshacer un rebase malo git reflog # Antes del rebase aparece como HEAD@{n} git reset --hard HEAD@{5} # Vuelve al estado anterior # Ver qué pasó hace 2 horas git reflog --date=relative # Muestra fechas relativasDiferencia con
git log:git logmuestra commits (públicos, del repositorio)git reflogmuestra movimientos de HEAD (privados, solo locales)- reflog se auto-limpia después de 90 días (por defecto)
- reflog no se sube al remoto (es solo local)
-
git cherry-pick <hash>:-n(--no-commit): Aplica los cambios al stage sin crear commit (útil para cherry-pick múltiple).-x: Añade una línea al mensaje indicando de dónde se cherry-pickeó.--signoff: AñadeSigned-off-by.-e(--edit): Edita el mensaje del commit antes de confirmar.
-
git cherry: Encuentra commits que están en una rama pero no en otra. Útil para saber qué falta por integrar.-v(--verbose): Muestra también el mensaje del commit.--abbrev=<N>: Hash abreviado.--left-only/--right-only: Muestra solo commits del lado izquierdo/derecho del rango.<rama> <upstream>: Compara<rama>contra<upstream>.- Sin argumentos: compara la rama actual contra
HEADde upstream.
-
git rerere: Reuse Recorded Resolution — recuerda cómo resolviste conflictos anteriores y los reaplica automáticamente.status: Muestra el estado actual de las resoluciones grabadas.remaining: Muestra los conflictos que rerere no pudo resolver automáticamente.diff: Muestra el diff de las resoluciones grabadas.clear: Borra las resoluciones grabadas.gc: Limpia resoluciones antiguas.- Se activa con
git config --global rerere.enabled true.
-
git replace: Reemplaza un objeto Git por otro sin modificar el historial. Útil para arreglar commits antiguos sin rebase.<objeto> <reemplazo>: Reemplaza<objeto>por<reemplazo>en el grafo.--delete <objeto>: Elimina un reemplazo existente.--list [<patrón>]: Lista los reemplazos activos.--graft <commit> [<padre>...]: Reemplaza los padres de un commit (útil para unir historiales disjuntos).--convert-graft-file: Convierte el archivo.git/info/graftsal formatorefs/replace/.--edit <objeto>: Edita el contenido del objeto reemplazado.--raw: Muestra los reemplazos en bruto.
6. Limpieza y Especialista
-
git clean:-n: Dry-run. Simulación de borrado.-f: Fuerza la eliminación de archivos no rastreados.-fdx: Borra archivos, directorios e ignorados por.gitignore.-x: Borra archivos no rastreados e ignorados (sin-dde directorios). Combinable:-xdf=-fdx.-X: Borra solo los archivos ignorados por.gitignore.-d: Elimina también directorios no rastreados.-i(--interactive): Modo interactivo para elegir qué borrar.-q(--quiet): Solo muestra errores.-e <patrón>(--exclude): Excluye patrones aunque estén en.gitignore.
-
git verify-commit: Verifica la firma GPG de uno o más commits.--raw: Muestra los detalles en bruto de la verificación GPG.--verbose: Muestra información detallada de la firma.<commit>...: Uno o más commits a verificar.
-
git verify-tag: Verifica la firma GPG de uno o más tags.--raw: Detalles en bruto de la verificación.--verbose: Información detallada.<tag>...: Uno o más tags a verificar.
-
git check-ignore: Depura.gitignore: comprueba si un archivo está siendo ignorado y por qué regla.-v(--verbose): Muestra la regla exacta de.gitignoreque hace que el archivo sea ignorado (archivo, línea, patrón).-n(--non-matching): Muestra también los archivos que NO coinciden con ninguna regla.-q(--quiet): No muestra salida; solo código de salida (0 = ignorado, 1 = no ignorado). Ideal para scripts.--stdin: Lee lista de rutas desde la entrada estándar.--no-index: Ignora los archivos del índice; busca solo en el working tree.- Sin argumentos o con rutas: comprueba las rutas indicadas.
Ejemplos:
git check-ignore .env # ¿Está .env ignorado? git check-ignore -v node_modules/ # ¿Qué regla de .gitignore lo ignora? echo ".env\n*.log" | git check-ignore --stdin -v -
git stripspace: Limpia espacios en blanco de un texto (desde stdin o archivo).-s(--strip-comments): Elimina también las líneas de comentario.-c(--comment-lines): Convierte las líneas no vacías en comentarios (prefijo#). Útil para limpiar mensajes de commit.< archivo: Lee desde un archivo (o stdin).- Sin flags: elimina trailing whitespace, líneas vacías duplicadas, y el último newline si sobra.
Ejemplo:
git stripspace -s < mensaje_sucio.txt > mensaje_limpio.txt -
git interpret-trailers: Añade, modifica o elimina trailers (metadatos clave=valor) al final de un mensaje de commit.--trailer <clave>=<valor>: Añade un trailer (ej.--trailer "Fixes:#123").--where <posición>: Dónde colocar el trailer (before,after,end,start).--if-exists <acción>: Qué hacer si el trailer ya existe (add,replace,doNothing,fail).--if-missing <acción>: Qué hacer si no existe (add,doNothing).--only-trailers: Muestra solo los trailers del mensaje, sin el cuerpo.--only-input: No aplica reglas de configuración; solo procesa los trailers pasados.--unfold: Despliega trailers multilínea en una sola línea.--parse: Parsea los trailers y los muestra en formato máquina.--no-divider: No usa separador entre clave y valor (por defecto es:).
Trailers comunes:
Fixes,Closes,Co-authored-by,Signed-off-by,Reviewed-by,Reported-by,Mentored-by.Ejemplos:
# Añadir un trailer a un mensaje existente git interpret-trailers --trailer "Fixes:#42" < mensaje.txt # En combinación con git commit git commit -m "fix: arreglo crítico" --trailer "Co-authored-by: Ana <ana@example.com>" -
git check-attr: Comprueba los atributos Git (gitattributes) de uno o más archivos.--all: Muestra todos los atributos definidos para los archivos.--cached: Comprueba solo en el índice, no en el working tree.--stdin: Lee rutas desde stdin.<atributo> <archivo>: Comprueba un atributo específico para un archivo.- Sin flags con archivo: comprueba atributos comunes como
text,diff,merge.
-
git check-mailmap: Normaliza nombres y emails según.mailmap. Útil para scripts que procesan contribuciones.<persona>: Muestra el nombre/email normalizado para una persona.--stdin: Lee personas desde stdin.--mailmap-file=<archivo>: Usa un archivo mailmap específico.
-
git column: Formatea líneas de entrada en columnas. Un formateador de salida para scripting.--mode=<modo>:column(llenar por columnas),row(llenar por filas),dense(sin separación).--width=<N>: Ancho total de la salida (por defecto el terminal).--indent=<N>: Sangría izquierda.--padding=<N>: Espaciado entre columnas.--nl/--newline: Separador de nuevas líneas.--keep-empty: Conserva líneas vacías (por defecto las omite).- Lee de stdin, escribe a stdout.
-
git blame:-L 10,20: Analiza solo esas líneas.-w: Ignora espacios en blanco.-M/-C: Detecta si el código fue movido o copiado de otros archivos.--since=<fecha>: Solo líneas modificadas desde una fecha específica.--date=<formato>: Formato de las fechas mostradas (relative,local,iso,rfc2822,short,raw).--show-email: Muestra el email del autor en lugar del nombre.--line-porcelain: Formato detallado por línea, ideal para scripting.
-
git bisect:start: Inicia la búsqueda binaria.bad/good: Marca el commit actual como malo o bueno (git bisect badogit bisect good <commit>).skip: Salta un commit que no se puede probar.reset: Sale del modo bisect y vuelve al commit original.run <script>: Automatiza la búsqueda ejecutando un script que devuelva 0 (good) o 1 (bad).log: Muestra el progreso del bisect (se puede reanudar después).replay <archivo>: Reanuda un bisect desde un log guardado.--no-checkout: No hace checkout de los commits (útil para probar archivos sin tocar el working tree).--term-old=<término>/--term-new=<término>: Personaliza los términos (ej.old/newen lugar debad/good).
-
git revert:-n(--no-commit): Revierte los cambios pero no crea commit (los deja en stage para revisar).-m 1(--mainline): Para revertear un merge: indica qué padre conservar (1 = la rama actual).--no-edit: No abre el editor; usa el mensaje por defecto.--edit(-e): Abre el editor para modificar el mensaje por defecto.--signoff: AñadeSigned-off-by.--strategy=<estrategia>: Estrategia de merge para la reversión.--strategy-option=<opción>: Opciones de estrategia (como en merge).--cleanup=<modo>: Limpieza del mensaje (strip,whitespace,verbatim).--rerere-autoupdate: Si rerere está activado, reaplica resoluciones conocidas.--no-rerere-autoupdate: No reaplica resoluciones conocidas.
7. Mantenimiento y Exportación
-
git archive:--format=<formato>:zip,tar,tgz,tar.gz.-o <archivo>(--output): Archivo de salida.--prefix=<prefijo>/: Añade una carpeta raíz al contenido exportado.HEAD,<tag>,<rama>: Lo que se exporta.--remote=<url>: Exporta desde un repositorio remoto.--worktree-attributes: Respeta atributos exportados por.gitattributes(comoexport-ignore).--add-file=<ruta>: Añade un archivo extra al archive (no incluido en el repo).
-
git worktree:add <ruta> [<rama>]: Crea un nuevo working tree con una rama.list: Lista todos los working trees activos.remove <ruta>: Elimina un working tree (solo si está limpio).lock/unlock <ruta>: Bloquea/desbloquea un working tree para evitar que lo borren.move <ruta> <nueva-ruta>: Mueve un working tree a otra ubicación.prune: Limpia referencias a working trees eliminados.--detach: Crea el worktree en modo detached HEAD.--force: Fuerza la operación aunque haya cambios sin commitear.
-
git gc:--prune=<fecha>: Elimina objetos sueltos más antiguos que la fecha (ej.now,2.weeks.ago).--aggressive: Optimización intensiva (más lenta, mejor compresión).--auto: Ejecuta GC solo si es necesario (por umbral de objetos sueltos/packs).--quiet: Modo silencioso (sin salida).--force: Fuerza la ejecución incluso sigc.autoestá desactivado.--keep-largest-pack: Omite el pack más grande al reempaquetar (ahorra tiempo en repos grandes).
-
git prune: Elimina objetos sueltos no reachables (que no están en ningún commit, tag o ref).-n(--dry-run): Simula la poda sin borrar nada.-v(--verbose): Muestra los objetos eliminados.--progress: Muestra el progreso de la operación.--expire=<fecha>: Solo poda objetos más antiguos que la fecha (por defecto 2 semanas).- Normalmente no necesitas ejecutarlo manualmente;
git gc --prunelo hace automáticamente.
-
git fsck:--full: Escanea todos los objetos del repositorio.--strict: Comprobación más exhaustiva (modo estricto).--lost-found: Restaura objetos huérfanos a.git/lost-found/.--unreachable: Muestra objetos sin referencia.--dangling: Muestra commits/árboles huérfanos (normalmente inofensivos).
-
git repack:-a(--all): Reempaqueta todos los objetos en un solo pack.-d: Elimina los packs viejos tras crear el nuevo.--window=<N>: Ventana de deduplicación (más alto = mejor compresión, más lento).--depth=<N>: Profundidad máxima de delta (default 50).-F(--no-reuse-delta): Recalcula deltas desde cero (más lento pero comprime mejor).
-
git bundle:create <archivo> <revisiones>: Crea un bundle con un rango de commits.verify <archivo>: Verifica que el bundle sea válido.list-heads <archivo>: Lista las referencias disponibles en el bundle.unbundle <archivo>: Restaura el bundle en el repositorio.--version=<version>: Versión del formato del bundle (v2 o v3).
-
git count-objects:-v(--verbose): Estadísticas detalladas: número de objetos, packs, espacio usado, etc.--human-readable: Muestra tamaños en formato legible (KB, MB).
-
git maintenance: Mantenimiento automático del repositorio en segundo plano (Git 2.30+). Ejecuta tareas de optimización sin intervención manual.start: Inicia el mantenimiento automático en segundo plano (configura cron o systemd timer).stop: Detiene el mantenimiento automático.register: Registra el repositorio actual para mantenimiento automático.unregister: Elimina el repositorio de la lista de mantenimiento automático.run --task=<tarea>: Ejecuta una tarea específica inmediatamente. Tareas disponibles:gc: Recolecta objetos sueltos (git gc --auto).commit-graph: Actualiza el grafo de commits para acelerargit log.prefetch: Hace fetch de todos los remotos sin integrar cambios.loose-objects: Empaqueta objetos sueltos en packs.incremental-repack: Reempaqueta objetos de forma incremental (no destructivo).pack-refs: Comprime referencias sueltas enpacked-refs.
--schedule=<frecuencia>: Pararun --task:hourly,daily,weekly.--quiet: Modo silencioso.
Diferencia con
git gc:git maintenancees la evolución moderna. No tienes que acordarte de ejecutarlo; corre en background y hace trabajo incremental sin bloquear tu terminal. -
git sparse-checkout: Checkout parcial. Descarga solo las carpetas que necesitas de un monorepo.init: Inicializa sparse-checkout en modo cone (recomendado).set <patrón> [<patrón>...]: Define los patrones de inclusion. Con--cone, limita a niveles de directorio (mucho más rápido).add <patrón> [<patrón>...]: Añade patrones a los existentes.reapply: Reaplica las reglas de sparse-checkout (útil tras un merge/fetch).disable: Desactiva sparse-checkout y descarga el repositorio completo.--cone: Modo cone (por defecto). Solo permite patrones de directorio raíz. Más eficiente.--no-cone: Modo completo. Permite patrones glob complejos comosrc/**/*.ts. Más lento.--sparse-index: Habilita el índice sparse (Git 2.32+). Reduce la memoria necesaria para operaciones con el índice.--stdin: Lee patrones de inclusion desde stdin.check-rules: Comprueba si un conjunto de rutas serían incluidas con las reglas actuales.
Ejemplos:
git sparse-checkout init --cone # Iniciar modo cone git sparse-checkout set src/web app/config # Solo estas dos carpetas git sparse-checkout add docs # Añadir docs a lo que ya tienes git sparse-checkout disable # Volver a tener todo -
git help: Muestra ayuda de cualquier comando Git.-a(--all): Lista todos los comandos disponibles (incluyendo los menos conocidos). Imprescindible para descubrir funcionalidades.-g(--guides): Lista las guías de Git (conceptos:gitcore-tutorial,giteveryday,gitworkflows).-c(--config): Lista todas las claves de configuración disponibles.<comando>: Muestra la página man del comando (ej.git help log).--web [<comando>]: Abre la documentación en el navegador.--man [<comando>]: Muestra la página man (por defecto).--info [<comando>]: Muestra la documentación en formato info.
7.5. filter-branch y filter-repo (Reescritura masiva)
git filter-branch ⚠️ DEPRECADO
⚠️ ADVERTENCIA:
git filter-branchestá deprecado desde Git 2.24. Usagit filter-repoen su lugar. Es más rápido, más seguro y más fácil de usar.
git filter-branch reescribe el historial de forma masiva. Es peligroso porque改变了 hashes de commits y puede romper colaboradores.
Uso básico:
# Eliminar un archivo de TODO el historial
git filter-branch --tree-filter 'rm -f secrets.env' HEAD
# Eliminar un archivo del índice (dejar de rastrearlo)
git filter-branch --index-filter 'git rm --cached --ignore-unmatch secrets.env' HEAD
# Cambiar el email en todos los commits
git filter-branch --env-filter '
if [ "$GIT_AUTHOR_EMAIL" = "antiguo@email.com" ]; then
export GIT_AUTHOR_EMAIL="nuevo@email.com"
export GIT_COMMITTER_EMAIL="nuego@email.com"
fi
' --tag-name-filter cat -- --all
# Eliminar commits vacíos
git filter-branch --force --index-filter \
'git rm --cached --ignore-unmatch $(git diff --name-only --diff-filter=A HEAD)' \
--prune-empty --tag-name-filter cat -- --all
Flags importantes:
| Flag | Qué hace |
|---|---|
--tree-filter 'comando' | Ejecuta el comando en cada commit y guarda el resultado |
--index-filter 'comando' | Modifica el índice (más rápido que —tree-filter) |
--env-filter 'script' | Modifica variables de entorno (autor, email, fecha) |
--subdirectory-filter <dir> | Mueve un subdirectorio a la raíz |
--tag-name-filter cat | Preserva tags (los re-apunta a nuevos commits) |
--prune-empty | Elimina commits que quedaron vacíos tras el filtro |
--force | Fuerza la ejecución |
--all | Aplica a todas las ramas y tags |
git filter-repo ✅ RECOMENDADO
La alternativa moderna y recomendada. Más rápida, más segura, más fácil.
# Instalar (pip)
pip install filter-repo
# Eliminar un archivo de todo el historial
git filter-repo --path secrets.env --invert-paths
# Eliminar una carpeta entera
git filter-repo --path node_modules/ --invert-paths
# Cambiar email en todos los commits
git filter-repo --mailmap '
Antiguo Nombre <antiguo@email.com> => Nuevo Nombre <nuevo@email.com>
'
# Mantener solo un subdirectorio (útil para extraer un monorepo)
git filter-repo --subdirectory-filter src/mi-app
# Eliminar archivos grandes (>10MB)
git filter-repo --strip-blobs-bigger-than 10M
# Poner un subdirectorio en la raíz
git filter-repo --path src/ --path-rename src/:
Diferencias con filter-branch:
| Aspecto | filter-branch | filter-repo |
|---|---|---|
| Velocidad | Lento (commit por commit) | Muy rápido (batch processing) |
| Seguridad | Puede romper el repo | Verifica integridad siempre |
| Filosofía | Modifica el historial existente | Crea un historial nuevo limpio |
| Instalación | Viene con Git | Se instala aparte (pip) |
Cuándo usar reescritura de historial
| Caso | Herramienta | Ejemplo |
|---|---|---|
Subir .env por error | filter-repo | git filter-repo --path .env --invert-paths |
| Archivo muy grande | filter-repo | git filter-repo --strip-blobs-bigger-than 10M |
| Cambiar email antiguo | filter-repo | git filter-repo --mailmap |
| Extraer subdirectorio | filter-repo | git filter-repo --subdirectory-filter src/ |
| Arreglar autor en pocos commits | rebase -i | Más fácil y seguro |
8. Hooks (Automatización de Git)
Los hooks son scripts que se ejecutan automáticamente antes o después de ciertas acciones de Git. Viven en .git/hooks/ y se ejecutan en el lado local (el servidor también tiene hooks, pero son diferentes).
Hooks más importantes
| Hook | Cuándo se ejecuta | Para qué sirve |
|---|---|---|
pre-commit | Antes de crear un commit | Linting, formateo, tests rápidos |
prepare-commit-msg | Después de abrir el editor, antes del commit | Modificar el mensaje automáticamente |
commit-msg | Después de escribir el mensaje | Validar formato (conventional commits) |
post-commit | Después del commit | Notificaciones, logs |
pre-push | Antes de push | Tests completos, verificar que no se sube main |
pre-rebase | Antes de rebase | Evitar rebases peligrosos |
post-checkout | Después de checkout/switch | Instalar dependencias, limpiar cache |
post-merge | Después de merge | Instalar dependencias, regenerar archivos |
pre-auto-gc | Antes de git gc —auto | Verificar espacio en disco |
Cómo funcionan
# Los hooks están en .git/hooks/
ls .git/hooks/
# Cada hook es un script ejecutable
cat .git/hooks/pre-commit
#!/bin/sh
# Tu script aquí
exit 0 # 0 = permitir la operación, 1 = cancelarla
Crear un hook
# 1. Crea el script
cat > .git/hooks/pre-commit << 'EOF'
#!/bin/sh
echo "Ejecutando linting antes del commit..."
npm run lint
if [ $? -ne 0 ]; then
echo "❌ Linting falló. Commit cancelado."
exit 1
fi
echo "✅ Linting OK"
EOF
# 2. Hazlo ejecutable (IMPORTANTE)
chmod +x .git/hooks/pre-commit
Hook de ejemplo: pre-commit con lint-staged
#!/bin/sh
# .git/hooks/pre-commit
# Ejecuta lint solo en los archivos que se van a commitear
staged_files=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(js|ts|jsx|tsx)$')
if [ -n "$staged_files" ]; then
echo "Linting archivos:"
echo "$staged_files"
echo "$staged_files" | xargs npx eslint --fix
if [ $? -ne 0 ]; then
echo "❌ Linting falló"
exit 1
fi
fi
exit 0
Hook de ejemplo: commit-msg para conventional commits
#!/bin/sh
# .git/hooks/commit-msg
# Valida que el mensaje siga el formato conventional commits
commit_msg=$(cat "$1")
pattern="^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\(.+\))?: .{1,72}"
if ! echo "$commit_msg" | grep -qE "$pattern"; then
echo "❌ Mensaje de commit no válido"
echo "Formato esperado: tipo(alcance): descripción"
echo "Ejemplos: feat(auth): añadir login, fix: corregir bug #123"
exit 1
fi
exit 0
Gestión de hooks con herramientas
En lugar de crear hooks manualmente, usa herramientas que los gestionan por ti:
Husky (Node.js):
# Instalar husky
npm install husky --save-dev
# Inicializar
npx husky init
# Crear hook pre-commit
echo "npx lint-staged" > .husky/pre-commit
# Crear hook commit-msg
echo "npx --no -- commitlint --edit \$1" > .husky/commit-msg
Lefthook (Go, multi-idioma):
# Instalar lefthook
brew install lefthook # macOS
# o
go install github.com/evilmartians/lefthook@latest
# Inicializar
lethook install
# Configurar en lefthook.yml
pre-commit:
commands:
lint:
run: npx lint-staged {staged_files}
glob: "*.{js,ts,jsx,tsx}"
Hooks compartidos del equipo
Los hooks de .git/hooks/ no se suben al repositorio. Para compartirlos:
-
Carpeta
.githooks/en el repo:# Configurar Git para usar esa carpeta git config core.hooksPath .githooks # O en .git/config [core] hooksPath = .githooks -
Con Husky (recomendado): Husky guarda los hooks en
.husky/que sí se sube al repo. -
Con package.json:
{ "scripts": { "prepare": "husky" } }Esto ejecuta
huskyautomáticamente al hacernpm install.
Desactivar hooks temporalmente
# Saltar hooks de pre-commit
git commit --no-verify -m "commit rápido"
# Saltar hooks de pre-push
git push --no-verify
9. Alias (Atajos personalizados)
Los alias son atajos que simplifican comandos largos. Se configuran con git config y se guardan en ~/.gitconfig o .git/config.
Crear alias
# Sintaxis básica
git config --global alias.<nombre> "<comando>"
# Ejemplos básicos
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.cm commit
git config --global alias.lg "log --oneline --graph --all"
Alias útiles para el día a día
# Ver estado
git config --global alias.st status
# Log visual
git config --global alias.lg "log --oneline --graph --all --decorate"
git config --global alias.ll "log --pretty=format:'%C(yellow)%h%Creset %s %C(green)(%cr)%Creset %C(blue)<%an>%Creset' --graph"
git config --global alias.la "log --pretty=format:'%C(yellow)%h%Creset %s %C(green)(%cr)%Creset' --graph --all"
# Commits
git config --global alias.amend "commit --amend --no-edit"
git config --global alias.last "commit -C HEAD"
git config --global alias.undo "reset --soft HEAD~1"
# Diffs
git config --global alias.ds "diff --staged"
git config --global alias.dh "diff HEAD~1"
# Ramas
git config --global alias.branches "branch -a --sort=-committerdate"
git config --global alias.unmerged "branch --no-merged"
# Stash
git config --global alias.s "stash"
git config --global alias.sp "stash push"
git config --global alias.sl "stash list"
# Limpieza
git config --global alias.cleanup "!git branch --merged | grep -v '\\*\\|main\\|master' | xargs -n 1 git branch -d"
Alias avanzados con ! (ejecutar shell)
Los alias que empiezan con ! ejecutan comandos de shell directamente:
# Ver el último commit con diff
git config --global alias.lastdiff "!git show --stat HEAD"
# Commits de hoy
git config --global alias.today "log --since='00:00:00' --oneline --no-merges"
# Commits de esta semana
git config --global alias.week "log --since='1 week ago' --oneline --no-merges"
# Autores por número de commits
git config --global alias.top-authors "shortlog -s -n --no-merges"
# Limpiar ramas ya mergeadas
git config --global alias.cleanup "!git branch --merged | grep -v '\\*\\|main\\|master\\|develop' | xargs -n 1 git branch -d"
# Abrir el último commit en el navegador (GitHub)
git config --global alias.browse "!git remote -v | head -1 | sed 's/.*github.com[:/]/https:\\/\\/github.com\\//' | sed 's/\\.git$//' | xargs open"
# Ver archivos ignorados
git config --global alias.ignored "status --ignored -s"
# Diff con solo nombres de archivos
git config --global alias.changed "diff --name-only"
# Tag el commit actual
git config --global alias.tag-now "!git tag -a $(date +%Y%m%d-%H%M%S) -m 'Tag automático'"
Ver y gestionar alias
# Ver todos los alias
git config --global --get-regexp alias
# Ver un alias concreto
git config --global alias.lg
# Eliminar un alias
git config --global --unset alias.lg
# Editar alias manualmente
git config --global --edit
Configuración recomendada en .gitconfig
[alias]
st = status
co = checkout
br = branch
cm = commit
lg = log --oneline --graph --all --decorate
ll = log --pretty=format:'%C(yellow)%h%Creset %s %C(green)(%cr)%Creset %C(blue)<%an>%Creset' --graph
amend = commit --amend --no-edit
undo = reset --soft HEAD~1
ds = diff --staged
branches = branch -a --sort=-committerdate
cleanup = !git branch --merged | grep -v '\\*\\|main\\|master' | xargs -n 1 git branch -d
ignored = status --ignored -s
top-authors = shortlog -s -n --no-merges
10. Comandos Advanced que debes conocer
Aplicar parches
-
git apply: Aplica parches en formato diff a tu working tree. No crea commits, solo modifica archivos.--check: Verifica si el parche se puede aplicar sin hacer nada (dry-run).--stat: Muestra un resumen de lo que cambiaría el parche.--reject: Aplica lo que puede y guarda lo que falla en archivos.rej.--3way(-3): Intenta fusión a 3 bandas si el parche no aplica limpiamente.--reverse: Invierte el parche (deshace los cambios).--cached: Aplica los cambios solo al stage (índice).-v(--verbose): Salida detallada.--whitespace=nowarn/--whitespace=fix: Controla qué hacer con espacios en blanco.
git apply --check parche.diff # ¿Se puede aplicar? git apply parche.diff # Aplicar al working tree git apply --3way parche.diff # Aplicar con merge a 3 bandas git apply --reverse parche.diff # Deshacer el parche -
git stash: Ya cubierto en la sección 2, pero recuerda:git stash apply --indexintenta restaurar el stage exacto.git stash branch nueva-ramacrea una rama desde el stash.
Herramientas gráficas y web
-
git gui: Abre una interfaz gráfica para commits ( Tcl/Tk). Útil para:- Ver el diff stageado lado a lado
- Hacer amend rápidamente
- Navegar el historial de un archivo
- Gestionar ramas
-
gitk: Visor de historial gráfico.--all: Muestra todas las ramas.--regexp-ignore-case: Búsqueda insensible a mayúsculas.--select=<commit>: Selecciona un commit específico al abrir.--full-history: Historial completo (sin simplificación).
-
git citool: Alternativa agit guipara commits rápidos. Más simple, solo para staging y commit. -
git instaweb: Levanta un servidor web local para explorar el repositorio en el navegador.--httpd=<servidor>: Servidor a usar (lighttpd, apache, python).-p <puerto>: Puerto (por defecto 1234).--start/--stop: Inicia/detiene el servidor.--browse: Abre el navegador automáticamente.
git instaweb --start --httpd=python # Levantar en Python # Abre http://localhost:1234 git instaweb --stop # Detener
Merge avanzado
-
git merge-tree: Simula un merge sin modificar el working tree. Útil para prever conflictos.<base> <ours> <theirs>: Los tres árboles a fusionar.- El resultado se escribe en stdout con marcadores de conflicto si los hay.
# Ver qué pasaría si fusionamos feature en main git merge-tree main feature | head -50 # Comparar con el merge real git diff HEAD...feature --stat -
git read-tree: Lee un tree object en el índice. Útil para scripting avanzado.-m <tree>: Fusiona un tree en el índice (como un merge sin commit).-u: Actualiza el working tree después de leer el tree.--prefix=<prefijo>: Lee el tree en un subdirectorio del índice.
Gestión de packs y objetos
-
git multi-pack-index(Git 2.20+): Gestiona un índice que abarca múltiples packs. Acelera operaciones en repos grandes.write: Escribe/actualiza el multi-pack-index.verify: Verifica la integridad del índice.expire: Elimina packs vacíos del índice.repack: Repacka y actualiza el índice.--object-dir=<dir>: Directorio de objetos (para worktrees).
git multi-pack-index write # Generar/actualizar índice git multi-pack-index verify # Verificar integridad -
git commit-graph(Git 2.18+): Genera un grafo de commits que aceleragit log,git merge-baseygit rev-list.write: Genera el archivocommit-graph.verify: Verifica el archivo.read: Muestra información del grafo.--reachable: Incluye commits alcanzables desde refs.--changed-paths: Añade información de paths cambiados (paragit log --diff-filtermás rápido).
git commit-graph write --reachable # Generar grafo completo git log --commit-graph --oneline # Usar el grafo (más rápido)
Logs avanzados
-
git whatchanged: Formato antiguo de log que muestra el diff de cada commit. Útil para ver qué archivos cambian en cada commit.-p: Muestra el diff completo (por defecto).--stat: Solo resumen de archivos.--oneline: Formato compacto.--since=<fecha>: Filtrado por fecha.
git whatchanged -p --since="2 weeks ago" # Diffs de los últimos 2 semanas -
git log --source: Muestra de qué rama vino cada commit. Útil en rebase interactivo o cuando usas--cherry-pick.- Combined con
--onelinemuestra la rama origen.
- Combined con
-
git log --cherry-pick: Evita mostrar commits equivalentes entre ramas (útil para ver qué falta por integrar sin duplicados). -
git log --cherry: Como--cherry-pickpero en formato=(equivale) o-(no equivale).
Peticiones de merge y email
-
git request-pull: Genera un mensaje para pedir que hagan merge de tu rama.<origen> <destino> [<url> [<descripción>]]: Crea el mensaje con la diff entre ramas.
git request-pull origin/main feature/login https://github.com/user/repo -
git send-email: Envía parches por email (usado en proyectos Linux/kernel).--to=<email>: Destinatario.--cc=<email>: Copia.--cover-letter: Incluye carta de presentación.--annotate: Añade comentarios a cada parche.
Información del repositorio
-
git count-objects -vH: Estadísticas de almacenamiento del repo.count: 150 size: 580.00 KiB in-pack: 1250 packs: 1 size-pack: 2.30 MiB -
git fsck --lost-found: Restaura objetos huérfanos a.git/lost-found/. Útil para recuperar commits perdidos. -
git verify-pack -v .git/objects/pack/*.idx: Muestra qué objetos están en un pack y su tamaño. Útil para encontrar archivos grandes.# Encontrar los 10 archivos más grandes en el historial git rev-list --objects --all | \ git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | \ sed -n 's/^blob //p' | \ sort -rnk2 | head -10
📂 Bonus: Configuración Global de .gitignore
Evita subir archivos basura de sistema o herramientas en todos tus proyectos locales:
# 1. Crear el archivo global
touch ~/.gitignore_global
# 2. Configurar Git para que lo use siempre
git config --global core.excludesfile ~/.gitignore_global
# 3. Ejemplo de contenido recomendado para ~/.gitignore_global:
# node_modules/
# .vscode/
# .idea/
# .DS_Store
# Thumbs.db
# .env
🧹 Guía: Eliminar un archivo del historial de Git como si nunca hubiera existido
Es posible que hayas subido un archivo que nunca debió estar en el repositorio: un .env con contraseñas, un node_modules/ de 500MB, un vídeo de prueba, o cualquier archivo que no debería estar ahí. El problema es que, aunque lo borres con git rm, el archivo sigue en el historial. Cualquiera que clone el repo puede verlo con git log -p.
Esta guía te muestra cómo eliminar un archivo de TODO el historial de forma que sea como si nunca hubiera existido.
⚠️ Antes de empezar: Entiende las consecuencias
| Consecuencia | Explicación |
|---|---|
| Cambia hashes | Todos los commits que contenían el archivo tendrán nuevos hashes |
| Rompe colaboradores | Todos los que tengan el repo necesitan clonar de nuevo |
| Rompe pull requests | PRs abiertos contra ramas antiguas dejarán de funcionar |
| Rompe CI/CD | Pipelines que usen commits antiguos fallarán |
| No se puede deshacer | Una vez hecho, no hay vuelta atrás |
Regla de oro: Solo haz esto si realmente necesitas que el archivo desaparezca del historial (seguridad, datos sensibles, archivos muy grandes).
Método 1: git filter-repo (RECOMENDADO)
La forma moderna, rápida y segura.
Paso 1: Instalar filter-repo
# macOS
brew install filter-repo
# Linux (pip)
pip install filter-repo
# Ubuntu/Debian
sudo apt install git-filter-repo
Paso 2: Eliminar un archivo concreto
# Eliminar un archivo específico de TODO el historial
git filter-repo --path .env --invert-paths
# Eliminar un archivo con nombre específico
git filter-repo --path secrets/passwords.txt --invert-paths
# Eliminar MÚLTIPLES archivos
git filter-repo --path .env --path secrets.json --path *.key --invert-paths
Paso 3: Eliminar una carpeta completa
# Eliminar toda la carpeta node_modules/
git filter-repo --path node_modules/ --invert-paths
# Eliminar la carpeta .env/ con todo su contenido
git filter-repo --path .env/ --invert-paths
# Eliminar archivos grandes (>10MB)
git filter-repo --strip-blobs-bigger-than 10M
Paso 4: Reconfigurar el remote
# filter-repo cambia las URLs del remote. Reconfigura:
git remote add origin https://github.com/tu-usuario/tu-repo.git
git push origin --all --force
git push origin --tags --force
Método 2: BFG Repo-Cleaner (alternativa fácil)
BFG es una herramienta externa más fácil de usar que filter-repo para casos comunes.
Instalar BFG
# macOS
brew install bfg
# Linux (descargar jar)
wget https://repo1.maven.org/maven2/com/madgag/bfg/1.14.0/bfg-1.14.0.jar
# Usar con: java -jar bfg-1.14.0.jar
Usar BFG
# Eliminar un archivo
bfg --delete-files .env
# Eliminar una carpeta
bfg --delete-folders node_modules
# Eliminar archivos >50MB
bfg --strip-blobs-bigger-than 50M
# Reemplazar texto (ej. contraseñas)
bfg --replace-text passwords.txt
BFG es más rápido porque no toca commits que no contienen el archivo objetivo.
Método 3: git filter-branch (DEPRECADO)
⚠️ No recomendado. Úsalo solo si no puedes instalar filter-repo ni BFG.
# Eliminar un archivo de TODO el historial
git filter-branch --tree-filter 'rm -f .env' HEAD
# Eliminar del índice (más rápido)
git filter-branch --index-filter 'git rm --cached --ignore-unmatch .env' HEAD
# Eliminar una carpeta
git filter-branch --tree-filter 'rm -rf node_modules' HEAD
# Limpiar después
git filter-branch --prune-empty --tag-name-filter cat -- --all
Después de eliminar: Pasos obligatorios
1. Verificar que el archivo desapareció
# Buscar el archivo en el historial (debería no encontrar nada)
git log --all --full-history -- .env
# Buscar texto específico en el historial
git log --all -S "API_KEY" --oneline
# Verificar tamaño del repo
git count-objects -vH
2. Limpiar el repo local
# Eliminar referencias originales
git reflog expire --expire=now --all
git gc --prune=now --aggressive
3. Forzar push (BORRA el historial en el remoto)
# ⚠️ ESTO BORRA EL HISTORIAL EN EL SERVIDOR
git push origin --all --force
git push origin --tags --force
4. Notificar a tu equipo
Esto es CRÍTICO. Todos los que tengan el repo necesitan hacer esto:
# Cada colaborador debe eliminar su copia local y clonar de nuevo
cd ..
rm -rf tu-repo
git clone https://github.com/tu-usuario/tu-repo.git
O si quieren conservar su trabajo:
cd tu-repo
# Guardar ramas locales importantes
git branch -a > /tmp/ramas.txt
# Fetch el nuevo historial
git fetch --all
# Resetear a el nuevo main
git reset --hard origin/main
# Re-crear ramas locales desde el nuevo historial
git checkout -b mi-feature origin/mi-feature
5. Invalidar caché en plataformas
Si el repo está en GitHub/GitLab, necesitas invalidar la caché:
- GitHub: Contacta soporte o haz un push vacío después de 24h
- GitLab: Ve a Repository > Cleanup > Start cleanup
- Bitbucket: Contacta soporte
Casos prácticos
Caso 1: Subí un .env con credenciales
# 1. Eliminar del historial
git filter-repo --path .env --invert-paths
# 2. Añadir a .gitignore (si no está)
echo ".env" >> .gitignore
git add .gitignore
git commit -m "chore: añadir .gitignore"
# 3. Revocar TODAS las credenciales que estaban en .env
# (esto es lo más importante: las credenciales están comprometidas)
# 4. Force push
git push origin --all --force
Caso 2: Subí node_modules/ (500MB)
# 1. Eliminar del historial
git filter-repo --path node_modules/ --invert-paths
# 2. Añadir a .gitignore
echo "node_modules/" >> .gitignore
# 3. Limpiar y push
git reflog expire --expire=now --all
git gc --prune=now --aggressive
git push origin --all --force
Caso 3: Un vídeo de 2GB en el historial
# 1. Eliminar archivos >50MB
git filter-repo --strip-blobs-bigger-than 50M
# 2. O eliminar el archivo específico
git filter-repo --path videos/test.mp4 --invert-paths
# 3. Limpiar
git reflog expire --expire=now --all
git gc --prune=now --aggressive
git push origin --all --force
Caso 4: Quiero ver qué archivos grandes hay en el historial
# Encontrar los 10 archivos más grandes que ALGUNA VEZ estuvieron en el repo
git rev-list --objects --all | \
git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | \
sed -n 's/^blob //p' | \
sort -rnk2 | head -10
# Salida:
# abc123def456 234567890 videos/demo.mp4
# 789xyz012abc 123456789 node_modules/big-package.tar.gz
# ...
Resumen rápido
| Situación | Comando |
|---|---|
| Archivo con credenciales | git filter-repo --path .env --invert-paths |
| node_modules subido | git filter-repo --path node_modules/ --invert-paths |
| Archivos grandes | git filter-repo --strip-blobs-bigger-than 50M |
| Múltiples archivos | git filter-repo --path a.txt --path b.txt --invert-paths |
| Ver archivos grandes | git rev-list --objects --all | git cat-file --batch-check=... |
| Limpiar después | git reflog expire --expire=now --all && git gc --prune=now --aggressive |
| Push obligigatorio | git push origin --all --force && git push origin --tags --force |
🔗 Recursos
Del blog (recopilación de recursos)
- 🐙 Git / Control de Versiones — Recursos visuales interactivos: Learn Git Branching, Visual Git Reference, Oh My Git! y más.
- ⭐ Repositorios Destacados GitHub — Proyectos open-source destacados en GitHub: freeCodeCamp, Awesome, Developer Roadmap, System Design Primer y más.
- 💻 Terminal — Herramientas CLI y terminal: emuladores, multiplexores (tmux), editores (neovim), buscadores (fzf, ripgrep) y utilidades dev.
Documentación oficial
- Pro Git Book — Scott Chacon & Ben Straub — Libro completo y gratuito en español, cubre desde lo básico hasta Git internals.
- Git Reference — git-scm.com — Documentación oficial de cada comando, flags y ejemplos.
- Git Cheat Sheet (PDF) — Chuleta descargable de GitHub Education.
Tutoriales interactivos
- Learn Git Branching — Simulador visual interactivo de ramas, merge, rebase y conflictos. Imprescindible.
- Git How To — Taller guiado paso a paso desde cero.
- Oh My Git! — Juego open-source para aprender Git jugando.
Resolución de problemas
- Oh Shit, Git!?! (es) — Qué hacer cuando la cagas con Git, explicado simple y directo.
- Dangit, Git!?! — Versión alternativa con más comandos de emergencia.
- Git Flight Rules — Guía exhaustiva de «qué hacer cuando algo sale mal», mantenida por la comunidad.
Referencias visuales
- Visual Git Reference (es) — Cada comando explicado con diagramas de cómo se mueven los datos.
- Git Visualization Tool — Visualizador en tiempo real de comandos Git.
- Atlassian Git Tutorials — Tutoriales visuales con casos reales de uso en equipo.
Workflows y trucos
- A successful Git branching model — Vincent Driessen — El artículo original de Git Flow.
- Conventional Commits — Especificación para mensajes de commit semánticos.
- GitHub Flow — Flujo ligero de GitHub (alternativa a Git Flow).
- git-tips — Colección de tips avanzados y casos de uso reales.
Herramientas visuales
- Sourcetree — GUI gratuita de Git con visualización de ramas.
- GitKraken — Cliente Git con interfaz gráfica y editor de grafos.
- Lazygit — TUI (terminal UI) para Git en la terminal, super ágil.
- tig — Navegador de repositorio Git para terminal (modo NCurses).
Hooks y automatización
- Git Hooks — guía de ejemplos — Catálogo de hooks útiles para automatizar tu flujo.
- Husky — Herramienta moderna para gestionar hooks Git en proyectos Node.
- Lefthook — Alternativa rápida a Husky, escrita en Go, multi-idioma.
