Git Pathspecs y cómo usarlos | Programar Plus

Cuando estaba mirando la documentación de los comandos de git, noté que muchos de ellos tenían una opción para <pathspec>. Inicialmente pensé que esta era solo una forma técnica de decir “ruta” y supuse que solo podía aceptar directorios y nombres de archivos. Después de sumergirme en la madriguera del conejo de la documentación, descubrí que la opción pathspec de los comandos git es capaz de mucho más.

Pathspec es el mecanismo que usa git para limitar el alcance de un comando de git a un subconjunto del repositorio. Si ha usado mucho git, es probable que haya usado una especificación de ruta, lo sepa o no. Por ejemplo, en el comando git add README.md, la especificación de ruta es README.md. Sin embargo, es capaz de muchos más matices y flexibilidad.

Entonces, ¿por qué debería aprender sobre pathspecs? Dado que es parte de muchos comandos, estos comandos se vuelven mucho más poderosos con una comprensión de las especificaciones de ruta. Con git add, puede agregar solo los archivos dentro de un solo directorio. Con git diff, puede examinar solo los cambios realizados en los nombres de archivo con una extensión de .scss. Usted puede git grep todos los archivos excepto los del /dist directorio.

Además, pathspecs puede ayudar con la escritura de alias de git más genéricos. Por ejemplo, tengo un alias llamado git todo, que buscará la cadena en todos mis archivos de repositorio 'todo'. Sin embargo, me gustaría que esto mostrara todas las instancias de la cadena, incluso si no están dentro de mi directorio de trabajo actual. Con pathspecs, veremos cómo esto es posible.

archivo o directorio

La forma más sencilla de usar una especificación de ruta es con solo un directorio y/o un nombre de archivo. Por ejemplo, con git add puedes hacer lo siguiente. ., src/, y README son las especificaciones de ruta respectivas para cada comando.

git add .      # add CWD (current working directory)
git add src/   # add src/ directory
git add README # add only README directory

También puede agregar varias especificaciones de ruta a un comando:

git add src/ server/ # adds both src/ and server/ directories

A veces, es posible que vea un -- que precede a la especificación de ruta de un comando. Esto se usa para eliminar cualquier ambigüedad de cuál es la especificación de ruta y qué es parte del comando.

comodines

Además de archivos y directorios, puede hacer coincidir patrones usando *, ?, y []. El * El símbolo se utiliza como comodín y coincidirá con el / en rutas; en otras palabras, buscará a través de subdirectorios.

git log '*.js' # logs all .js files in CWD and subdirectories
git log '.*'   # logs all 'hidden' files and directories in CWD
git log '*/.*' # logs all 'hidden' files and directories in subdirectories

Las comillas son importantes, especialmente cuando se usan *! Evitan que su shell (como bash o ZSH) intente expandir los comodines por su cuenta. Por ejemplo, echemos un vistazo a cómo git ls-files enumerará los archivos con y sin las comillas.

# example directory structure
#
# .
# ├── package-lock.json
# ├── package.json
# └── data
#     ├── bar.json
#     ├── baz.json
#     └── foo.json

git ls-files *.json 

# package-lock.json
# package.json

git ls-files '*.json'

# data/bar.json
# data/baz.json
# data/foo.json
# package-lock.json
# package.json

Dado que el caparazón está expandiendo el * en el primer comando, git ls-files recibe el comando como git ls-files package-lock.json package.json. Las comillas aseguran que git es el que resuelve el comodín.

También puede utilizar el ? carácter como comodín para un solo carácter. Por ejemplo, para hacer coincidir cualquiera mp3 o mp4 archivos, puede hacer lo siguiente.

git ls-files '*.mp?'

Expresiones de paréntesis

También puede usar “expresiones entre paréntesis” para hacer coincidir un solo carácter de un conjunto. Por ejemplo, si desea hacer coincidencias entre archivos TypeScript o JavaScript, puede usar [tj]. Esto coincidirá con un t o un j.

git ls-files '*.[tj]s'

Esto coincidirá con cualquiera .ts archivos o .js archivos Además de solo usar caracteres, hay ciertas colecciones de caracteres a las que se puede hacer referencia dentro de las expresiones entre paréntesis. Por ejemplo, puedes usar [:digit:] dentro de una expresión de paréntesis para que coincida con cualquier dígito decimal, o puede usar [:space:] para que coincida con cualquier carácter de espacio.

git ls-files '*.mp[[:digit:]]' # mp0, mp1, mp2, mp3, ..., mp9
git ls-files '*[[:space:]]*' # matches any path containing a space

Para leer más sobre la expresión entre paréntesis y cómo usarla, consulte el manual de GNU.

firmas mágicas

Pathspecs también tiene la herramienta especial en su arsenal llamada “firmas mágicas” que desbloquea algunas funciones adicionales para sus pathspecs. Estas “firmas mágicas” se llaman usando :(signature) al comienzo de su pathspec. Si esto no tiene sentido, no se preocupe: esperamos que algunos ejemplos ayuden a aclararlo.

cima

El top La firma le dice a git que coincida con el patrón de la raíz del repositorio de git en lugar del directorio de trabajo actual. También puedes usar la abreviatura :/ en vez de :(top).

git ls-files ':(top)*.js'
git ls-files ':/*.js' # shorthand

Esto mostrará una lista de todos los archivos en su repositorio que tienen una extensión de .js. Con el top firma esto se puede llamar dentro de cualquier subdirectorio en su repositorio. ¡Encuentro que esto es especialmente útil al escribir alias genéricos de git!

git config --global alias.js 'ls-files -- ':(top)*.js''

Puedes usar git js en cualquier lugar dentro de su repositorio para obtener una lista de todos los archivos JavaScript en su proyecto usando esto.

caso

El icase La firma le dice a git que no se preocupe por las mayúsculas y minúsculas al hacer coincidir. Esto podría ser útil si no le importa en qué caso está el nombre del archivo; por ejemplo, esto podría ser útil para hacer coincidir jpg archivos, que a veces usan la extensión en mayúsculas JPG.

git ls-files ':(icase)*.jpg'

literal

El literal La firma le dice a git que trate a todos tus personajes literalmente. Esto se usaría si desea tratar caracteres como * y ? como ellos mismos, en lugar de como comodines. A menos que su repositorio tenga nombres de archivo con * o ?, no espero que esta firma se use con demasiada frecuencia.

git log ':(literal)*.js' # returns log for the file '*.js'

globo

Cuando comencé a aprender pathspecs, noté que los comodines funcionaban de manera diferente a como estaba acostumbrado. Normalmente veo un solo asterisco * como un comodín que no coincide con nada a través de directorios y asteriscos consecutivos (**) como un comodín “profundo” que coincide con nombres a través de directorios. Si prefiere este estilo de comodines, puede utilizar el glob firma mágica!

Esto puede ser útil si desea un control más detallado sobre cómo buscar en la estructura de directorios de su proyecto. Como ejemplo, observe cómo estos dos git ls-files puede buscar a través de un proyecto React.

git ls-files ':(glob)src/components/*/*.jsx' # 'top level' jsx components
git ls-files ':(glob)src/components/**/*.jsx' # 'all' jsx components

atributo

Git tiene la capacidad de establecer “atributos” a archivos específicos. Puede establecer estos atributos mediante un .gitattributes Archivo.

# .gitattributes

src/components/vendor/*  vendored # sets 'vendored' attribute
src/styles/vendor/*      vendored

Utilizando el attr La firma mágica puede establecer requisitos de atributos para su especificación de ruta. Por ejemplo, es posible que deseemos ignorar los archivos anteriores de un proveedor.

git ls-files ':(attr:!vendored)*.js' # searches for non-vendored js files
git ls-files ':(attr:vendored)*.js'  # searches for vendored js files

excluir

Por último, está la firma mágica “excluir” (abreviatura de :! o :^). Esta firma funciona de forma diferente al resto de firmas mágicas. Una vez resueltas todas las demás especificaciones de ruta, todas las especificaciones de ruta con un exclude firma se resuelven y luego se eliminan de las rutas devueltas. Por ejemplo, puede buscar en todos sus .js archivos mientras se excluyen los .spec.js archivos de prueba.

git grep 'foo' -- '*.js' ':(exclude)*.spec.js' # search .js files excluding .spec.js
git grep 'foo' -- '*.js' ':!*.spec.js' .       # shorthand for the same

Combinando firmas

¡No hay nada que te limite a usar múltiples firmas mágicas en una sola especificación de ruta! Puede usar múltiples firmas separando sus palabras mágicas con comas dentro de su paréntesis. Por ejemplo, puede hacer lo siguiente si desea hacer coincidir desde la base de su repositorio (usando top), mayúsculas y minúsculas (usando icase), usando solo código creado (ignorando los archivos de proveedores con attr), y usando comodines de estilo global (usando glob).

git ls-files -- ':(top,icase,glob,attr:!vendored)src/components/*/*.jsx'

Las únicas dos firmas mágicas que no puedes combinar son glob y literal, ya que ambos afectan cómo git trata con comodines. Esto se menciona en el glosario de git con quizás mi oración favorita que he leído en cualquier documentación.

La magia glob es incompatible con la magia literal.

Pathspecs son una parte integral de muchos comandos de git, pero su flexibilidad no es accesible de inmediato. Al aprender a usar comodines y firmas mágicas, puede multiplicar su dominio de la línea de comandos de git.

(Visited 11 times, 1 visits today)