Git filtre-dalıyla satır sonlarını düzeltmeye çalışıyor, ancak şansı yok


270

Git ile ilgili Windows / Linux satır sonu sorunu tarafından ısırıldı. En iyi çözüm yolu yerel repo kullanımı linux tarzı satır sonları ayarlanır, ancak ayarlanmış olması olduğunu, GitHub, MSysGit ve diğer kaynaklar yoluyla, görünüyor core.autocrlfiçin true. Ne yazık ki, bunu yeterince erken yapmadım, bu yüzden şimdi her değişiklik yaptığımda satır sonları doludur.

Burada bir cevap bulduğumu sanıyordum ama benim için çalışmasını sağlayamıyorum. Linux komut satırı bilgim en iyi şekilde sınırlıdır, bu yüzden komut dosyasında "xargs fromdos" satırının ne yaptığından bile emin değilim. Bu tür bir dosya veya dizin hakkında ileti almaya devam ediyorum ve varolan bir dizine yönlendirmeyi başardığımda izinlerim olmadığını söylüyor.

Bunu Windows'ta MSysGit ve Mac OS X terminali ile denedim.


Bu konuyu neredeyse yeterince değerlendiremiyorum. +1 ++ bunun için en iyi cevabı veriyor.
sjas

Charles ile aynı fikirde. Ancak, benim durumumda (Mac OS X 10.8 kullanarak)> git config core.autocrlf false çalıştı, değil> git config core.autocrlf giriş
user1045085 4:13

Yanıtlar:


187

Gitattributes için git belgeleri artık projenizdeki tüm satır sonlarını "düzeltmek" veya normalleştirmek için başka bir yaklaşımı belgelemektedir. İşte özü:

$ echo "* text=auto" >.gitattributes
$ git add --renormalize .
$ git status        # Show files that will be normalized
$ git commit -m "Introduce end-of-line normalization"

Normalleştirilmesi gerekmeyen dosyalar git durumunda görünüyorsa, git add -u komutunu çalıştırmadan önce metin özniteliklerini kaldırın.

manual.pdf -text

Tersine, git'in algılamadığı metin dosyalarında normalleştirme manuel olarak etkinleştirilebilir.

weirdchars.txt text

Bu --renormalize, Ocak 2018'de yayınlanan git v2.16.0'da eklenen yeni bir bayraktan yararlanır. Git'in eski sürümleri için birkaç adım daha vardır:

$ echo "* text=auto" >>.gitattributes
$ rm .git/index     # Remove the index to force git to
$ git reset         # re-scan the working directory
$ git status        # Show files that will be normalized
$ git add -u
$ git add .gitattributes
$ git commit -m "Introduce end-of-line normalization"

1
Bana bunun amacının ne olduğunu söyler misiniz git resetlütfen?
crdx

1
git'i dizini yeniden oluşturmaya zorlar; bu sırada her dosyayı ikili olup olmadığını tahmin etmek için tarar. RM eski dizini siler, reset yeni dizini oluşturur.
Russ Egan

16
Teşekkürler, bu benim için çalıştı. git statusÇalıştırdıktan sonra yararlı bir komut git diff --ignore-space-at-eol, yalnızca yaptığınız değişikliklerin satır sonları olduğundan emin olmak için çalıştırmaktır .
zelanix

1
Not: Bu ve "eski" çözüm arasındaki tek "gerçek" fark .gitattributes (uygun içerikle) varlığındadır. Bu olmadan, git resethiçbir değişiklik tespit etmez ve bu nedenle işe yaramaz.
Rob

3
Talimatları gitattributes sayfanın yararlanmak için güncellendi --renormalizeOcak 2018 yılında piyasaya sürüldü git v2.16.0 eklenen bayrağı --renormalizebayrak, tek komutla her bir paletli dosya için yeniden işleme satır sonları sürecini birleştirir: git add --renormalize ..
Mike Hill

389

Bunu düzeltmenin en kolay yolu, tüm satır sonlarını sabitleyen bir taahhüt yapmaktır. Değiştirilmiş dosyanızın olmadığı varsayılarak, bunu aşağıdaki gibi yapabilirsiniz.

# From the root of your repository remove everything from the index
git rm --cached -r .

# Change the autocrlf setting of the repository (you may want 
#  to use true on windows):
git config core.autocrlf input

# Re-add all the deleted files to the index
# (You should get lots of messages like:
#   warning: CRLF will be replaced by LF in <file>.)
git diff --cached --name-only -z | xargs -0 git add

# Commit
git commit -m "Fixed crlf issue"

# If you're doing this on a Unix/Mac OSX clone then optionally remove
# the working tree and re-check everything out with the correct line endings.
git ls-files -z | xargs -0 rm
git checkout .

7
PS Ben github.com çocuklar düzeltmek için tavsiye ve onlar çözümünü kullanmak için onların yardım kılavuzu güncelledi (daha önce sadece taze bir klon ve tüm dosyaları almak gibi görünmüyordu bir sert sıfırlama tavsiye vardı.) Help.github. com / line-dealendings
Brian Donahue

31
Teşekkürler ... bu harika bir düzeltme. GitHub'da buldum.
PHLAK

4
Metin olmayan dosyalarda (ikili gibi) crlfs'yi değiştirmediğinizden emin olmak için config.safecrlf dosyasını da kontrol etmek isteyebilirsiniz. Bunu kernel.org/pub/software/scm/git/docs/git-config.html adresinde bulabilirsiniz .
vrish88

4
@ vrish88: Bu durumdaysanız, karışık çizgili sonlardan ve core'dan muzdarip olmanız muhtemeldir. safecrlf aslında yapmanız gerekeni yapmanıza engel olabilir. Safecrlf kullanmamak daha kolaydır. git genellikle ikili dosya algılamayı yanlış almaz ve eğer yaparsa, bir .gitattribute ile manuel olarak ikili olarak işaretleyebilir ve önceki işlemden doğru sürümü kurtarabilirsiniz.
CB Bailey

26
Aşağıdaki Russ Egan'ın cevabında önerilen yeni çözüm daha basittir ve tüm kaynak kodunuzu silmek gibi korkunç şeyleri içermez , bu yüzden bu eski çözümün 10 kat fazla oyu olmasına rağmen, insanların bunu kullanmasını gerçekten tavsiye ederim!
Porculus

11

Satır sonlarıyla başa çıkma prosedürüm aşağıdaki gibidir (birçok depoda savaş test edildi):

Yeni bir repo oluştururken:

  • .gitattributesve diğer tipik dosyalarla birlikte ilk taahhüdü koymak .gitignoreveREADME.md

Mevcut bir repo ile uğraşırken:

  • Buna .gitattributesgöre oluştur / değiştir
  • git commit -a -m "Modified gitattributes"
  • git rm --cached -r . && git reset --hard && git commit -a -m 'Normalize CRLF' -n"
    • -n( --no-verifyön işleme kancalarını atlamaktır)
    • Bunu bir takma ad olarak tanımlayabileceğim kadar sık ​​yapmalıyım alias fixCRLF="..."
  • önceki komutu tekrarla
    • evet, bu voodoo, ama genellikle komutu iki kez çalıştırmak zorundayım, ilk kez bazı dosyaları normalleştirdiğinde, ikinci kez daha fazla dosya. Genellikle yeni bir taahhüt oluşturulmadan tekrarlamak en iyisidir :)
  • eski (normalizasyondan hemen önce) ve yeni dal arasında birkaç kez ileri geri gidin. Şubeyi değiştirdikten sonra, bazen git yeniden düzenlenmesi gereken daha fazla dosya bulur!

In .gitattributesben LF EOL sahip olarak açıkça tüm metin dosyaları beyan beri genel olarak, Windows kalıp Windows olmayan takım CRLF ile uyumlu değilken LF ile uyumludur (hatta birçok nodejs hat araçları LF varsayar ve dolayısıyla Dosyalarınızdaki EOL değiştirebilir komutu).

İçeriği .gitattributes

Benim .gitattributesgenellikle şöyle görünür:

*.html eol=lf
*.js   eol=lf
*.json eol=lf
*.less eol=lf
*.md   eol=lf
*.svg  eol=lf
*.xml  eol=lf

Geçerli repoda git tarafından hangi farklı uzantıların izlendiğini anlamak için buraya bakın

Normalizasyondan sonraki sorunlar

Bu yapıldıktan sonra, ortak bir uyarı daha var.

Diyelim ki masterzaten güncel ve normalleştirilmiş ve sonra ödeme outdated-branch. Bu dalı kontrol ettikten hemen sonra, git birçok dosyayı değiştirilmiş olarak işaretler.

Çözüm sahte bir taahhüt ( git add -A . && git commit -m 'fake commit') yapmak ve sonra git rebase master. Rebase'den sonra, sahte taahhüt ortadan kalkmalıdır.


1
Gönderinizi okuyana kadar delirdiğimi sanıyordum, çünkü belirtilen komut dizisini birkaç kez de çalıştırmak zorunda kaldım. Voodoo! ;)
Sean Fausett

Git sürümünde 2.7.0.windows.1aşağıdakileri kullandım:git rm --cached -r . && git reset --hard && git add . && git commit -m "Normalize EOL" -n
Sean Fausett

4
git status --short|grep "^ *M"|awk '{print $2}'|xargs fromdos

Açıklama:

  • git status --short

    Bu, git'in farkında olduğu ve farkında olmadığı her satırı görüntüler. Git kontrolü altında olmayan dosyalar satırın başında '?' İle işaretlenir. Değiştirilen dosyalar bir M ile işaretlenir.

  • grep "^ *M"

    Bu yalnızca değiştirilmiş dosyaları filtreler.

  • awk '{print $2}'

    Bu, yalnızca işaretçisi olmayan dosya adını gösterir.

  • xargs fromdos

    Bu, dosya adlarını önceki komuttan alır ve bunları satır sonlarını dönüştürmek için 'fromdos' yardımcı programı aracılığıyla çalıştırır.


Bu harika. Teşekkür ederim. Homebrew kullanarak çözüm arayan herkes dos2unixyerine kullanın fromdos.
Almir Sarajčić


3

"| Xargs fromdos", standart girdiden (dosyalar findbulur) okur ve bunu fromdossatır sonlarını dönüştüren komut için bağımsız değişken olarak kullanır . (Bu ortamda fromdos standart mı? Dos2unix için alışkınım). Xargs kullanmaktan kaçınabileceğinizi unutmayın (özellikle argüman listesinin xargs için çok uzun olmasına yetecek kadar dosyanız varsa):

find <path, tests...> -exec fromdos '{}' \;

veya

find <path, tests...> | while read file; do fromdos $file; done

Hata mesajlarınızdan tam olarak emin değilim. Bu yöntemi başarıyla test ettim. Her biri hangi programı üretiyor? Hangi dosyalar / dizinler için izniniz yok? Ancak, bunun ne olabileceğini tahmin etme konusunda bir bıçak:

Komut dosyası için 'dosya bulunamadı' hatası almanın kolay bir yolu, göreli bir yol kullanmaktır - mutlak olanı kullanın. Benzer şekilde komut dosyanızı çalıştırılabilir hale getirmediyseniz (chmod + x) bir izin hatası alabilirsiniz.

Yorum ekleyin, ben de çalışmanıza yardımcı olacağım!


Dos2unix ile başka bir örnek gördüm ve bunun bir şekilde dosyaları adlı bir klasöre kopyalamak olduğunu düşündüm, ama şimdi anladım. Vay, şimdi belli görünüyor. Yardımınız için teşekkürler!
Brian Donahue

1

tamam ... cygwin altında biz fromdos kolayca mevcut değildir ve değiştirilmiş dosyalara (ki biz vardı) yollarda herhangi bir boşluk varsa, bu awk subeb yüzünüzde patlar, bu yüzden bunu biraz farklı yapmak zorunda kaldı:

git status --short | grep "^ *M" | sed 's/^ *M//' | xargs -n 1 dos2unix

bu çözümün büyük kısmı için @lloyd için kudos


-2

Başka yanıtların hiçbiri işe yaramazsa şu adımları izleyin:

  1. Windows işletim sistemindeyseniz git config --global core.autocrlf true; Unix'deyseniz,git config core.autocrlf input
  2. Çalıştırmak git rm --cached -r .
  3. Dosyayı sil .gitattributes
  4. Çalıştırmak git add -A
  5. Çalıştırmak git reset --hard

O zaman yerel artık temiz olmalı.


4
Gerçekten mi? .gitattributesDosya silme , satır sonları sorununa çözüm mü?
Aleksandr M

Evet lütfen @AleksandrM tarafından yazılan adrese hitap edin
Mr_and_Mrs_D
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.