2010-05-24 8 views
7

Ho un albero di lavoro sporco, sporco perché ho apportato modifiche ai file di origine e ho ritoccato alcune immagini. Stavo cercando di aggiungere solo le immagini all'indice, quindi ho eseguito questo comando:Git add non funziona con i file .png?

git add *.png 

Ma questo non aggiunge i file. Sono stati aggiunti alcuni file immagine nuovi aggiunti, ma nessuno di quelli modificati/preesistenti è stato aggiunto.

Cosa dà?

Edit: Ecco un po 'di uscita del terminale in questione

$ 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") 

quindi eseguito "git add * .png" (nessuna uscita dopo il comando)

Poi:

$ 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

strano:/puoi dare qualche informazione in più? Estratti da 'stato git 'o qualcosa del genere? –

+0

Non si visualizzano sullo schermo "Git commit -a", giusto? –

+2

Sei sicuro che il carattere jolly corrisponda ai file modificati che ti aspetti di aggiungere? (Test facile: mostra 'ls * .png'?) – Cascabel

risposta

15

commento di Michael Mrozek è essenzialmente la risposta. *.png corrisponde a file con quel nome nella directory corrente, non nelle sottodirectory. Se si desidera aggiungere quelli in una sottodirectory, fare così:

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

Oppure, a seconda della vostra shell, si può essere in grado di fare:

git add **/*.png 

Il punto è che è il guscio che fa il globbing (espande * .png in una lista di nomi di file). Git non ha niente a che fare con questo; prende solo gli argomenti che la shell gli dà.

Edit: Dal momento che questo è riuscito a farsi accettare, dovrei andare avanti e sottolineare come altri hanno fatto che alcuni comandi git supportano globbing internamente (via fnmatch), quindi se si cita un modello di glob, sarà approvata senza modifiche dal guscio a git, dove l'espansione globbing avrà luogo.

+1

Buona cattura. +1. ho visto cose strane con il metodo 'fnname()' che differisce per sistema operativo: vedi per esempio: http://stackoverflow.com/questions/2330471/gitignore-does-not-understand-my-folder-wildcard-on-windows e http://stackoverflow.com/questions/1470572/ – VonC

1

In dubbio, prova:

git -A -- *.png 

, che potrebbe essere più completo (git add man page)

-A 
--all 

Come -u, ma partita <filepattern> contro i file nella struttura di lavoro in aggiunta all'indice.
Ciò significa che troverà nuovi file, nonché il contenuto modificato di staging e la rimozione di file che non si trovano più nell'albero di lavoro.

vedere così domanda "Difference of “git add -A” and “git add ."

+0

provato, ma non ha funzionato :( – DLaw

10

Alcuni dei comandi di Git (incluso git add) possono gestire direttamente i nomi dei file. Ma prima devi assicurarti che il modello arrivi a Git.

In generale, i motivi non quotati non possono accedere al comando invocato.Come caso speciale, se il modello non corrisponde a nessun file (nella directory corrente se non vi è alcuna barra nel motivo), bash passerà il modello non espanso al comando (a meno che non sia impostata l'opzione nullglob, nel qual caso il modello l'argomento verrà eliminato dagli argomenti passati al comando). Ma il comportamento varia tra le conchiglie. Per impostazione predefinita, zsh genera un errore come "Nessuna corrispondenza trovata" a meno che l'opzione nomatch non sia impostata (passa il modello non espanso come argomento) o è impostata l'opzione null_glob (elimina il modello dall'elenco di argomenti).

Quindi utilizzare schemi non quotati e aspettarsi che arrivino al comando sottostante è affidabile solo se si conosce il comportamento della shell e si conosce il contenuto di qualsiasi directory specificata nel pattern (in genere solo la directory corrente per i pattern senza barra).

Quindi, per la massima affidabilità, se si desidera git add ottenere la stringa letterale *.png come argomento, quindi è necessario citarla.

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

Dopo aver superato con successo un modello di nome di file a Git, si incontrano alcune differenze rispetto come conchiglie li gestisce.

La differenza principale di preoccupazione in questa domanda è che la corrispondenza è fatto da fnmatch(3)senza FNM_PATHNAME set. Ciò significa che un modello come *.png corrisponderà a un file foo.png nella directory corrente (proprio come una shell), ma corrisponderà anche a dir/bar.png (perché senza FNM_PATHNAME lo * può corrispondere alla barra). Git chiama i suoi pattern "pathspecs" per differenziarli dai pattern "glob" della shell.

Sfortunatamente, c'è un'incongruenza nel modo in cui lo git add gestisce le pathspec. Li applica sempre ai file non tracciati, ma non li applica mai ai file monitorati (invece, gli argomenti tipo-file come pathspecs vengono controllati solo per corrispondenze esatte rispetto all'elenco dei file tracciati). Questo è apparentemente esattamente ciò che l'OP ha effettivamente eseguito, in quanto aggiungerebbe nuovi file che corrispondono al pathspec, ma non riuscirebbe ad aggiornare (già) i file tracciati che corrispondono al pathspec.

La soluzione alternativa di Jefromi (git add **/*.png) funziona finché la shell supporta il modello esteso ** (o un equivalente).

In realtà, Git può fare il lavoro, ma l'uso della shell è probabilmente più semplice (se la shell lo supporta).

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

appianare movimentazione pathspec interno di Git è un “medio termine” obiettivo, ma non uno che chiunque con il tempo, l'interesse, e l'esperienza pertinente è fatto avanti per fissare.

è stato portato come un project idea for Google Summer of Code 2010 (non raccolto da nessuno), e le questioni connesse venire sulla mailing list di tanto in tanto (in gennaio e di nuovo marzo 2010 qualcuno ha riferito a symptom much like the OP's, Git's maintainer explained what he would like to see in the long term).

+0

+1, molto più completo della mia risposta. – Cascabel

0

I file system senza distinzione tra maiuscole e minuscole, come l'impostazione predefinita di Mac OS X, causeranno anche il caos. Se cambi 'directory' in 'Directory' non otterrai git per riconoscerlo a meno che non ti sposti in un'altra cartella temporanea, commetti, torni indietro e esegui nuovamente il commit.

0

git ls-files è un buon modo per elencare tutto nella vostra git repo

Per il vostro caso si può fare qualcosa di simile

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

Lista i file modificati, il filtro per estensione (.png in questo caso) e git aggiungi le voci risultanti