क्या लाइन-एंडिंग के अंतर को अनदेखा करना संभव है?


150

क्या git mergeलाइन-एंडिंग के अंतर को अनदेखा करना संभव है ?

शायद मैं गलत सवाल पूछ रहा हूँ ... लेकिन:

मैंने uisng की कोशिश की, config.crlf inputलेकिन चीजें थोड़ी गड़बड़ हो गईं और नियंत्रण से बाहर हो गईं, खासकर जब मैंने इसे तथ्य के बाद लागू किया ।

एक बात के लिए, इस विकल्प को लागू करने के बाद इस विकल्प को लागू करने से पहले रिपॉजिटरी के लिए प्रतिबद्ध फ़ाइलों को प्रभावित नहीं करता है। एक और बात यह है कि अचानक सभी कमिट्स के परिणामस्वरूप CRLF के एलएफ में परिवर्तित होने के बारे में बहुत सारे कष्टप्रद चेतावनी संदेश मिलते हैं।

ईमानदार होने के लिए, मुझे वास्तव में परवाह नहीं है कि लाइन-एंडिंग का क्या उपयोग किया जाता है, मैं व्यक्तिगत रूप से यूनिक्स शैली को पसंद करता हूं \n, लेकिन जो भी हो। मुझे बस इतना ही ध्यान रखना git mergeचाहिए कि लाइन-एंडिंग में थोड़ा अंतर हो सकता है और मतभेदों को अनदेखा किया जा सकता है।

कभी-कभी मेरे पास दो समान फाइलें होती हैं, लेकिन git उन्हें संघर्ष में होने के रूप में चिह्नित करता है (और संघर्ष पूरी फ़ाइल है) बस इसलिए कि वे एक अलग पंक्ति के अंत वर्ण का उपयोग करते हैं।

अपडेट करें:

मुझे पता चला कि git diffएक --ignore-space-at-eolविकल्प को स्वीकार करता है , क्या git mergeइस विकल्प का उपयोग करना संभव होगा ?


28
ओह काश! गिट में समाप्त होने वाली यह रेखा पूरी तरह से टूट गई है
1800 सूचना

सिर्फ एक टेस्ट केस जोड़ा गया जो उन थर्ड-पार्टी मर्ज टूल को दर्शाता है जो एक मर्ज के दौरान ईओल स्टाइल को नजरअंदाज कर देगा
VonC

तो, स्पष्ट करने के लिए (जो मैं निर्धारित कर सकता हूं): सीआर को अनदेखा करने के लिए गिट पाने का कोई तरीका नहीं है, लेकिन अन्य सभी अनुगामी व्हाट्सएप के बारे में शिकायत करें?
स्टीफन

नीचे दिए गए उत्तर पर एक नज़र रखना सुनिश्चित करेंgit config merge.renormalize true
क्निल

जवाबों:


115

अद्यतन २०१३:

अधिक हालिया गिट संस्करण रणनीति recursiveऔर रणनीति विकल्प ( -X) के साथ मर्ज का उपयोग करते हुए अधिकृत करते हैं :

git मर्ज -s recursive -Xignore-space-at-eol

लेकिन " -Xignore-space-change" का उपयोग करना भी एक संभावना है


jakub.g यह भी टिप्पणी करता है कि रणनीति चेरी-पिकिंग के साथ भी काम करती है :

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

इससे काफी बेहतर काम होता है ignore-all-space


मूल उत्तर (मई 2009)

ईओल शैली की अनदेखी के लिए पैच जून 2007 में प्रस्तावित किया गया है , लेकिन यह केवल चिंता करता है git diff --ignore-space-at-eol, नहीं git merge

इस समय, सवाल पूछा गया है:

के --ignore-space-at-eolलिए एक विकल्प होना चाहिए git-merge?
विलय वे होते हैं जहां यह कार्यक्षमता मायने रखती है।
उन विकल्पों के साथ स्वतः हल किए गए मर्ज के शब्दार्थ क्या हैं - क्या वे केवल नाम का पता लगाने के लिए उपयोग किए जाते हैं, या क्या हम, उदाहरण के लिए, केवल व्हाट्सएप परिवर्तन के साथ झंडा संघर्ष नहीं? और अगर हम नहीं करते हैं, तो हम किस संस्करण को स्वचालित रूप से स्वीकार करते हैं?

जूलियो सी हमानो बिल्कुल उत्साही नहीं थे:

यह निश्चित रूप से आकर्षक है, लेकिन मुझे संदेह है कि बाद के दौर में छोड़ दिया जाना चाहिए।
मुझे संदेह है कि यह दो अलग-अलग प्रकार की भिन्नताओं की अवधारणा को पेश करेगा, एक यंत्रवत रूप से संसाधित होना (यानी "गिट-मर्ज-पुनरावर्ती" के साथ मर्ज में उपयोग करना, और "गिट-एम" के साथ लागू होना), और दूसरे द्वारा निरीक्षण किया जाना मनुष्य को समझना है।
यह अक्सर बाद के मामले के लिए इनपुट को मून करने के लिए उपयोगी हो सकता है, भले ही मुंग्ड इनपुट फ़ाइलों की तुलना करने से आउटपुट यांत्रिक अनुप्रयोग के लिए आसानी से उपयोग करने योग्य नहीं हो।

सामान्य विचार, जब यह आता है git merge, तो तीसरे पक्ष के मर्ज टूल पर भरोसा करना है।

उदाहरण के लिए, मेरे पास GIP मर्ज के लिए उपकरण होने के लिए DiffMerge सेटअप है , एक नियम सेट है जो उस मर्ज टूल को कुछ प्रकार की फ़ाइलों के लिए ईओएल को अनदेखा करने की अनुमति देता है।


MSysGit1.6.3 के साथ Windows पर सेटअप, या तो DOS या Git बैश सत्र के लिए, DiffMerge याiffiff3 के साथ:

  • अपने पथ में एक निर्देशिका सेट करें (यहां:) c:\HOMEWARE\cmd
  • उस निर्देशिका में जोड़ें स्क्रिप्ट merge.sh (आपके पसंदीदा मर्ज टूल के लिए आवरण)

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 के लिए अपने मर्ज आवरण को घोषित करें

Git config कमांड:

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 गलत है

सिस्टम स्तर पर विन्यास कॉन्फ़िगर करें:

git config ---system core.autoCRLF=false
  • परीक्षण करें कि, जब दो रेखाएं समान हैं (लेकिन उनके ईओएल चार्ट), दोनों डिफमर्ज़ या केडीफ़ 3 एक मर्ज के दौरान उन रेखाओं को अनदेखा करेंगे।

डॉस स्क्रिप्ट (ध्यान दें: dos2unix कमांड यहां से आती है , और इसका उपयोग यूनिक्स ईओल-स्टाइल को अनुकरण करने के लिए किया जाता है। इस कमांड को इस उत्तर की शुरुआत में उल्लिखित निर्देशिका में कॉपी किया गया है।)

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):

इस बिंदु पर (हिटिंग "वापसी"), डिफमर्ज़ या केडीफ़ 3 खुल जाएगा, और आप खुद देखेंगे कि कौन सी रेखाएं वास्तव में विलय हो रही हैं, और कौन सी रेखाओं को अनदेखा किया गया है।

चेतावनी : परिणाम फ़ाइल हमेशा डिफॉगर के साथ विंडोज ईओएल मोड (CRLF) में होगी ...
केडीआईफ़ 3 एक या दूसरे तरीके से सहेजने की पेशकश करता है।


टिप के लिए धन्यवाद! मैक में Meld और FileMerge भी शानदार ऐप लगता है।
लेओ लेपोल्ड हर्ट्ज़ '25

1
जानकारी के लिए, रणनीतियाँ चेरी-पिकिंग के साथ भी काम करती हैं : git cherry-pick abcd123456 --strategy=recursive --strategy-option=renormalize (यह इससे कहीं बेहतर काम करता है ignore-all-space)
jakub.g

1
@ jakub.g अच्छी बात! मैंने इसे अधिक दृश्यता के लिए उत्तर में शामिल किया है।
VonC

98

मैं एक ही जवाब के लिए देख रहा था और मुझे पता चला यह

अलग चेकइन / चेकआउट विशेषताओं के साथ शाखाओं को जोड़ना

यदि आपने किसी फ़ाइल में विशेषताओं को जोड़ा है जो उस फ़ाइल के लिए कैनोनिकल रिपॉजिटरी प्रारूप को बदलने का कारण बनता है, जैसे कि एक साफ / स्मज फिल्टर या टेक्स्ट / ईओएल / पहचान विशेषताओं को जोड़ना, कुछ भी विलय करना जहां विशेषता नहीं है, आमतौर पर टकराव का कारण होगा। ।

इन अनावश्यक मर्ज संघर्षों को रोकने के लिए, git को एक वर्चुअल चेक-आउट और फ़ाइल के सभी तीन चरणों के चेक-इन को चलाने के लिए कहा जा सकता है जब मर्ज को सेट करके तीन-तरफा मर्ज को हल किया जाता है। कॉन्फ़िगरेशन चर को निर्धारित करें। यह चेक-इन रूपांतरण के कारण होने वाले परिवर्तनों को रोकता है, जब एक परिवर्तित फ़ाइल को एक अनजाने फ़ाइल के साथ विलय कर दिया जाता है।

जब तक "स्मज → → क्लीन" समान आउटपुट का परिणाम "क्लीन" के रूप में होता है, यहां तक ​​कि पहले से ही स्मूद किए गए फ़ाइलों पर भी, यह रणनीति स्वचालित रूप से सभी फ़िल्टर-संबंधित संघर्षों को हल करेगी। इस तरह से कार्य नहीं करने वाले फिल्टर अतिरिक्त मर्ज संघर्ष का कारण बन सकते हैं जिन्हें मैन्युअल रूप से हल किया जाना चाहिए।

इसलिए किसी भी भंडार में इस कमांड को चलाने से यह चाल चलेगी:

git config merge.renormalize true

20
यह अब डिफ़ॉल्ट उत्तर देने के योग्य है। प्रश्न के पहले पूछे जाने के बाद से बहुत कुछ बदल गया है, git की हैंडलिंग अब इस मर्ज के साथ निर्मित है। जैसा कि आप कहते हैं।
एंटोन आई। सिपोस

यह सिर्फ कमाल है .. मेरा दिन बचाता है
मैथ्यू



4

मैंने जो कुछ भी किया था वह डिफ़ॉल्ट के रूप में छोड़ दिया गया था (अर्थात ऑटोक्रॉफ्ट = सच), सभी फ़ाइलों को स्पर्श करें (खोजें -exec स्पर्श {} \?), उन्हें 'संशोधित' के रूप में देखें और उन्हें वापस करने दें, और इसके साथ किया जाए। अन्यथा आप हमेशा या तो कष्टप्रद संदेशों या आश्चर्यजनक मतभेदों से त्रस्त हो जाएंगे, या सभी व्हाट्सएप के व्हाट्सएप फीचर को बंद कर देंगे।

आप जानकारी को दोष देंगे, लेकिन यह बाद में करने के बजाय जल्द ही करना बेहतर है :)


4

"git मर्ज -Xrencommonize" एक आकर्षण की तरह काम करता है।



1

http://stahlforce.com/dev/index.php?tool=remcrlf

मैंने इसकी कोशिश की, लेकिन अगर आपके कोड में अंतिम पंक्ति के बाद आपके पास पहले से CRLF नहीं था, तो यह अपने आप में LF जोड़ता है और फ़ाइल गिट में बदल जाती है। इसके अलावा यह काम करता है।


0

अब मुझे लगता है कि सबसे अच्छा तरीका है कि दोनों शाखाओं (और प्रतिबद्ध) पर लाइन अंत को सामान्य करने से पहले उन्हें विलय कर दिया जाए।

मैंने गुगली को "क्रैफ़ल को एलएफ में बदल दिया" और इसे पहले परिणाम के रूप में पाया:
http://stahlforce.com/dev/index.php?tool=remcrlf

मैंने इसे डाउनलोड किया और इस्तेमाल किया, एक अच्छा उपकरण लगता है।

>sfk remcr . .py

हालांकि एक निर्देशिका और एक फ़ाइल प्रकार (उदाहरण के लिए .py) निर्दिष्ट करना सुनिश्चित करें अन्यथा यह .gitनिर्देशिका की सामग्री के साथ गड़बड़ करने की कोशिश कर सकता है !


0

AFAICT, (मैंने यह कोशिश नहीं की है) आप git diffउस शाखा की तुलना करने के लिए उपयोग कर सकते हैं जिसे आप सामान्य पूर्वज में मर्ज करना चाहते हैं, फिर परिणामों को लागू करें git apply। दोनों कमांड में --ignore-whitespaceलाइन एंडिंग और व्हाइट स्पेस एरर्स को नजरअंदाज करने के विकल्प हैं।

दुर्भाग्य से, यदि पैच सफाई से लागू नहीं होता है, तो पूरे ऑपरेशन को रोक दिया जाता है। आप मर्ज विरोधों को ठीक नहीं कर सकते। फ़ाइलों --rejectमें असंगत हॉक छोड़ने का एक विकल्प है .rej, जो मदद करता है, लेकिन एक फ़ाइल में दिखाए गए मर्ज संघर्षों के समान नहीं है।


-1

रिज़ॉल्यूशन मर्ज टकरावों को पढ़ने के बाद : फोर्स सभी फाइलों को अधिलेखित कर देता है

मैंने आखिरकार इस मुद्दे के अपने संस्करण को हल कर दिया। मैं अपस्ट्रीम रेपो से अपडेट खींचने की कोशिश कर रहा था, लेकिन मेरा वर्तमान सीआरएलएफ से संबंधित समस्याएँ थीं और परिणाम के रूप में विलय करने में असमर्थ था। यह ध्यान दिया जाना चाहिए कि मुझे कोई चिंता नहीं थी मुझे चिंता करने की ज़रूरत थी। निम्नलिखित चरणों ने मेरी समस्या हल कर दी:

सिंकिंग कांटे पर github के निर्देशों के अनुसार ( https://help.github.com/articles/syncing-a-fork/ ):

  1. git fetch upstream

  2. git reset --hard upstream/master
    Git की मेरी सीमित समझ मुझे बताती है कि मैं यही कर रहा हूं- अपस्ट्रीम स्रोत में किए गए सभी बदलावों को हासिल करने के लिए अपने कांटे (बिना किसी वास्तविक परिवर्तन के साथ) को पुन: प्राप्त कर रहा हूं। स्रोत पृष्ठ के अनुसार, इस चरण को सामान्य रूप से आवश्यक नहीं होना चाहिए, लेकिन CRLF समस्या ने इसे आवश्यक बना दिया।

  3. git merge upstream/master

  4. git push

1
आप महसूस करते हैं कि git reset --hard upstream/masterआपकी स्थानीय शाखा को फेंक दिया जाता है और इसे एक नो-ऑप upstream/masterबनाता git merge upstream/masterहै?
क्रिस्टोफर हैमरस्ट्रॉम्ड

-1

हालाँकि मैं सही लाइन एंडिंग को प्राप्त करने के लिए sed जैसे टूल का उपयोग करने का सुझाव देता हूं, और फिर फ़ाइलों को अलग करता हूं। मैं पर कुछ घंटों के खर्च diffing विभिन्न लाइन अंत के साथ परियोजनाओं।

सबसे अच्छा तरीका था:

  1. .gitकिसी अन्य निर्देशिका में केवल प्रोजेक्ट फ़ाइलों ( डायरेक्ट डाइरेक्टरी) को कॉपी करें और फिर उसमें रिपॉजिटरी बनाएं, फिर फाइल्स जोड़ें और उन्हें कमिट करें (नए रिपॉजिटरी में मास्टर ब्रांच पर होना चाहिए)।
  2. दूसरी परियोजना से फ़ाइलों को एक ही फ़ोल्डर में कॉपी करें, लेकिन उदाहरण के लिए एक और शाखा dev( git checkout -b dev), इस शाखा पर फाइलें और चलाएं (यदि पहली परियोजना मास्टर में है): git diff master..dev --names-only केवल परिवर्तित फ़ाइलों के नाम देखने के लिए
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.