Git-merge komutunun satır sonu farklılıklarını yoksayması mümkün mü?


150

git mergeSatır sonu farklılıklarını göz ardı etmek mümkün müdür ?

Belki de yanlış soruyu soruyorum ... ama:

Ben uisng denedim config.crlf inputama biraz gergin ve kontrolden çıktı, özellikle de gerçeği uyguladıktan sonra .

Birincisi, bu yapılandırmayı gerçeğin ardından uygulamak, bu seçeneği uygulamadan önce depoya taahhüt edilen dosyaları etkilemez. Başka bir şey, aniden tüm taahhütlerin, CRLF'nin LF'ye dönüştürülmesiyle ilgili birçok can sıkıcı uyarı mesajıyla sonuçlanmasıdır.

Dürüst olmak gerekirse, hangi satır sonunun kullanıldığını umursamıyorum, şahsen Unix stilini tercih ediyorum \n, ama her neyse. Tek umurumda olan, git mergebiraz daha akıllı olmak ve satır sonlarındaki farklılıkları görmezden gelmek.

Bazen iki özdeş dosyam var, ancak git onları farklı bir satır sonu karakteri kullandıkları için çakışmada (ve çakışma bütün dosya) olarak işaretlerdi .

Güncelleme:

git diffBir --ignore-space-at-eolseçeneği kabul ettiğini öğrendim , git mergebu seçeneği de kullanmak mümkün mü?


28
Keşke. Git'te biten bu satır tamamen bozuldu
1800 BİLGİ

Bu üçüncü taraf birleştirme aracının bir birleştirme sırasında eol stilini göz ardı edeceğini gösteren bir test örneği ekledi
VonC

Yani, açıklığa kavuşturmak için (ne belirleyebileceğimden): Git'i CR'leri görmezden gelmenin, ancak diğer tüm boşluklardan şikayet etmenin bir yolu yok mu?
Stephen

Aşağıdaki cevaba bir göz git config merge.renormalize true
attığınızdan

Yanıtlar:


115

2013 Güncellemesi:

Daha yeni git sürümleri strateji recursiveve strateji seçeneğiyle birleştirme kullanma yetkisi verir ( -X):

git merge -s özyinelemeli -xignore-space-at-eol

Ama " -Xignore-space-change" kullanmak da bir olasılık


jakub.g da yorumlar bu stratejiler kiraz toplama ile de çalışır :

git cherry-pick abcd123456 --strategy=recursive --strategy-option=renormalize 

Bu çok daha iyi çalışıyor ignore-all-space.


Orijinal cevap (Mayıs 2009)

Eeo stilini göz ardı etme yaması Haziran 2007'de önerildi , ancak sadece endişe ediyor git diff --ignore-space-at-eol, değilgit merge .

O zaman soru soruldu:

Meli --ignore-space-at-eoliçin bir seçenek olabilir git-merge?
Bu işlevsellik önemli olan birleşmelerdir.
Geçerli olarak bu seçeneklerle otomatik olarak çözülmüş birleştirme semantikleri nelerdir - yalnızca yeniden adlandırma algılaması için mi kullanılıyorlar, yoksa yalnızca boşluk değişiklikleriyle çakışmaları mı işaretlemiyoruz? Ve eğer yapmazsak, hangi sürümü otomatik olarak kabul ediyoruz?

Julio C Hamano tam olarak hevesli değildi:

Bu kesinlikle cazip, ancak bunun daha sonraki turlara bırakılması gerektiğinden şüpheleniyorum.
Biri mekanik olarak işlenecek (yani "git-merge-özyinelemeli" ile birleşerek ve "git-am" ile uygulanacak iki farklı türden farklı bir kavram sunacağından şüpheleniyorum. insanlar anlamak için.
Munged girdi dosyalarının karşılaştırılmasından elde edilen çıktı, mekanik uygulama için kolayca kullanılamasa da, çoğu zaman ikinci durum için girişin sıkıştırılması yararlı olabilir.

Genel fikir, söz konusu olduğunda git merge, üçüncü taraf birleştirme aracına güvenmektir.

Örneğin, DiffMerge'i Git birleştirme aracı olarak ayarladım, bu birleştirme aracının belirli dosya türleri için eol'u yok saymasına izin veren bir kural kümesi ayarladım .


Windows veya MSysGit1.6.3 ile DOS veya Git bash oturumu için DiffMerge veya KDiff3 ile kurulum:

  • PATH'nize bir dizin ayarlayın (burada:) c:\HOMEWARE\cmd.
  • bu dizine merge.sh betiğini ekleyin (en sevdiğiniz birleştirme aracınızın sarıcısı)

merge.sh:

#!/bin/sh

# Passing the following parameters to mergetool:
#  local base remote merge_result

alocal=$1
base=$2
remote=$3
result=$4

if [ -f $base ]
then
    #"C:/Program Files/SourceGear/DiffMerge/DiffMerge.exe" "$alocal" "$base" "$remote" -m --result="$result" --title1="Mine" --title2="Merging to: $result" --title3="Theirs"

    # for merge respecting eol, KDiff3 is better than DiffMerge (which will always convert LF into CRLF)
    # KDiff3 will display eol choices (if Windows: CRLF, if Unix LF)
    "C:/Program Files/KDiff3/kdiff3.exe" -m "$base" "$alocal" "$remote" -o "$result"
else
    #there is not always a common ancestor: DiffMerge needing 3 files, BASE will be the result
    #"C:/Program Files/SourceGear/DiffMerge/DiffMerge.exe" "$alocal" "$result" "$remote" -m --result="$result" --title1="Mine" --title2="Merging to: $result" --title3="Theirs"

    # KDiff3 however does know how to merge based on 2 files (not just 3)
    "C:/Program Files/KDiff3/kdiff3.exe" -m "$base" "$remote" -o "$result"
fi
  • Git için birleştirme paketinizi bildirin

Git config komutları:

git config --global merge.tool diffmerge
git config --global mergetool.diffmerge.cmd "merge.sh \"$PWD/$LOCAL\" \"$PWD/$BASE\" \"$PWD/$REMOTE\" \"$PWD/$MERGED\"
git config --global mergetool.diffmerge.trustExitCode false
git config --global mergetool.diffmerge.keepBackup false
  • AutoCRLF öğesinin yanlış olup olmadığını kontrol edin

sistem düzeyinde git config:

git config ---system core.autoCRLF=false
  • İki satır aynı olduğunda (ancak eol karakterleri), DiffMerge veya KDiff3'ün birleştirme sırasında bu satırı yok sayacağını test edin.

DOS komut dosyası (not: dos2unix komutu buradan gelir ve bir Unix eol stilini simüle etmek için kullanılır. Bu komut, bu yanıtın başında belirtilen dizine kopyalanmıştır.):

C:\HOMEWARE\git\test>mkdir test_merge C:\HOMEWARE\git\test>cd test_merge C:\HOMEWARE\git\test\test_merge>git init C:\HOMEWARE\git\test\test_merge>echo a1 > a.txt & echo a2 >> a.txt C:\HOMEWARE\git\test\test_merge>git add a.txt C:\HOMEWARE\git\test\test_merge>git commit -m "a.txt, windows eol style" C:\HOMEWARE\git\test\test_merge>git checkout -b windows Switched to a new branch 'windows' C:\HOMEWARE\git\test\test_merge>echo a3 >> a.txt & echo a4 >> a.txt C:\HOMEWARE\git\test\test_merge>git add a.txt C:\HOMEWARE\git\test\test_merge>git commit -m "add two lines, windows eol style" C:\HOMEWARE\git\test\test_merge>git checkout master C:\HOMEWARE\git\test\test_merge>git checkout -b unix Switched to a new branch 'unix' C:\HOMEWARE\git\test\test_merge>echo au3 >> a.txt & echo au4 >> a.txt && echo au5 >> a.txt C:\HOMEWARE\git\test\test_merge>dos2unix a.txt Dos2Unix: Processing file a.txt ... C:\HOMEWARE\git\test\test_merge>git add a.txt C:\HOMEWARE\git\test\test_merge>git commit -m "add 3 lines, all file unix eol style" [unix c433a63] add 3 lines, all file unix eol style C:\HOMEWARE\git\test\test_merge>git merge windows Auto-merging a.txt CONFLICT (content): Merge conflict in a.txt Automatic merge failed; fix conflicts and then commit the result. C:\HOMEWARE\git\test\test_merge>git ls-files -u 100644 39b4c894078a02afb9b1dfeda6f1127c138e38df 1 a.txt 100644 28b3d018872c08b0696764118b76dd3d0b448fca 2 a.txt 100644 3994da66530b4df80189bb198dcfac9b8f2a7b33 3 a.txt C:\HOMEWARE\git\test\test_merge>git mergetool Merging the files: a.txt Normal merge conflict for 'a.txt': {local}: modified {remote}: modified Hit return to start merge resolution tool (diffmerge):

Bu noktada ("return" tuşuna basmak), DiffMerge veya KDiff3 açılacak ve hangi satırların gerçekten birleştirildiğini ve hangi satırların yok sayıldığını kendiniz göreceksiniz.

Uyarı : sonuç dosyası her zaman DiffMerge ile Windows eol modunda (CRLF) olacaktır ...
KDiff3 bir şekilde kaydetmeyi önerir.


Bahşiş için teşekkürler! Mac'teki Meld ve FileMerge de harika uygulamalar gibi görünüyor.
Léo Léopold Hertz 준영

1
Bilgi için, stratejiler kiraz toplama ile de git cherry-pick abcd123456 --strategy=recursive --strategy-option=renormalize çalışır : (bu daha iyi çalışır ignore-all-space)
jakub.g

1
@ jakub.g iyi bir nokta! Daha fazla görünürlük için cevaba ekledim.
VonC

98

Aynı yanıtı bulmaya ve öğrendiğim bu

Farklı check-in / checkout özelliklerine sahip şubeleri birleştirme

Bir dosyaya, temiz / bulaşma filtresi veya metin / eol / ident öznitelikleri eklemek gibi, kanonik havuz biçiminin değişmesine neden olan öznitelikler eklediyseniz, özniteliğin yerinde olmadığı her şeyi birleştirmek normalde birleştirme çakışmalarına neden olur .

Bu gereksiz birleştirme çakışmalarını önlemek için git'e, merge.renormalize yapılandırma değişkenini ayarlayarak üç yönlü birleştirme çözümlenirken dosyanın üç aşamasının da sanal bir teslim alma ve teslim alma işlemi gerçekleştirilebilir. Bu, dönüştürülen bir dosya dönüştürülmemiş bir dosyayla birleştirildiğinde check-in dönüşümünün neden olduğu değişikliklerin birleştirme çakışmalarına neden olmasını önler.

"Leke → temiz", zaten bulaşmış olan dosyalarda bile "temiz" ile aynı çıktıyla sonuçlandığı sürece, bu strateji filtreyle ilgili tüm çakışmaları otomatik olarak çözer. Bu şekilde çalışmayan filtreler, el ile çözülmesi gereken ek birleştirme çakışmalarına neden olabilir.

Bu komutu herhangi bir depoda çalıştırmak hile yapacaktır:

git config merge.renormalize true

20
Bu, şimdi varsayılan yanıt olmayı hak ediyor. Sorunun ilk sorulmasından bu yana çok şey değişti, git'in bunu ele alması artık merge.renormalize ile inşa edildi.
Anton I.Sipos

Bu sadece harika .. günümü kurtarıyor
matthaeus



4

Yaptığım her şeyi varsayılan olarak bırakmak (yani autocrlf = true), tüm dosyalara dokunun (. -Exec touch {} \;) bulun, git onları 'değiştirilmiş' olarak görüp geri verin ve onunla bitirin. Aksi takdirde, her zaman sinir bozucu mesajlar veya şaşırtıcı farklılıklar sizi rahatsız edecek veya git'in tüm boşluk özelliklerini kapatmak zorunda kalacaksınız.

Suçlama bilgilerinizi kaybedeceksiniz, ancak daha sonra değil, daha erken yapmak daha iyidir :)


4

"git merge -Xrenormalize" bir cazibe gibi çalışır.




0

Şimdi bana öyle geliyor ki en iyi yol, her iki dalda (ve taahhütte) satır sonlarını birleştirmeden önce normalize etmektir.

"Crlf'yi lf'ye dönüştür" seçeneğini buldum ve bunu ilk sonuç olarak buldum:
http://stahlforce.com/dev/index.php?tool=remcrlf

İndirdim ve kullandım, güzel bir araç gibi görünüyor.

>sfk remcr . .py

Bir dizin ve bir dosya türü (örn. .Py) belirttiğinizden emin olun, aksi takdirde .gitdizinin içeriğiyle uğraşmaya çalışabilir !


0

AFAICT, (denemedim) git diff, ortak ata ile birleştirmek istediğiniz dalı karşılaştırmak ve ardından sonuçları uygulamak için kullanabilirsiniz git apply. Her iki komut da --ignore-whitespace satır sonunu ve boşluk boşluklarını yoksayma seçenekleri vardır.

Ne yazık ki, yama temiz bir şekilde uygulanmazsa, tüm işlem iptal edilir. Birleştirme çakışmalarını düzeltemezsiniz. Dosyalarda --rejecterişilemeyen iri parçalar bırakma seçeneği vardır .rej, bu da yardımcı olur, ancak bir dosyada birleştirme çakışmalarının gösterilmesi ile aynı değildir.


-1

Okuduktan sonra Birleştirme çakışmalarını çözme : Tüm dosyaların üzerine yazmaya zorla

Sonunda bu sorunun sürümümü çözdüm. Yukarı akış deposundan güncellemeler almaya çalışıyordum ama şu anki CRLF ile ilgili sorunlar yaşıyordum ve sonuç olarak birleştirilemedi. Endişelenmem gereken YEREL DEĞİŞİMLERİN olmadığı unutulmamalıdır. Aşağıdaki adımlar sorunumu çözdü:

Github'un çatalları senkronize etme hakkındaki talimatlarına göre ( https://help.github.com/articles/syncing-a-fork/ ):

  1. git fetch upstream

  2. git reset --hard upstream/master
    Git konusundaki sınırlı anlayışım bunun istediğimi yaptığını söylüyor - yukarı akış kaynağında yapılan tüm değişiklikleri elde etmek için çatalımı (gerçek taahhüt edilmemiş değişikliklerle) yeniden temellendirmek. Kaynak sayfaya göre, bu adım normalde gerekli olmamalıdır, ancak CRLF sorunu bunu gerektirdi.

  3. git merge upstream/master

  4. git push

1
Bunun git reset --hard upstream/masteryerel şubenizi uzaklaştıracağını ve bunu işaret edip upstream/master, git merge upstream/masterhiç işlem yapmayacağınızı biliyor musunuz?
Christoffer Hammarström

-1

Ancak doğru çizgi sonları elde etmek için sed gibi aracı kullanmanızı öneririz ve sonra diff dosyaları. Ben kaç saat geçirdim diffing çeşitli satır sonları projeleri.

En iyi yol:

  1. yalnızca proje dosyalarını (atla .gitdizini) başka bir dizine kopyalayın , içinde depo oluşturun, sonra dosyaları ekleyin ve bunları kesin (yeni depoda ana dalda olmalıdır).
  2. dosyaları ikinci projeden aynı klasöre kopyalayın, ancak örneğin başka bir dal dev( git checkout -b dev), bu dalda dosyaları çalıştırın ve çalıştırın (ilk proje master ise): git diff master..dev --names-only yalnızca değiştirilen dosyaların adlarını görmek için
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.