2013-10-03 10 views
12

So che rimuovere lo spazio vuoto finale può essere fatto con un hook pre-commit. Sono interessato a farlo manualmente. Ho letto la domanda qui:
Make git automatically remove trailing whitespace before committing - Stack Overflow
La risposta più vicina a quello che voglio è the "automatic version" from ntc2:

git rimuove lo spazio vuoto finale nei nuovi file prima del commit

(export VISUAL=: && git -c apply.whitespace=fix add -ue .) && git checkout . && git reset 


che il comando funziona bene tranne che sembra essere solo per le modifiche sui file che sono già nel repository, non nuovi file. Ho un sacco di file che sono nuovi, il che significa che non sono ancora nel repository. Voglio rimuovere gli spazi bianchi da questi file, quindi ho provato ad aggiungere -A invece di -u ma questo non ha fatto la differenza.

+1

Vuoi dire "git add -Ae' non aggiunge nuovi file"? Oppure: "i file vengono aggiunti, ma non riparati"? – VonC

+0

@VonC Non funziona su file non tracciati o nuovi (aggiunti per la prima volta ma non ancora impegnati). Per me mostra 'fatale: Empty patch. Aborted. Sto usando git versione 1.8.3.msysgit.0. – loop

+0

@test: se avessi lasciato un commento sulla mia risposta originale, o chiedendo come far funzionare il mio comando, o collegandolo alla tua domanda, avrei ricevuto una notifica e avrei potuto parlarti di 'add -N'. Ma, SO è stato abbastanza intelligente da mettere la tua domanda nella sezione "Related" così l'ho vista quando ho modificato la mia risposta oggi. – ntc2

risposta

30

Per pulire manualmente gli spazi dai vostri ultimi 3 commit, si può fare questo:

git rebase --whitespace=fix HEAD~3

Quando lavoro su un ramo argomento, a monitorare il ramo di monte (di solito creando in questo modo)

git checkout -b topic -t

Che mi consente di eliminare l'ultimo argomento da git rebase. Così una volta ho finito & pronto a fondersi, posso pulire l'intero argomento ramo rapidamente con:

git ws # alias per rebase --whitespace = fissare

Si noti che, a differenza del HEAD ~ 3 esempio, questo in realtà cambierà le tue modifiche sul ramo upstream se è cambiato! (Ma questo è anche quello che voglio, nel mio flusso di lavoro.)

+0

Luke funziona ma sai perché Non posso usare il comando che ho chiesto nella mia domanda? – loop

+0

Mi colpisce, ho paura; ma dato che whitespace = fix è destinato all'applicazione di patch (incluso rebase) non mi sorprende che sorgano problemi. Strippare w da file non tracciati è come modificare file al di fuori del repository: questo non è il lavoro di Git. –

+2

Ehi, ecco qualcosa che ho appena inventato (dai comandi di base) per ripulire solo le modifiche di stage (lasciando la selezione dei file aggiunti intatta in seguito): 'git commit -mTemp && git stash && git rebase HEAD ~ --whitespace = fix && git reset --soft HEAD ~ && git stash pop'. –

2

semplice correzione

Il comando che ha citato

(export GIT_EDITOR=: && git -c apply.whitespace=fix add -ue .) && git checkout . && git reset 

opere se si aggiungono prima i file che si desidera fissare con git add -N <files you want to fix>. Lo add -N in sostanza dice a Git di fingere di aver precedentemente commesso versioni vuote dei file.

errore ti ha

Non capisco perché si ottiene fatal: Empty patch. Aborted. errore add -Ae, ma sembra come un insetto, dal momento che facendo pianura git add -A . && git diff --cached dimostra che la patch non dovrebbe in realtà essere vuoto.

Meglio fixer spazi

ho recentemente aggiornato my answer that you linked to con una migliore Git alias per il fissaggio spazi bianchi.Ecco una riscrittura di quell'alias utilizzando Luke's rebase trick e un flusso di controllo meno ridondante:

fixws =!"\ 
    if (! git diff-index --quiet --cached HEAD); then \ 
    \ 
    git diff-files --quiet `git rev-parse --show-toplevel` ; \ 
    export NEED_TO_STASH=$? ; \ 
    \ 
    git commit -m FIXWS_SAVE_INDEX && \ 
    if [ 1 = $NEED_TO_STASH ] ; then git stash save FIXWS_SAVE_TREE; fi && \ 
    git rebase --whitespace=fix HEAD~ && \ 
    git reset --soft HEAD~ && \ 
    if [ 1 = $NEED_TO_STASH ] ; then git stash pop; fi ; \ 
    fi" 

Questo fissa spazi nell'indice, preservando l'indice, e lasciando l'albero intatto. Con questo alias, è possibile correggere senza versione file nella repo con

git add --all :/ && git fixws && git reset 

Ma, gestisce anche il caso più comune di riparazione in su spazi bianchi in una commettere si sta lavorando. È complicato perché funziona anche quando l'indice o l'albero sono puliti.

+0

Se questo lascia intatto l'albero, non significa che qualsiasi correzione di spazio bianco nell'indice mostrerà su al contrario in 'git diff', e verrà ripristinato quando aggiungi i file interessati all'indice? Immagino sia per questo che hai 'git reset' nella tua pipeline, ma sembra che annulli il beneficio di lasciare intatto l'albero. – jbyler

+0

@jbyler: se ti riferisci al 'reset' nella combo' add', 'fixws',' reset', allora il punto è annullare l'iniziale 'add'. Notare che il reset di default è '--mixed', che tocca solo l'indice, non l'albero. – ntc2

+0

Ciao, ho aggiunto il tuo alias oggi e ho provato la migliore riga di comando del tuo whitespace fixer. Inizialmente non funzionava perché in precedenza avevo abilitato il gancio di pre-commit per la cattura delle violazioni di spazi bianchi. Sospettavo cosa stesse succedendo, quindi l'ho disabilitato e poi ho eseguito il comando e ha funzionato. Grazie ancora! – loop

6

Mi piace la risposta di Luke, fatta eccezione per la limitazione che è necessario specificare manualmente il commit di base o utilizzare un flusso di lavoro in stile rebase, in cui la cronologia è linearizzata. Propongo una modifica che non richiede un argomento aggiuntivo e non modifica la topologia del grafico di commit. Come un comando di shell:

git rebase --whitespace=fix --onto $(git merge-base HEAD @{u}) 

O come un alias ~/.gitconfig:

ws = "!git rebase --whitespace=fix --onto $(git merge-base HEAD @{u})" 

Preferisco questo perché a volte voglio rebase miei cambiamenti, ma se penso che ci potrebbe essere una fusione conflitto preferisco unirmi, in modo che sia la mia modifica originale sia la risoluzione del conflitto vengano registrate nella cronologia. In questo modo potrò in seguito secondo-indovinare la risoluzione del conflitto e rifarla se necessario.

Dato che non sempre rebase, preferisco non mescolare il whitespace-fixing con rebasing; da qui questa modifica alla risposta di Luca.

Inoltre, abilita la predefinita pre-commit hook, che interrompe in caso di errori spazi bianchi:

cp .git/hooks/pre-commit.sample .git/hooks/pre-commit 

Questo dà il seguente flusso di lavoro, che mi piace perché è abbastanza manuale che io so cosa sta succedendo, ma automatizzato abbastanza di non mettersi in cammino:

  1. hack hack, introdurre errori spazi
  2. tentativo di commettere
  3. commit fallisce con w Errore di hitespace a causa di pre-commit hook
  4. git commit --no-verify a commettere ogni caso
  5. git ws utilizzare l'alias per risolvere

Nota sull'uso di --onto: Non è necessario qui, ma trovo più facile ragionare su come funziona il rebase in questo modo. Nella versione di Luke, HEAD~3 è il <upstream> nella pagina man, mentre nella mia versione <upstream> mantiene il suo valore predefinito del vero upstream del ramo. Comunque, si finisce sempre con lo stesso risultato.

+0

Uso piacevole del '--onto' lì. +1 – VonC