Menulis ulang riwayat git untuk mengganti semua CRLF ke LF?
32
Saya akan mentransfer repositori Git pribadi dari kotak win32 ke Ubuntu. Walaupun saya dapat melakukan commit dos2unix terakhir, tetapi saya ingin menulis ulang seluruh sejarah, sehingga beberapa Git GUI akan menampilkan log / diff dengan benar. Misalnya, gitg akan menyisipkan baris kosong untuk setiap CR / LF.
Rewrite df4970f63e3196216d5986463f239e51eebb4014 (1/1)dos2unix: converting file testfile to Unix format ...
Ref 'refs/heads/master' was rewritten
$ hexdump -C testfile
00000000 61 0a 62 0a 63 0a |a.b.c.|
00000006
Saya sangat menyarankan untuk melakukan full backup terlebih dahulu . Menjalankan itu dari mesin Linux Anda (kecuali Anda memiliki set up shell yang baik di lingkungan windows Anda) mungkin lebih mudah.
Terima kasih, posting ini banyak membantu saya. Aku punya beberapa file dengan spasi di nama mereka, sedikit perubahan untuk perintah asli tetap itu: git filter-branch --tree-filter 'git ls-files -z | xargs -0 dos2unix' -- --all. Bendera -zdan -0memberitahu git ls-filesdan xargsuntuk mencetak dan menafsirkan nullsebagai akhir baris.
Ivan
Alternatif lain untuk perintah dos2unix adalah mengandalkan git itu sendiri:git filter-branch --prune-empty --tree-filter 'git add --renormalize .' -- --all
Vilmantas Baranauskas
6
Jawaban Mat telah mengatasi masalah ini tepat di kepala. Sayangnya di Ubuntu Linux, dimulai dengan versi 10.04 (Lucid Lynx), perintah dos2unix / unix2dos tidak lagi tersedia, dan telah digantikan oleh fromdos / todos. Selain itu, kedua set perintah konversi memiliki berbagai tingkat ketidaktahuan terhadap keberadaan file biner, sehingga jika repositori Anda berisi gambar, font, dll. Mereka akan rusak oleh proses ini.
Saya dapat menemukan solusi untuk masalah korupsi file biner yang menggunakan perintah 'file' Linux untuk mengidentifikasi dan memproses hanya file teks dengan benar seperti yang ditunjukkan di bawah ini. Perintah di bawah ini menggunakan opsi --tag-name-filter untuk mempertahankan tag yang ada dengan memindahkannya ke commit yang baru diubah. Juga menggunakan --force flag untuk memastikan bahwa perintah akan berfungsi jika Anda menjalankan tree-filter pada repositori Anda sebelumnya.
Crossplatform (OS X, FreeBSD, Linux) analog yang berguna 'fromdos', 'dos2unix':
sed -i'' -e 's/'"$(printf '\015')"'$//'
Mungkin berguna 'unix2dos':
sed -i '' -e 's|$|'"`printf '\015'`"'|' file.name
Jika Anda benar-benar memastikan apa yang Anda lakukan, Anda dapat menggunakan perintah inline sederhana ini untuk menghapus "/ r" dari semua file di direktori saat ini ".":
find . -type f -exec sed -i'' -e 's/'"$(printf '\015')"'$//' {} \;
git filter-branch --tree-filter 'git ls-files -z | xargs -0 dos2unix' -- --all
. Bendera-z
dan-0
memberitahugit ls-files
danxargs
untuk mencetak dan menafsirkannull
sebagai akhir baris.git filter-branch --prune-empty --tree-filter 'git add --renormalize .' -- --all
Jawaban Mat telah mengatasi masalah ini tepat di kepala. Sayangnya di Ubuntu Linux, dimulai dengan versi 10.04 (Lucid Lynx), perintah dos2unix / unix2dos tidak lagi tersedia, dan telah digantikan oleh fromdos / todos. Selain itu, kedua set perintah konversi memiliki berbagai tingkat ketidaktahuan terhadap keberadaan file biner, sehingga jika repositori Anda berisi gambar, font, dll. Mereka akan rusak oleh proses ini.
Saya dapat menemukan solusi untuk masalah korupsi file biner yang menggunakan perintah 'file' Linux untuk mengidentifikasi dan memproses hanya file teks dengan benar seperti yang ditunjukkan di bawah ini. Perintah di bawah ini menggunakan opsi --tag-name-filter untuk mempertahankan tag yang ada dengan memindahkannya ke commit yang baru diubah. Juga menggunakan --force flag untuk memastikan bahwa perintah akan berfungsi jika Anda menjalankan tree-filter pada repositori Anda sebelumnya.
sumber
Dan tanpa alat tambahan apa pun (seperti 'fromdos', 'dos2unix', dll.):
Crossplatform (OS X, FreeBSD, Linux) analog yang berguna 'fromdos', 'dos2unix':
Mungkin berguna 'unix2dos':
Jika Anda benar-benar memastikan apa yang Anda lakukan, Anda dapat menggunakan perintah inline sederhana ini untuk menghapus "/ r" dari semua file di direktori saat ini ".":
sumber
sed
doa yang sesuai dapat diganti dengan yang lebih pendek:sed -n -e "s/\(.*\): .*text.*/\1/p"