2010-05-24 28 views
7

Tengo un árbol de trabajo sucio, sucio porque realicé cambios en los archivos fuente y retoqué algunas imágenes. Estaba tratando de agregar solo las imágenes al índice, así que ejecuté este comando:¿Agregar Git no funciona con archivos .png?

git add *.png 

Pero esto no agrega los archivos. Hubo unos pocos nuevos archivos de imagen que se agregaron, pero ninguno de los que se modificaron/preexistieron se agregaron.

¿Qué ofrece?

Editar: Aquí hay alguna salida del terminal relevante

$ git status 
# On branch master 
# 
# Changed but not updated: 
# (use "git add <file>..." to update what will be committed) 
# (use "git checkout -- <file>..." to discard changes in working directory) 
# 
# modified: src/main/java/net/plugins/analysis/FormMatcher.java 
# modified: src/main/resources/icons/doctor_edit_male.png 
# modified: src/main/resources/icons/doctor_female.png 
# 
# Untracked files: 
# (use "git add <file>..." to include in what will be committed) 
# 
# src/main/resources/icons/arrow_up.png 
# src/main/resources/icons/bullet_arrow_down.png 
# src/main/resources/icons/bullet_arrow_up.png 
no changes added to commit (use "git add" and/or "git commit -a") 

Entonces ejecutado "git add * .png" (sin salida después de un comando)

continuación:

$ git status 
# On branch master 
# 
# Changes to be committed: 
# (use "git reset HEAD <file>..." to unstage) 
# 
# new file: src/main/resources/icons/arrow_up.png 
# new file: src/main/resources/icons/bullet_arrow_down.png 
# new file: src/main/resources/icons/bullet_arrow_up.png 
# 
# Changed but not updated: 
# (use "git add <file>..." to update what will be committed) 
# (use "git checkout -- <file>..." to discard changes in working directory) 
# 
# modified: src/main/java/net/plugins/analysis/FormMatcher.java 
# modified: src/main/resources/icons/doctor_edit_female.png 
# modified: src/main/resources/icons/doctor_edit_male.png 
+1

raro:/¿Puedes darme más información? Extractos de 'git status' o algo así? –

+0

No aparecen en la pantalla "git commit -a", ¿verdad? –

+2

¿Estás seguro de que el comodín coincide con los archivos modificados que esperas agregar? (Prueba fácil: ¿los muestra 'ls * .png'?) – Cascabel

Respuesta

15

comentario de Michael Mrozek es esencialmente la respuesta. *.png coincide con los archivos de ese nombre en el directorio actual, no en los subdirectorios. Si desea añadir otros en un subdirectorio, hacerlo:

git add src/main/resources/icons/*.png 

O, dependiendo de su cáscara, es posible que pueda hacer:

git add **/*.png 

El punto es que es la cáscara que hace globbing (expande * .png en una lista de nombres de archivos). Git no tiene nada que ver con eso; simplemente toma los argumentos que le da el caparazón.

Editar: Dado que esto logró ser aceptado, debo seguir y señalar como otros hicieron que algunos comandos de git admiten globbing internamente (a través de fnmatch), por lo que si cita un patrón global, se pasará sin modificaciones de shell a git, donde tendrá lugar la expansión globbing.

+1

Buena captura. +1. Tengo cosas extrañas vistas con el método subyacente 'fnname()' que difieren por sistema operativo: ver por ejemplo: http://stackoverflow.com/questions/2330471/gitignore-does-not-understand-my-folder-wildcard-on-windows y http://stackoverflow.com/questions/1470572/ – VonC

1

En duda, intente:

git -A -- *.png 

, que podría ser más amplio (git add man page)

-A 
--all 

Como -u, pero <filepattern> partido contra los archivos en el directorio de trabajo, además del índice.
Eso significa que encontrará nuevos archivos, así como organizar el contenido modificado y eliminar los archivos que ya no están en el árbol de trabajo.

ver a la pregunta "Difference of “git add -A” and “git add ."

+0

lo probé, pero no funcionó :( – DLaw

10

Algunos de los comandos de Git (incluido git add) pueden manejar los patrones de nombre de archivo. Pero primero debes asegurarte de que el patrón llegue a Git.

En general, es posible que los patrones sin comillas no lleguen al comando invocado.Como caso especial, si el patrón no coincide con ningún archivo (en el directorio actual si no hay una barra en el patrón), bash pasará el patrón no expandido al comando (a menos que se establezca la opción nullglob, en cuyo caso el patrón el argumento se eliminará de los argumentos pasados ​​al comando). Pero el comportamiento varía entre las conchas. De forma predeterminada, zsh emite un error como "no se encontraron coincidencias" a menos que la opción nomatch no esté configurada (pasa el patrón no expandido como argumento) o se establece la opción null_glob (descarta el patrón de la lista de argumentos).

Por lo tanto, utilizar patrones sin comillas y esperar que lleguen al comando subyacente solo es confiable si conoce el comportamiento de su caparazón y conoce el contenido de los directorios especificados en el patrón (normalmente solo el directorio actual para patrones sin barra oblicua).

Por lo tanto, para obtener la máxima confiabilidad, si desea git add para obtener la cadena literal *.png como argumento, debe citarla.

git add \*.png 
git add "*.png" 
git add '*'.png 
# etc. 

Una vez que haya superado con éxito un patrón de nombre de archivo para Git, se encontrará con algunas diferencias con respecto a la forma en conchas trata de manera.

La principal diferencia de preocupación en esta pregunta es que la coincidencia se realiza por fnmatch(3)sin conjunto de FNM_PATHNAME. Esto significa que un patrón como *.png coincidirá con un archivo foo.png en el directorio actual (como un shell), pero también coincidirá con dir/bar.png (porque sin FNM_PATHNAME el * puede coincidir con la barra). Git llama a sus patrones "pathspecs" para diferenciarlos de los patrones "glob" de shell.

Lamentablemente, hay una incoherencia en la forma en que git add maneja pathspecs. Siempre los aplica a los archivos sin seguimiento, pero nunca los aplica a los archivos rastreados (en cambio, los argumentos del tipo de nombre de archivo como pathspecs solo se comprueban para encontrar coincidencias exactas con la lista de archivos rastreados). Esto es aparentemente exactamente con lo que se encontró el OP, ya que agregaría nuevos archivos que coinciden con la ruta de acceso, pero no actualizaría (ya) los archivos rastreados que coinciden con la ruta de acceso.

La solución provisional de Jefromi (git add **/*.png) funciona siempre que su shell admita el patrón extendido ** (o un equivalente).

En realidad puedes hacer que Git haga el trabajo, pero usar el caparazón es probablemente más fácil (si tu caparazón lo admite).

# update all tracked files matching the Git pathspec *.png 
git ls-files --cached -z \*.png | git update-index --add -z --stdin 

Suavizar la manipulación pathspec interno de Git es un “medio plazo” objetivo, pero no uno que cualquier persona con el tiempo, el interés y la experiencia pertinente ha dado un paso adelante para arreglar.

Fue criado como project idea for Google Summer of Code 2010 (no recogido por nadie), y temas relacionados a plantear en la lista de correo de vez en cuando (en enero y en marzo de 2010 Una persona informó a symptom much like the OP's, Git's maintainer explained what he would like to see in the long term).

+0

+1, mucho más completo que mi respuesta. – Cascabel

0

Los sistemas de archivos insensibles a las mayúsculas y minúsculas como la configuración predeterminada de Mac OS X también causarán estragos. Si cambias 'directorio' a 'Directorio' no conseguirás que git lo reconozca a menos que te muevas a otra carpeta temporal, confirmes, retrocedas y vuelvas a cometer.

0

git ls-files es una buena manera de enumerar todo en su repositorio git

Para su caso, puede hacer algo como

git ls-files --modified | grep '\.png$' | xargs git add 

Lista de los archivos modificados, filtro por extensión (.png en este caso) y git agrega las entradas resultantes

Cuestiones relacionadas