Bisakah git beralih antar spasi dan tab secara otomatis?

196

Saya menggunakan tab untuk indentasi dalam program python saya, tetapi saya ingin berkolaborasi (menggunakan git) dengan orang-orang yang menggunakan spasi.

Apakah ada cara bagi git untuk secara otomatis mengkonversi antara spasi dan tab (katakanlah, 4 spasi = 1 tab) saat mendorong / mengambil? (mirip dengan konversi CR / LF)

Olivier Verdier
sumber
33
PEP8 justru masalah saya. Semua orang mengikutinya dan saya terjebak dengan tab saya. Saya kebetulan berpikir bahwa satu lekukan = satu tab adalah hal yang benar untuk dilakukan (mengapa spasi? Mengapa 4 spasi? PEP8 tidak menjelaskan itu ...). Ngomong-ngomong, dengan trik git ini, saya dapat menggunakan tab di komputer saya dan membagikan kode saya dengan semua pengikut PEP8 di luar sana.
Olivier Verdier
7
Oh! Saya menggunakan TextMate, dan saya bisa mengonversi antar spasi menjadi tab. Masalahnya, ketika saya menekan tab, saya suka editor saya untuk menulis ... tab. Jadi jika saya checkout proyek python dengan spasi, saya akan memasukkan semua jenis tab. Saya harus mengonversi ke tab secara manual, tetapi ketika saya check-in, sepertinya 1000 penghapusan, 1000 tambahan, dan kolaborator saya tidak akan senang. :-)
Olivier Verdier
6
Alasan PEP8 menentukan spasi bukan tab adalah karena aturan lekukan kelanjutan. Ada dua cara untuk melanjutkan garis yang terlalu panjang di dalam tanda kurung. Jika Anda memulai baris baru segera setelah tanda kurung, Anda tinggal membuat indentasi. Jika Anda sebaliknya meletakkan bagian dari isi tanda kurung pada baris pertama maka Anda harus melanjutkan tanda kurung pada baris berikutnya pada tingkat lekukan tanda kurung pembuka. Jika Anda menggunakan tab yang tidak berfungsi.
John Christopher Jones
2
@JohnChristopherJones untuk situasi itu, seseorang dapat menggunakan tab untuk mencocokkan indentasi dengan baris sebelumnya kemudian spasi untuk mencocokkan posisi di baris sebelumnya. Ini dapat dikonversi menjadi spasi dengan mudah. Sayangnya, kebalikannya tidak benar, karena itu mengacaukan informasi indentasi dengan informasi penyelarasan.
Patrick Parker

Jawaban:

195

Inilah solusi lengkapnya:

Di repositori Anda, tambahkan file .git/info/attributesyang berisi:

*.py  filter=tabspace

Linux / Unix

Sekarang jalankan perintah:

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

OS X

Pertama instal coreutils dengan minuman:

brew install coreutils

Sekarang jalankan perintah:

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

Semua sistem

Anda sekarang dapat memeriksa semua file proyek Anda. Anda dapat melakukannya dengan:

git checkout HEAD -- **

dan semua file python sekarang akan memiliki tab bukan spasi.

Sunting : mengubah perintah checkout terpaksa. Anda harus melakukan pekerjaan Anda terlebih dahulu, tentu saja.

Olivier Verdier
sumber
1
Filter bersih tidak berfungsi untuk saya. Ketika saya git add. Saya mendapatkan pesan kesalahan "kesalahan: filter eksternal perluas --tab = 4 - awal gagal" Saya di Windows. Apakah itu membuat perbedaan?
Jeremy Hicks
2
@Jeremy: expand / unexpand adalah perintah unix. Anda harus menemukan port / setara Windows atau menggunakan sesuatu seperti Cygwin
Tim
1
Saya telah menemukan kulit pohon versi kerja sourceforge.net/projects/gnuwin32/files/coreutils/5.3.0
hazzik
3
@ Marc-André Poin bagus. Saya sebenarnya menggunakan versi coreutils. (Instal homebrew, lalu jalankan brew install coreutils).
Olivier Verdier
2
Tampaknya ini tidak berfungsi lagi, filter tidak melakukan apa pun untuk saya. Setelah checkout, file masih memiliki spasi. Adakah pembaruan tentang ini?
Philipp Ludwig
141

Ya, salah satu solusi potensial adalah dengan menggunakan driver filter atribut git (lihat juga buku GitPro ), untuk mendefinisikan mekanisme noda / bersih.

teks alternatif

Seperti itu:

  • setiap kali Anda checkout beberapa file dari repo Anda, spasi dapat dikonversi dalam tab,
  • tetapi ketika Anda check-in (dan mendorong dan menerbitkan), file-file yang sama disimpan kembali hanya menggunakan spasi.

Anda dapat mendeklarasikan driver filter ini (dinamai di sini ' tabspace') di .git/info/attributes(untuk filter yang diterapkan ke semua file dalam repo Git), dengan konten berikut:

*.py  filter=tabspace

Sekarang jalankan perintah:

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

Lihat Olivier 's jawaban untuk contoh kerja konkret dari noda seperti / set bersih instruksi.

VONC
sumber
Sayangnya, itu tidak berfungsi. Saya mengikuti semua instruksi, tetapi git tidak menerapkan fiter. :-( Ketika saya checkout, filter noda tidak diterapkan, dan ketika saya checkin, tidak ada yang terjadi baik ... git begitu frustasi kadang-kadang ...
Olivier Verdier
@Olivier: Aneh, saya tidak pernah punya masalah dengan itu, selama saya dengan hati-hati membatasi ruang lingkup filter atribut (untuk subtree tertentu, untuk jenis file tertentu saja) agar tidak memperlambat checkout / check- dalam proses. Lihat misalnya stackoverflow.com/questions/62264/…
VonC
Terima kasih! Sekarang berhasil. Lihat solusi lengkap: stackoverflow.com/questions/2316677/…
Olivier Verdier
@ Vonc: mungkin orang harus menghapus --globalbendera, karena ini akan menyiratkan, Anda mengirim spasi ke setiap proyek kolaborasi ...
Willem Van Onsem
@CommuSoft hanya untuk proyek-proyek yang berhak .gitattributes. Tapi ya, lebih mudah untuk dipahami jika konfigurasi disimpan secara lokal ke repo. Saya telah mengedit jawabannya.
VonC
39

Info yang sangat berguna untuk semua orang yang menggunakan GitHub (atau layanan serupa lainnya)

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

Lalu saya punya dua file: attributes

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

dan attributes2

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

Bekerja pada proyek pribadi

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

Dengan begitu, ketika Anda akhirnya mendorong pekerjaan Anda di github, itu tidak akan terlihat konyol dalam tampilan kode 8 space tabsyang merupakan perilaku default di semua browser.

Berkontribusi ke proyek lain

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

Dengan begitu Anda dapat bekerja dengan tab normal pada 2 space indentedproyek.

Tentu saja Anda dapat menulis solusi serupa untuk mengkonversi dari 4 space to 2 spaceyang terjadi jika Anda ingin berkontribusi pada proyek yang diterbitkan oleh saya dan Anda cenderung menggunakan 2 spasi saat mengembangkan.

simo
sumber
2
Terkait: Menyimpan git config sebagai bagian dari repositori ; juga perhatikan Anda dapat menggunakan (dan melakukan) .gitattributesfile dalam repo Anda
Tobias Kienzler
1

Jika Anda menggunakan windows maka Anda memiliki beberapa langkah tambahan untuk mendapatkan solusi @Olivier Verdier agar berfungsi.

  1. Unduh CoreUtils untuk windows
  2. Setelah menginstal, letakkan lokasi instal di PATH Anda ( Cara menambahkan variabel path )
  3. Saya mengganti nama expand.exe menjadi gexpand.exe karena sudah ada utilitas jendela perbesar.
sumpah
sumber