görmemek için git-diff ^ M


474

Bazı dosyaların yeni satır ayırıcıları olarak ^ M içerdiği bir projede. Git-diff dosyayı tek bir satır olarak gördüğünden, bu dosyaları dağıtmak imkansızdır.

Bir önceki versiyona göre farkı nedir?

"Farklı olduğunda ^ M'yi yeni satır olarak ele al" gibi bir seçenek var mı?

prompt> git-diff "HEAD^" -- MyFile.as 
diff --git a/myproject/MyFile.as b/myproject/MyFile.as
index be78321..a393ba3 100644
--- a/myproject/MyFile.cpp
+++ b/myproject/MyFile.cpp
@@ -1 +1 @@
-<U+FEFF>import flash.events.MouseEvent;^Mimport mx.controls.*;^Mimport mx.utils.Delegate
\ No newline at end of file
+<U+FEFF>import flash.events.MouseEvent;^Mimport mx.controls.*;^Mimport mx.utils.Delegate
\ No newline at end of file
prompt>

GÜNCELLEME:

şimdi en son 10 revizyonu kontrol eden ve CR'yi LF'ye dönüştüren bir Ruby senaryosu yazdım.

require 'fileutils'

if ARGV.size != 3
  puts "a git-path must be provided"
  puts "a filename must be provided"
  puts "a result-dir must be provided"
  puts "example:"
  puts "ruby gitcrdiff.rb project/dir1/dir2/dir3/ SomeFile.cpp tmp_somefile"
  exit(1)
end

gitpath = ARGV[0]
filename = ARGV[1]
resultdir = ARGV[2]

unless FileTest.exist?(".git")
  puts "this command must be run in the same dir as where .git resides"
  exit(1)
end

if FileTest.exist?(resultdir)
  puts "the result dir must not exist"
  exit(1)
end
FileUtils.mkdir(resultdir)

10.times do |i|
  revision = "^" * i
  cmd = "git show HEAD#{revision}:#{gitpath}#{filename} | tr '\\r' '\\n' > #{resultdir}/#{filename}_rev#{i}"
  puts cmd 
  system cmd
end

7
isteyebilirsiniz git diff -b- Bunu stackoverflow.com/a/46265081/58794
Jason Pyeron

6
Git 2.16 (1. Çeyrek 2018) ile sahip olacaksınız git diff --ignore-cr-at-eol. Bkz aşağıda Cevabımı .
VonC

7
@ JasonPyeron ve gelecekteki Google çalışanları için: Bunun git diff -baynısını aramak zorunda kaldım git diff --ignore-space-change.
Gogowitsch

Yanıtlar:


392

GitHub, git işlenen depolarda \ n karakterini yeni satır karakteri olarak kullandığınızdan emin olmanızı önerir . Otomatik dönüştürme seçeneği vardır:

$ git config --global core.autocrlf true

Tabii ki, bu crlf lf dönüştürmek için söylenirken, cr lf dönüştürmek istiyorum. Umarım bu hala işe yarar ...

Ve sonra dosyalarınızı dönüştürün:

# Remove everything from the index
$ git rm --cached -r .

# 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 "Fix CRLF"

core.autocrlf kılavuz sayfasında açıklanmıştır .


1
Hayır, elbette hayır, ayar bir kez orada olduğunda, sessizce taahhüt üzerine dönüşecektir. Her şey düşündüğüm şekilde çalışıyorsa, bu…
nes1983

1
Sorun zaten depoda CRLF sonları olan bazı dosyalar ve diğerleri değil olmasıdır. Mac sürümünü kullanmama rağmen Adobe Flash'ın CRLF eklediğinden şüpheleniyorum. Bu dosyaların eski sürümleriyle karşılaştırmam gerekiyor. Bundan sonra başlayan satır sonlarını dönüştürmek, eski revizyonlarla ilgili sorunu çözmez: - /
neoneye

65
Burada CRLF dosyalarıyla çalışmıyorsunuz, en azından yayınladığınız örnekte değil. Bu eski tarz bir mac dosyası (sadece EOL için \ r kullanır). Bu yüzden fark bir satırda gösteriliyor. Dos EOL kullanan bir dosya, her satırı ayrı ayrı ele almak için söyleyebileceğiniz bir ^ M ile gösterecektir git config core.whitespace cr-at-eol.
jamessan

12
Bunu deniyorum, ama warning: LF will be replaced by CRLFonun yerine almaya devam warning: CRLF will be replaced by LFediyorum ve Linux'tayım. Neden olduğu hakkında bir fikrin var mı? Herkesin LRL ile bitmesini istiyorum, CRLF ile değil!
trusktr

5
@trusktr, benim için de aynısı oldu. Linux'ta, yanlışlıkla CRLF ile kullanın git config --global core.autocrlf input, bu yanıttaki adımları uygulayın (rm, add, kesinleştirme) ve elde edersiniz warning: CRLF will be replaced by LF. The file will have its original line endings in your working directory.. Dosyaları kaldırın (orijinal, yanlış CRLF'ye sahip oldukları için) ve son "Fix CRLF" işleminden tekrar teslim alın.
jmmut

370

Windows üzerinde geliştirirken, kullanırken bu sorunla karşılaştım git tfs. Bu şekilde çözdüm:

git config --global core.whitespace cr-at-eol

Bu, Git'e satır sonu CR'sinin bir hata olmadığını bildirir. Sonuç olarak, bu can sıkıcı ^Mkarakterler artık satırların sonunda görünür git diff, git showvb

Diğer ayarları olduğu gibi bırakır; örneğin, bir satırın sonundaki fazladan boşluklar farkta hala hatalar (kırmızı ile vurgulanmış) olarak gösterilir.

(Buna başka cevaplar da verilmiştir, ancak yukarıdaki ayarın tam olarak nasıl yapılacağıdır. Yalnızca bir proje için ayarı yapmak için --global.

DÜZENLE :

Birçok satır sonu travails sonra, bir .NET ekibi üzerinde çalışırken, bu ayarlarla en iyi şansı elde ettim:

  • NO core.eol ayarı
  • NO çekirdek. Beyaz ayarı
  • NO core.autocrlf ayarı
  • Windows için Git yükleyicisini çalıştırırken şu üç seçeneği elde edersiniz:
    • Windows tarzı ödeme yapın, Unix tarzı satır sonlarını tamamlayın <- bunu seçin
    • Olduğu gibi ödeme yapın, Unix stili satır sonları verin
    • Olduğu gibi ödeme yapın, olduğu gibi taahhüt edin

Boşluk ayarını kullanmanız gerekiyorsa, muhtemelen TFS ile etkileşime girmeniz gerekiyorsa proje başına temelinde etkinleştirmeniz gerekir. Sadece atlayın --global:

git config core.whitespace cr-at-eol

Bazı core. * Ayarlarını kaldırmanız gerekiyorsa, en kolay yol bu komutu çalıştırmaktır:

git config --global -e

Bu, global .gitconfig dosyanızı bir metin düzenleyicisinde açar ve kaldırmak istediğiniz satırları kolayca silebilirsiniz. (Ya da yorum yapmak için önüne '#' koyabilirsiniz.)


30
Bunu şimdi bulanlar için, Checkout Windows stili, Unix stili satır sonlarının otomatik olarak ayarlandığını core.autocrlfbelirtmek gerekirtrue
K. Carpenter

14
Satırın git config --global core.whitespace cr-at-eolvarsayılan diğer ayarları kapatacağını unutmayın. Üç varsayılan değer vardır: eol'de boşluk, eof'de boşluk ve sekmeden önce boşluk. Bu nedenle, diğerlerini tutarken cr-at-eol'yi etkinleştirmek için kullanmanız gerekir git config --global core.whitespace blank-at-eol,blank-at-eof,space-before-tab,cr-at-eol.
Zitrax

2
Projem için (Windows'ta ödeme yapıldı ve Linux'ta izliyorum), satırların sonunda cr-at-eolkurtuldum , ancak GIT bu satırları farklı olarak gösterdi, ancak satır sonu tek farktı. ^Mgit diff
Jānis Elmeris

SourceInsight ^ M karakterini itmeye devam ediyor ve git yine de satır sonlarındaki farkı gösteriyor. @ Zitrax'in komutu benim durumum için doğru cevap, git diff show güzel ve temiz çıktı.
Lê Quang Duy

3
Bence git biraz daha karmaşık, satır sonu için birkaç çelişkili ayar gerekiyor. Bence git boşluklarım hakkında daha fazla endişelenmeli. Örneğin, ilgisiz bir ölümcül hata atın ve bir Windows (Linux değil) makinesinde Mac satır sonlarıyla karşılaştığınızda depoyu bozuk bir durumda bırakın. Demek istediğim, neden işine bakacak ve istediğim satır sonlarını kullanmama izin verecek bir VCS kullanayım? Deniyorlar, ama var olmayan bir sorunu çözmek için yarım düzine daha fazla satır sonu davranışları atmalılar. Neredeyse oradalar! Aynen böyle devam.
Rolf

125

Deneyin git diff --ignore-space-at-eol, veya git diff --ignore-space-change, veya git diff --ignore-all-space.


22
Bunların hiçbiri yeni satırı tanımlayan karakteri gerçekten etkilemez.
nes1983

4
Ben de "-w" ile denedim ama hiçbir şans, hala tek bir satır olarak davranır. Bir sonraki proje, kaynak koduna hiç CR almamayı hatırlamalıyım.
neoneye

3
Sadece git config hatırla - global core.autocrlf doğru veya git millet varsayılan yapmak kadar böcek :)
nes1983

10
Bu, autocrlfayarlarımı değiştirmek zorunda kalmadan sorunumu çözdü . Teşekkürler!
nneonneo

11
Bu bayrakların benim için bir etkisi yok ... Hala ^ M'yi diffs olarak gösteriyor
Magnus

103

Ayrıca bakınız:

core.whitespace = cr-at-eol

Veya eşdeğer olarak,

[core]
    whitespace = cr-at-eol

Nerede whitespacebir öncesinde sekme karakteri.


4
Evet, bu git fark aracı (ayrıca kullanılan git show) ^Mdeğiştirilen satırlarda s hakkında beni rahatsız etmeyi bıraktı ! :)
Rijk

2
nedense bu benim için işe yaramadı. Hem = hem de no = işaretiyle denedim. git diffhala ^ M karakter gösteriyor.
Dennis

6
Bunu yapmanın iki yolu: bir, yukarıdaki satırı .gitconfig dosyasına .git / config veya ~ / .gitconfig biçiminde ekleyin; iki, git config --global core.whitespace cr-at-eol(burada --global, sadece bulunduğunuz repoda istiyorsanız isteğe bağlıdır)
K. Carpenter

Windows 7'de bu benim için çalıştı, ancak öneki bir TAB karakteriyle [core]değiştirebilmem için altına koymuştum core..
Rufflewind

Bu soru nasıl gizlemek üzerindeydi ^Miçinde git diffdeğil ilk etapta M ^ koymak değil hakkında. Bu, değiştirmenin kabul edilen cevabının core.autocrlfen iyisi olmadığı anlamına gelir, çünkü kullanıcının onayı olmadan dosyaları sessizce değiştirir.
deddebme

45

Bunları neden alabilirim ^MGözlerinde farklı git diff?

Benim durumumda Windows'da geliştirilen bir proje üzerinde çalışıyordum ve OS X kullandım. Bazı kodları değiştirdiğimde, ^Meklediğim satırların sonunda gördüm git diff. Bence ^Monlar dosyanın geri kalanından farklı satır sonları çünkü görünüyordu. Dosyanın geri kalanı Windows'da geliştirildiğinden CRsatır sonlarını ve OS X'te LFsatır sonlarını kullanır .

Görünüşe göre, Windows geliştiricisi Git'in yüklenmesi sırasında " Windows stili, Unix stili satır sonlarını teslim et " seçeneğini kullanmadı .

Peki bu konuda ne yapmalıyız?

Windows kullanıcılarının git'i yeniden yüklemelerini ve " Windows stili, Unix stili satır sonlarını tamamla " seçeneğini kullanmalarını sağlayabilirsiniz . Bunu tercih ederim, çünkü Windows'u satır sonu karakterlerinde bir istisna olarak görüyorum ve Windows kendi sorununu bu şekilde düzeltiyor.

Bu seçeneğe giderseniz, geçerli dosyaları düzeltmelisiniz (çünkü bunlar hala CRsatır sonlarını kullanıyorlar ). Bunu şu adımları izleyerek yaptım:

  1. Depodaki tüm dosyaları kaldırın, ancak dosya sisteminizden kaldırmayın.

    git rm --cached -r .
    
  2. Satır sonları olarak .gitattributeskullanmak için belirli dosyaları zorlayan bir dosya ekleyin LF. Bunu dosyaya koyun:

    *.ext text eol=crlf
    

    .extEşleştirmek istediğiniz dosya uzantılarıyla değiştirin .

  3. Tüm dosyaları tekrar ekleyin.

    git add .
    

    Bu, aşağıdaki gibi mesajları gösterecektir:

    warning: CRLF will be replaced by LF in <filename>.
    The file will have its original line endings in your working directory.
    
  4. .gitattributes" Windows stili, Unix stili satır sonlarını onayla " seçeneğini kullanmak istemeyen inatçı Windows kullanıcılarınız yoksa dosyayı kaldırabilirsiniz .

  5. Tamamlayın ve her şeyi itin.

  6. Kullanıldıkları tüm sistemlerde geçerli dosyaları kaldırın ve teslim alın. Windows sistemlerinde, şimdi " Windows stili, Unix stili satır sonlarını tamamla " seçeneğini kullandıklarından emin olun . Ayrıca, bu görevleri yürüttüğünüz sistemde de yapmanız gerekir, çünkü dosyaları eklediğinizde git dedi:

    The file will have its original line endings in your working directory.
    

    Dosyaları kaldırmak için böyle bir şey yapabilirsiniz:

    git ls | grep ".ext$" | xargs rm -f
    

    Ve sonra bunları doğru satır sonlarıyla geri almak için:

    git ls | grep ".ext$" | xargs git checkout
    

    Tabii ki .extistediğiniz uzantı ile değiştirmek .

Artık projeniz yalnızca LFsatır sonları için karakterler kullanıyor ve kötü CRkarakterler bir daha geri gelmeyecek :).

Diğer seçenek, Windows stili satır sonlarını zorlamaktır. .gitattributesDosyayı bunun için de kullanabilirsiniz .

Daha fazla bilgi: https://help.github.com/articles/dealing-with-line-endings/#platform-all


4
Belirli bir dosyadaki tüm satır sonlarını düzeltmek için, Yüce Metin kullanıyorsanız View-> ' Line Endingsya gidebilir ve üzerine tıklayabilirsiniz Unix.
Topher Hunt

Bu tam olarak ne anlama ^Mgeliyor? Bir pencere veya linux satırsonu mu? Yoksa dosyadaki diğer satırlara kıyasla sadece "farklı" bir satırsonu mu?
buhtz

İyi bir şey, bence bu sadece "farklı" bir yeni satır (diğerlerinden farklı)
gitaarik

-1, gitmesi için git config --global core.autocrlf truegit'i yeniden yüklemek aşırıya kaçıyor ve Windows karşıtı / CRkampanya karşıtı soruya teğet görünüyor.
RJFalconer

41

"Farklı olduğunda ^ M'yi yeni satır olarak ele al" gibi bir seçenek var mı?

Git 2.16'da (1. Çeyrek 2018) bir tane olacak diff.

Junio ​​C Hamano ( ) tarafından taahhüt edilen e9282f0 (26 Ekim 2017) bölümüne bakınız . Yardım eden: Johannes Schindelin ( ) . (Göre Birleştirilmiş - Junio Cı Hamano - içinde 10f65c2 tamamlama 2017 27 Eki)gitster
dscho
gitster

diff: --ignore-cr-at-eol

Yeni bir seçenek --ignore-cr-at-eol, diff makinesine, (tam) bir hattın sonunda bir satır-dönüşü yokmuş gibi davranmasını söyler.

Diğer --ignore-*beyaz boşluk farklarını yoksaymak gibi diğer " " seçenekler gibi , bu da CRLF<->LFeditör programınız tarafından yapılan sahte dönüşümün dikkatini dağıtmadan yaptığınız gerçek değişiklikleri gözden geçirmenize yardımcı olacaktır .


@kaartic Cevabı düzenlediğiniz ve doğru taahhütte bulunduğunuz için teşekkür ederiz!
VonC

3
git config --global core.autocrlf trueKabul edilen cevapta olduğu gibi ayarlamak genellikle iyi bir uygulama olmakla birlikte , bu OP'nin sorusuna daha doğrudan cevap verir: 'Farklılık sırasında ^ M'ye yeni satır olarak davran' gibi bir seçenek var mı? '
drkvogel

1
Git 2.20 itibariyle ^ M
user1944491

@ user1944491 Herhangi bir gerileme fark etmedim, yani eşik Git 2.26'da bu seçenekle farklılık gösterdiğinde eol'ü yok sayar.
VonC

@VonC git diff komutunda bu bağımsız değişkeni kullanmak işe yaramadı. Ne de core.whitespace değerimi ayarladım git version 2.20.1 (Apple Git-117)ama Jason Pyeron'un core.pager cevabını ekledi. Açıkça YMMV.
user1944491

26

TL; DR

Değişim core.pageriçin "tr -d '\r' | less -REX"değil, kaynak kodu

Bu nedenle

Gösterilen bu sinir bozucu ^ M renklendirme ve çağrı cihazının bir eseridir. resim açıklamasını buraya girin Bunun nedeni less -R, varsayılan bir git çağrı cihazı seçeneğidir. (GIT varsayılan çağrı cihazı olan less -REX)

Dikkat edilmesi gereken ilk şey git diff -b, beyaz boşlukta değişiklik gösterilmeyecek olmasıdır (örneğin, \ r \ n vs \ n)

kurmak:

git clone https://github.com/CipherShed/CipherShed
cd CipherShed

Unix dosyası oluşturmak ve satır sonlarını değiştirmek için yapılan hızlı bir test aşağıdakilerle hiçbir değişiklik göstermez git diff -b:

echo -e 'The quick brown fox\njumped over the lazy\ndogs.' > test.txt
git add test.txt
unix2dos.exe test.txt
git diff -b test.txt

Bir boruyu daha azına zorlamanın ^ M'yi göstermediğini, rengi etkinleştirdiğini ve less -Rşunları yaptığını not ediyoruz :

git diff origin/v0.7.4.0 origin/v0.7.4.1 | less
git -c color.ui=always diff origin/v0.7.4.0 origin/v0.7.4.1 | less -R

Düzeltme, çıkıştan \ r (^ M) çıkarmak için bir boru kullanılarak gösterilir:

git diff origin/v0.7.4.0 origin/v0.7.4.1
git -c core.pager="tr -d '\r' | less -REX"  diff origin/v0.7.4.0 origin/v0.7.4.1

Akıllı olmayan bir alternatif kullanmaktır less -r, çünkü sadece renk kodlarını değil tüm kontrol kodlarını geçecektir.

Git yapılandırma dosyanızı doğrudan düzenlemek istiyorsanız, bu güncelleme / ekleme girişi:

[core]
        pager = tr -d '\\r' | less -REX

Bazı dosyaları \r\nsatır sonları ve bazı \nsatır sonları vardı (bu alakalı olup olmadığını bilmiyorum ) bir repo bu sorunu vardı ; öncekinin diffs'si ^Mdeğiştirilmiş çizgilerde (yani +çizgilerde) gösterdi. core.autocrlfolarak ayarlandı true. Koşmak git config core.pager "tr -d '\r' | less -REX"sinir bozucu ^Ms kurtuldu . Teşekkürler!
labreuer

5
Bunun için teşekkürler. Repo (ları) nızda farklı satır sonlarıyla çalışmanız gerektiğinde tek yanıt budur - örneğin, kasayı olduğu gibi kullanın, olduğu gibi taahhüt edin.
Mike

git diff -baradığım şeydi, ancak ayrıntılı açıklamayı takdir ediyorum.
Martin Burch

Cevap bu! Teşekkür ederim. -b bayrağı benim için çalışmadı.
Chris

Evet! Bu sorunun tüm cevapları arasında, git "config" dosyasının [core]bölümünü ekleyerek değiştirmek pager = tr -d '\\r' | less -REXbenim için çalışan tek cevaptı. Teşekkür ederim!
Rashiki

13

Bu sorunla uzun süre mücadele ettim. Şimdiye kadar en kolay çözüm, ^ M karakterleri hakkında endişelenmemek ve sadece bunları işleyebilen görsel bir fark aracı kullanmaktır.

Yazmak yerine:

git diff <commitHash> <filename>

Deneyin:

git difftool <commitHash> <filename>

1
Teşekkürler! Ayrıca ben sadece "git difftool" koştu ve temelde bir döngüde tüm değişen dosyaları karşılaştırdı
Bhanuprakash D


2

VonC tarafından belirtildiği gibi, bu zaten git 2.16+ içine dahil edilmiştir. Ne yazık ki, ( --ignore-cr-at-eol) seçeneğinin adı GNU diff tarafından kullanılandan ( --strip-trailing-cr) alışık olduğumdan farklı .

Bu sorunla karşılaştığımda, çözümüm git'in yerleşik farkı yerine GNU farkını çağırmaktı, çünkü benim adım 2.16'dan daha eski. Bunu bu komut satırını kullanarak yaptım:

GIT_EXTERNAL_DIFF='diff -u --strip-trailing-cr "$2" "$5";true;#' git diff --ext-diff

Bu, kullanmaya --strip-trailing-crve diğer GNU fark seçeneklerine izin verir .

Başka bir yol daha var:

git difftool -y -x 'diff -u --strip-trailing-cr'

ancak yapılandırılmış çağrı cihazı ayarlarını kullanmaz, bu yüzden öncekini tercih ederim.


Cevabım için ilginç bir alternatif. Upvoted.
VonC
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.