Git può passare automaticamente da spazi a schede?


196

Uso i tab per il rientro nei miei programmi Python, ma vorrei collaborare (usando git) con persone che usano spazi invece.

C'è un modo per git di convertire automaticamente tra spazi e tab (diciamo, 4 spazi = 1 tab) spingendo / recuperando? (simile alla conversione CR / LF)


33
PEP8 è precisamente il mio problema. Tutti lo seguono e sono bloccato con le mie schede. Mi capita di pensare che un rientro = una scheda sia la cosa giusta da fare (perché spazi? Perché 4 spazi? PEP8 non lo spiega ...). Ad ogni modo, con questo trucco git, posso felicemente usare le schede sul mio computer e condividere il mio codice con tutti i follower di PEP8 là fuori.
Olivier Verdier,

7
Oh! Uso TextMate e posso convertire tra spazi in schede. Il fatto è che quando premo tab, mi piace il mio editor per scrivere ... tab. Quindi, se controllo un progetto Python con spazi, inserirò tutti i tipi di schede. Devo convertire manualmente in schede, ma quando eseguo il check-in, sembrano 1000 eliminazioni, 1000 aggiunte e i miei collaboratori non saranno contenti. :-)
Olivier Verdier,

6
Il motivo per cui PEP8 specifica spazi anziché tab è dovuto alle regole di rientro della continuazione. Esistono due modi per continuare una linea troppo lunga all'interno di un parentetico. Se inizi una nuova riga immediatamente dopo una parentesi, ne indentri una. Se invece metti parte del contenuto tra parentesi sulla prima riga, allora devi continuare la parentesi sulla riga successiva a livello di rientro tra parentesi iniziale. Se usi schede che non funzionano.
John Christopher Jones,

2
@JohnChristopherJones per quella situazione, si potrebbero usare le schede per abbinare il rientro con la riga precedente e quindi gli spazi per abbinare una posizione nella riga precedente. Questo può essere convertito facilmente in spazi. Sfortunatamente non è vero il contrario, perché mescola le informazioni di rientro con le informazioni di allineamento.
Patrick Parker,

Risposte:


195

Ecco la soluzione completa:

Nel tuo repository, aggiungi un file .git/info/attributesche contiene:

*.py  filter=tabspace

Linux / Unix

Ora esegui i comandi:

git config --global filter.tabspace.smudge 'unexpand --tabs=4 --first-only'
git config --global filter.tabspace.clean 'expand --tabs=4 --initial'

OS X

Prima installa coreutils con brew:

brew install coreutils

Ora esegui i comandi:

git config --global filter.tabspace.smudge 'gunexpand --tabs=4 --first-only'
git config --global filter.tabspace.clean 'gexpand --tabs=4 --initial'

Tutti i sistemi

Ora puoi controllare tutti i file del tuo progetto. Puoi farlo con:

git checkout HEAD -- **

e tutti i file Python ora avranno tab invece di spazi.

Modifica : modificato il comando di checkout forzato. Dovresti impegnarti per primo, ovviamente.


1
Il filtro pulito non funziona per me. Quando lo faccio aggiungo git. Ricevo un errore che dice "errore: filtro esterno espandere --tabs = 4 --initial fallito". Sono su Windows. Questo fa la differenza?
Jeremy Hicks,

2
@Jeremy: espandere / annullare l'espansione sono comandi unix. Dovrai trovare porte / equivalenti di Windows o usare qualcosa come Cygwin
Tim

1
Ho trovato bast funzionante versione sourceforge.net/projects/gnuwin32/files/coreutils/5.3.0
hazzik

3
@ Marc-André Un buon punto. In realtà uso le versioni coreutils. (Installa homebrew, quindi esegui brew install coreutils).
Olivier Verdier,

2
Sembra che non funzioni più, i filtri non fanno nulla per me. Dopo il checkout, i file hanno ancora spazi. Qualche aggiornamento a questo proposito?
Philipp Ludwig,

141

Sì, una potenziale soluzione consiste nell'utilizzare un driver di filtro degli attributi git (vedere anche il libro GitPro ), per definire un meccanismo di sfumatura / pulizia.

testo alternativo

Quel modo:

  • ogni volta che esegui il checkout di alcuni file del tuo repository, gli spazi possono essere convertiti in schede,
  • ma quando effettui il check-in (e spingi e pubblichi), quegli stessi file vengono archiviati usando solo spazi.

Puoi dichiarare questo driver di filtro (chiamato qui ' tabspace') in .git/info/attributes(per un filtro applicato a tutti i file all'interno del repository Git), con il seguente contenuto:

*.py  filter=tabspace

Ora esegui i comandi:

# local config for the current repo
git config filter.tabspace.smudge 'script_to_make_tabs'
git config filter.tabspace.clean 'script_to_make_spaces'

Vedi la risposta di Olivier per un esempio concreto di lavoro di un insieme così chiaro di istruzioni.


Sfortunatamente, semplicemente non funziona. Ho seguito tutte le istruzioni, ma git non applica il fiter. :-( Quando eseguo il checkout, il filtro sbavature non viene applicato e quando eseguo il check-in, non succede nulla ... git è così frustrante a volte ...
Olivier Verdier

@Olivier: Strano, non ho mai avuto problemi con questo, purché limiti attentamente l'ambito del filtro degli attributi (a una sottostruttura specifica, solo per un tipo specifico di file) al fine di non rallentare il checkout / check- in corso. Si veda ad esempio stackoverflow.com/questions/62264/...
VonC

Grazie! Ora funziona. Vedi la soluzione completa: stackoverflow.com/questions/2316677/…
Olivier Verdier

@Vonc: forse si dovrebbe rimuovere la --globalbandiera, dal momento che ciò implicherebbe, si inviano spazi per ogni progetto di collaborazione ...
Willem Van Onsem

@CommuSoft solo ai progetti che hanno il diritto .gitattributes. Sì, è più facile capire se la configurazione è mantenuta locale nel repository. Ho modificato la risposta.
VonC,

39

Informazioni molto utili per tutti coloro che usano GitHub (o altri servizi simili)

~/.gitconfig

[filter "tabspace"]
    smudge = unexpand --tabs=4 --first-only
    clean = expand --tabs=4 --initial
[filter "tabspace2"]
    smudge = unexpand --tabs=2 --first-only
    clean = expand --tabs=2 --initial

Quindi ho due file: attributes

*.js  filter=tabspace
*.html  filter=tabspace
*.css  filter=tabspace
*.json  filter=tabspace

e attributes2

*.js  filter=tabspace2
*.html  filter=tabspace2
*.css  filter=tabspace2
*.json  filter=tabspace2

Lavorare su progetti personali

mkdir project
cd project
git init
cp ~/path/to/attributes .git/info/

In questo modo, quando finalmente spingi il tuo lavoro su github, non sembrerà sciocco nella vista del codice con 8 space tabsquale è il comportamento predefinito in tutti i browser.

Contribuire ad altri progetti

mkdir project
cd project
git init
cp ~/path/to/attributes2 .git/info/attributes
git remote add origin git@github.com:some/repo.git
git pull origin branch

In questo modo puoi lavorare con le normali schede dei 2 space indentedprogetti.

Ovviamente puoi scrivere una soluzione simile per la conversione da 4 space to 2 spacecui è il caso se vuoi contribuire a progetti pubblicati da me e tendi a usare 2 spazi durante lo sviluppo.


2
Correlati: memorizzazione di git config come parte del repository ; nota anche che puoi usare (e impegnare) un .gitattributesfile nel tuo repository
Tobias Kienzler,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.