-
1. Inicio - Sobre el Control de Versiones
-
2. Fundamentos de Git
-
3. Ramificaciones en Git
-
4. Git en el Servidor
- 4.1 Los Protocolos
- 4.2 Configurando Git en un servidor
- 4.3 Generando tu clave pública SSH
- 4.4 Configurando el servidor
- 4.5 El demonio Git
- 4.6 HTTP Inteligente
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 Git en un alojamiento externo
- 4.10 Resumen
-
5. Git en entornos distribuidos
-
6. GitHub
-
7. Herramientas de Git
- 7.1 Revisión por selección
- 7.2 Organización interactiva
- 7.3 Guardado rápido y Limpieza
- 7.4 Firmando tu trabajo
- 7.5 Buscando
- 7.6 Reescribiendo la Historia
- 7.7 Reiniciar Desmitificado
- 7.8 Fusión Avanzada
- 7.9 Rerere
- 7.10 Haciendo debug con Git
- 7.11 Submódulos
- 7.12 Agrupaciones
- 7.13 Replace
- 7.14 Almacenamiento de credenciales
- 7.15 Resumen
-
8. Personalización de Git
-
9. Git y Otros Sistemas
- 9.1 Git como Cliente
- 9.2 Migración a Git
- 9.3 Resumen
-
10. Los entresijos internos de Git
-
A1. Apéndice A: Git en otros entornos
- A1.1 Interfaces gráficas
- A1.2 Git en Visual Studio
- A1.3 Git en Eclipse
- A1.4 Git con Bash
- A1.5 Git en Zsh
- A1.6 Git en Powershell
- A1.7 Resumen
-
A2. Apéndice B: Integrando Git en tus Aplicaciones
- A2.1 Git mediante Línea de Comandos
- A2.2 Libgit2
- A2.3 JGit
-
A3. Apéndice C: Comandos de Git
- A3.1 Configuración
- A3.2 Obtener y Crear Proyectos
- A3.3 Seguimiento Básico
- A3.4 Ramificar y Fusionar
- A3.5 Compartir y Actualizar Proyectos
- A3.6 Inspección y Comparación
- A3.7 Depuración
- A3.8 Parcheo
- A3.9 Correo Electrónico
- A3.10 Sistemas Externos
- A3.11 Administración
- A3.12 Comandos de Fontanería
7.5 Herramientas de Git - Buscando
Buscando
Con casi cualquier tamaño de código de base, a menudo necesitará encontrar en dónde se llama o define una función, o encontrar el historial de un método. Git proporciona un par de herramientas útiles para examinar el código y hacer commit a las instantáneas almacenadas en su base de datos de forma rápida y fácil. Vamos a revisar algunas de ellas.
Git Grep
Git se envía con un comando llamado grep
que le permite buscar fácilmente a través de cualquier árbol o directorio de trabajo con commit por una cadena o expresión regular. Para estos ejemplos, veremos el código fuente de Git.
Por defecto, mirará a través de los archivos en su directorio de trabajo. Puedes pasar -n
para imprimir los números de línea donde Git ha encontrado coincidencias.
$ git grep -n gmtime_r
compat/gmtime.c:3:#undef gmtime_r
compat/gmtime.c:8: return git_gmtime_r(timep, &result);
compat/gmtime.c:11:struct tm *git_gmtime_r(const time_t *timep, struct tm *result)
compat/gmtime.c:16: ret = gmtime_r(timep, result);
compat/mingw.c:606:struct tm *gmtime_r(const time_t *timep, struct tm *result)
compat/mingw.h:162:struct tm *gmtime_r(const time_t *timep, struct tm *result);
date.c:429: if (gmtime_r(&now, &now_tm))
date.c:492: if (gmtime_r(&time, tm)) {
git-compat-util.h:721:struct tm *git_gmtime_r(const time_t *, struct tm *);
git-compat-util.h:723:#define gmtime_r git_gmtime_r
Hay una serie de opciones interesantes que puede proporcionar el comando grep
.
Por ejemplo, en lugar de la llamada anterior, puedes hacer que Git resuma el resultado simplemente mostrándote qué archivos coinciden y cuántas coincidencias hay en cada archivo con la opción --count
:
$ git grep --count gmtime_r
compat/gmtime.c:4
compat/mingw.c:1
compat/mingw.h:1
date.c:2
git-compat-util.h:2
Si quieres ver en qué método o función piensa Git que ha encontrado una coincidencia, puedes pasar -p
:
$ git grep -p gmtime_r *.c
date.c=static int match_multi_number(unsigned long num, char c, const char *date, char *end, struct tm *tm)
date.c: if (gmtime_r(&now, &now_tm))
date.c=static int match_digit(const char *date, struct tm *tm, int *offset, int *tm_gmt)
date.c: if (gmtime_r(&time, tm)) {
Así que aquí podemos ver que se llama a gmtime_r
en las funciones match_multi_number
y match_digit
en el archivo date.c.
También puedes buscar combinaciones complejas de cadenas con el indicador --and
, que asegura que múltiples coincidencias estén en la misma línea. Por ejemplo, busquemos cualquier línea que defina una constante con las cadenas “LINK” o “BUF_MAX” en ellas en la base del código de Git en una versión 1.8.0 anterior.
Aquí también usaremos las opciones --break
y --heading
que ayudan a dividir el resultado en un formato más legible.
$ git grep --break --heading \
-n -e '#define' --and \( -e LINK -e BUF_MAX \) v1.8.0
v1.8.0:builtin/index-pack.c
62:#define FLAG_LINK (1u<<20)
v1.8.0:cache.h
73:#define S_IFGITLINK 0160000
74:#define S_ISGITLINK(m) (((m) & S_IFMT) == S_IFGITLINK)
v1.8.0:environment.c
54:#define OBJECT_CREATION_MODE OBJECT_CREATION_USES_HARDLINKS
v1.8.0:strbuf.c
326:#define STRBUF_MAXLINK (2*PATH_MAX)
v1.8.0:symlinks.c
53:#define FL_SYMLINK (1 << 2)
v1.8.0:zlib.c
30:/* #define ZLIB_BUF_MAX ((uInt)-1) */
31:#define ZLIB_BUF_MAX ((uInt) 1024 * 1024 * 1024) /* 1GB */
El comando git grep
tiene algunas ventajas sobre los comandos de búsqueda normales como grep
y ack
. La primera es que es realmente rápido, la segunda es que puedes buscar a través de cualquier árbol en Git, no solo en el directorio de trabajo. Como vimos en el ejemplo anterior, buscamos términos en una versión anterior del código fuente de Git, no en la versión que estaba actualmente verificada.
Búsqueda de Registro de Git
Quizás no estás buscando dónde existe un término, sino cuándo existió o se introdujo. El comando git log
tiene varias herramientas potentes para encontrar commits específicos por el contenido de sus mensajes o incluso el contenido de las diferencias que introducen.
Si queremos saber, por ejemplo, cuándo se introdujo originalmente la constante ZLIB_BUF_MAX
, podemos decirle a Git que sólo nos muestre los commits que agregaron o eliminaron esa cadena con la opción -S
.
$ git log -SZLIB_BUF_MAX --oneline
e01503b zlib: allow feeding more than 4GB in one go
ef49a7a zlib: zlib can only process 4GB at a time
Si miramos la diferencia de esos commits, podemos ver que en ef49a7a
se introdujo la constante y en e01503b
se modificó.
Si necesitas ser más específico, puedes proporcionar una expresión regular para buscar con la opción -G
.
Búsqueda de Registro de Línea
Otra búsqueda de registro bastante avanzada que es increíblemente útil es la búsqueda del historial de línea. Esta es una adición bastante reciente y no muy conocida, pero puede ser realmente útil. Se llama con la opción -L
a git log
y te mostrará el historial de una función o línea de código en tu base de código.
Por ejemplo, si quisiéramos ver cada cambio realizado en la función git_deflate_bound
en el archivo zlib.c
, podríamos ejecutar git log -L :git_deflate_bound:zlib.c
. Esto intentará descubrir cuáles son los límites de esa función y luego examinará el historial y nos mostrará cada cambio que se hizo a la función como una serie de parches de cuando se creó la función por primera vez.
$ git log -L :git_deflate_bound:zlib.c
commit ef49a7a0126d64359c974b4b3b71d7ad42ee3bca
Author: Junio C Hamano <gitster@pobox.com>
Date: Fri Jun 10 11:52:15 2011 -0700
zlib: zlib can only process 4GB at a time
diff --git a/zlib.c b/zlib.c
--- a/zlib.c
+++ b/zlib.c
@@ -85,5 +130,5 @@
-unsigned long git_deflate_bound(z_streamp strm, unsigned long size)
+unsigned long git_deflate_bound(git_zstream *strm, unsigned long size)
{
- return deflateBound(strm, size);
+ return deflateBound(&strm->z, size);
}
commit 225a6f1068f71723a910e8565db4e252b3ca21fa
Author: Junio C Hamano <gitster@pobox.com>
Date: Fri Jun 10 11:18:17 2011 -0700
zlib: wrap deflateBound() too
diff --git a/zlib.c b/zlib.c
--- a/zlib.c
+++ b/zlib.c
@@ -81,0 +85,5 @@
+unsigned long git_deflate_bound(z_streamp strm, unsigned long size)
+{
+ return deflateBound(strm, size);
+}
+
Si Git no puede encontrar la forma de relacionar una función o método en tu lenguaje de programación, también puedes proporcionarle una expresión regular. Por ejemplo, esto habría hecho lo mismo: git log -L '/unsigned long git_deflate_bound/',/^}/:zlib.c
. También podrías darle un rango de líneas o un único número de línea y obtendrás el mismo tipo de salida.