Czy git może automatycznie przełączać się między spacjami i tabulatorami?

196

Używam tabulatorów do wcięć w moich programach pythonowych, ale chciałbym współpracować (używając git) z ludźmi, którzy zamiast tego używają spacji.

Czy istnieje sposób, aby git automatycznie konwertował między spacjami i tabulatorami (powiedzmy, 4 spacje = 1 tab) po wypychaniu / pobieraniu? (podobny do konwersji CR / LF)

Olivier Verdier
źródło
33
PEP8 jest właśnie moim problemem. Wszyscy podążają za tym i utknąłem z zakładkami. Zdarza mi się myśleć, że jedno wcięcie = jedna tabulator jest właściwą rzeczą (dlaczego spacje? Dlaczego 4 spacje? PEP8 tego nie wyjaśnia ...). W każdym razie dzięki tej sztuczce git z radością mogę używać kart na komputerze i dzielić się kodem ze wszystkimi obserwatorami PEP8.
Olivier Verdier
7
O! Używam TextMate i mogę konwertować spacje na tabulatory. Chodzi o to, że kiedy naciskam klawisz tab, lubię, by mój edytor pisał ... tab. Więc jeśli sprawdzę projekt w języku Python ze spacjami, wstawię wszystkie tabulatory. Muszę ręcznie przekonwertować na zakładki, ale kiedy się zaloguję, wygląda na to, że 1000 usunięć, 1000 dodatków, a moi współpracownicy nie będą zadowoleni. :-)
Olivier Verdier
6
Powodem, dla którego PEP8 określa spacje zamiast tabulatorów, są reguły wcięcia kontynuacji. Istnieją dwa sposoby kontynuowania zbyt długiej linii w nawiasie. Jeśli zaczynasz nową linię natychmiast po nawiasie, po prostu wcięcie jednej linii. Jeśli zamiast tego umieścisz część treści w nawiasie w pierwszym wierszu, musisz kontynuować nawias w następnym wierszu na poziomie wcięcia otwierającego nawiasu. Jeśli korzystasz z kart, które nie działają.
John Christopher Jones
2
@JohnChristopherJones w tej sytuacji można użyć tabulatorów, aby dopasować wcięcie do poprzedniej linii, a następnie spacji, aby dopasować pozycję w poprzedniej linii. Można to łatwo przekształcić w spacje. Niestety sytuacja odwrotna nie jest prawdziwa, ponieważ łączy informacje o wcięciach z informacjami o wyrównaniu.
Patrick Parker,

Odpowiedzi:

195

Oto kompletne rozwiązanie:

W swoim repozytorium dodaj plik .git/info/attributeszawierający:

*.py  filter=tabspace

Linux / Unix

Teraz uruchom polecenia:

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

OS X

Najpierw zainstaluj coreutils z naparem:

brew install coreutils

Teraz uruchom polecenia:

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

Wszystkie systemy

Możesz teraz sprawdzić wszystkie pliki swojego projektu. Możesz to zrobić za pomocą:

git checkout HEAD -- **

i wszystkie pliki Pythona będą teraz miały tabulatory zamiast spacji.

Edycja : zmieniono polecenie wymuszonego pobrania. Oczywiście powinieneś najpierw wykonać swoją pracę.

Olivier Verdier
źródło
1
Czysty filtr nie działa dla mnie. Kiedy to zrobię, dodaj. Pojawia się komunikat o błędzie „błąd: filtr zewnętrzny rozwiń --tabs = 4 - początkowe niepowodzenie”. Jestem na Windowsie. Czy to robi różnicę?
Jeremy Hicks,
2
@Jeremy: expand / unexand są poleceniami uniksowymi. Musisz albo znaleźć porty / ekwiwalenty Windows, albo użyć czegoś takiego jak Cygwin
Tim
1
Znalazłem bast działającą wersję sourceforge.net/projects/gnuwin32/files/coreutils/5.3.0
hazzik
3
@ Marc-André Dobra uwaga. Właściwie używam wersji coreutils. (Zainstaluj homebrew, a następnie uruchom brew install coreutils).
Olivier Verdier
2
Wygląda na to, że to już nie działa, filtry nic dla mnie nie robią. Po kasie pliki nadal mają spacje. Czy to ma jakieś aktualizacje?
Philipp Ludwig
141

Tak, jednym z potencjalnych rozwiązań jest użycie sterownika filtru atrybutów git (patrz także książka GitPro ), aby zdefiniować mechanizm rozmazywania / czyszczenia.

alternatywny tekst

W ten sposób:

  • za każdym razem, gdy kasujesz niektóre pliki repo, spacje można konwertować na tabulatory,
  • ale podczas odprawy (oraz wypychania i publikowania) te same pliki są zapisywane z powrotem tylko przy użyciu spacji.

Możesz zadeklarować ten sterownik filtra (o nazwie tutaj ' tabspace') w .git/info/attributes(dla filtra zastosowanego do wszystkich plików w repozytorium Git), o następującej treści:

*.py  filter=tabspace

Teraz uruchom polecenia:

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

Zobacz Olivier jest odpowiedzią na konkretny przykład takiej pracy rozmazywanie / czystej zestaw instrukcji.

VonC
źródło
Niestety po prostu nie działa. Postępowałem zgodnie ze wszystkimi instrukcjami, ale git nie stosuje instalatora. :-( Kiedy kasuję, filtr rozmazywania nie jest stosowany, a kiedy się kasuję, nic się też nie dzieje ... czasami git jest tak frustrujący ...
Olivier Verdier
@Olivier: Dziwne, nigdy nie miałem z tym problemu, o ile ostrożnie ograniczam zakres filtru atrybutów (do konkretnego poddrzewa, tylko dla określonego typu plików), aby nie spowalniać kasy / w trakcie. Zobacz na przykład stackoverflow.com/questions/62264/…
VonC
Dzięki! Teraz działa. Zobacz kompletne rozwiązanie: stackoverflow.com/questions/2316677/...
Olivier Verdier
@Vonc: być może należy usunąć --globalflagę, ponieważ oznaczałoby to wysłanie spacji do każdego projektu współpracy ...
Willem Van Onsem,
@CommuSoft tylko do projektów, które mają do tego prawo .gitattributes. Ale tak, łatwiej zrozumieć, czy konfiguracja jest lokalna dla repozytorium. Zredagowałem odpowiedź.
VonC
39

Bardzo przydatne informacje dla wszystkich korzystających z GitHub (lub innej podobnej usługi)

~/.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

Następnie mam dwa pliki: attributes

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

i attributes2

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

Praca nad osobistymi projektami

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

W ten sposób, kiedy w końcu pchniesz swoją pracę na github, nie będzie wyglądać głupio w widoku kodu, z 8 space tabsktórym jest domyślne zachowanie we wszystkich przeglądarkach.

Wkład w inne projekty

mkdir project
cd project
git init
cp ~/path/to/attributes2 .git/info/attributes
git remote add origin [email protected]:some/repo.git
git pull origin branch

W ten sposób możesz pracować z normalnymi zakładkami w 2 space indentedprojektach.

Oczywiście możesz napisać podobne rozwiązanie do konwersji, z 4 space to 2 spacektórego ma to miejsce, jeśli chcesz przyczynić się do opublikowanych przeze mnie projektów i podczas programowania zwykle używasz 2 spacji.

simo
źródło
2
Powiązane: Przechowywanie konfiguracji git jako części repozytorium ; pamiętaj również, że możesz użyć (i zatwierdzić) .gitattributesplik w swoim repozytorium
Tobias Kienzler
1

Jeśli korzystasz z systemu Windows, musisz wykonać kilka dodatkowych kroków, aby uruchomić rozwiązanie @Olivier Verdier .

  1. Pobierz CoreUtils na Windows
  2. Po zainstalowaniu umieść lokalizację instalacji w zmiennej PATH ( jak dodać zmienną ścieżki )
  3. Zmieniłem nazwę expand.exe na gexpand.exe, ponieważ istnieje już narzędzie do rozwijania systemu Windows.
odyth
źródło