एक कॉन्फ़िगर फ़ाइल के विशिष्ट उदाहरण पर, मैं रॉन के जवाब से सहमत होगा :
एक कॉन्फ़िगरेशन आपके कार्यक्षेत्र के लिए "निजी" होना चाहिए (इसलिए "अनदेखा", जैसा कि "एक .gitignore
फ़ाइल में घोषित किया गया है ")।
आपके पास इसमें टोकन मूल्यों के साथ एक कॉन्फिग फाइल टेम्प्लेट हो सकती है और एक स्क्रिप्ट उस फाइल को एक निजी (और उपेक्षित) कॉन्फिगर फाइल में बदल सकती है।config.template
हालाँकि, उस विशिष्ट टिप्पणी का उत्तर नहीं है कि व्यापक सामान्य प्रश्न क्या है, अर्थात आपका प्रश्न (!)
मैं यह कैसे बताऊं कि किसी विशिष्ट फ़ाइल पर विवादित मर्ज के लिए हमेशा अपने स्थानीय संस्करण का चयन करें? (किसी फ़ाइल या फ़ाइल के समूह के लिए)
इस तरह का मर्ज एक "कॉपी मर्ज" है, जिसमें आप हमेशा किसी फाइल के 'हमारा' या 'उनके' वर्जन को कॉपी करेंगे जब भी कोई टकराव होता है।
(के रूप में ब्रायन वन्देंबेर्ग नोटों टिप्पणी में , ' ours
' और ' theirs
' यहाँ किसी मर्ज के लिए उपयोग किया जाता है ।
वे कर रहे हैं उलट एक के लिए रिबेस : देखें " Why is the meaning of “ours” and “theirs” reversed with git-svn
" है, जो एक रिबेस का उपयोग करता है, " git rebase
, का ट्रैक रखने के 'स्थानीय' और 'दूरस्थ' " )
"एक फ़ाइल" के लिए (सामान्य रूप से एक फ़ाइल, "कॉन्फ़िग" फ़ाइल की बात नहीं कर रही है, क्योंकि यह एक बुरा उदाहरण है), आप इसे प्राप्त करेंगे जो मर्ज के माध्यम से बुलाए गए कस्टम स्क्रिप्ट के साथ होगा।
Git उस स्क्रिप्ट को कॉल करेगा क्योंकि आपने एक gitattributes मान निर्धारित किया होगा , जो एक कस्टम मर्ज ड्राइवर को परिभाषित करता है ।
"कस्टम मर्ज ड्राइवर" इस मामले में, एक बहुत ही सरल स्क्रिप्ट है जो मूल रूप से वर्तमान संस्करण को अपरिवर्तित रखेगा, इसलिए आपको हमेशा अपने स्थानीय संस्करण का चयन करने की अनुमति देगा।
आईई।, जैसा कि सिरो सेंटिल्ली ने नोट किया है :
echo 'path/to/file merge=ours' >> .gitattributes
git config --global merge.ours.driver true
आइए परीक्षण करें कि एक साधारण परिदृश्य में, विंडोज पर एमएसआईजित 1.6.3 के साथ, केवल डॉस सत्र में:
cd f:\prog\git\test
mkdir copyMerge\dirWithConflicts
mkdir copyMerge\dirWithCopyMerge
cd copyMerge
git init
Initialized empty Git repository in F:/prog/git/test/copyMerge/.git/
अब, दो फाइल बनाते हैं, जिसमें दोनों का टकराव होगा, लेकिन जिसे अलग-अलग मर्ज किया जाएगा।
echo a > dirWithConflicts\a.txt
echo b > dirWithCopyMerge\b.txt
git add -A
git commit -m "first commit with 2 directories and 2 files"
[master (root-commit) 0adaf8e] first commit with 2 directories and 2 files
हम दो अलग-अलग गिट शाखाओं में उन दोनों फाइलों की सामग्री में एक "संघर्ष" शुरू करेंगे:
git checkout -b myBranch
Switched to a new branch 'myBranch'
echo myLineForA >> dirWithConflicts\a.txt
echo myLineForB >> dirWithCopyMerge\b.txt
git add -A
git commit -m "add modification in myBranch"
[myBranch 97eac61] add modification in myBranch
git checkout master
Switched to branch 'master'
git checkout -b hisBranch
Switched to a new branch 'hisBranch'
echo hisLineForA >> dirWithConflicts\a.txt
echo hisLineForB >> dirWithCopyMerge\b.txt
git add -A
git commit -m "add modification in hisBranch"
[hisBranch 658c31c] add modification in hisBranch
अब, "myBranch" पर, "उसके बर्च" को मर्ज करने की कोशिश करें:
- परस्पर विरोधी विलय के लिए मैनुअल संकल्प
- सिवाय के लिए
dirWithCopyMerge\b.txt
जहां मैं हमेशा रखना चाहते हैं मेरी के संस्करण b.txt
।
चूंकि मर्ज ' MyBranch
' में होता है , हम इसे वापस स्विच करेंगे, और ' gitattributes
' निर्देश जोड़ेंगे जो मर्ज व्यवहार को अनुकूलित करेगा।
git checkout myBranch
Switched to branch 'myBranch'
echo b.txt merge=keepMine > dirWithCopyMerge\.gitattributes
git config merge.keepMine.name "always keep mine during merge"
git config merge.keepMine.driver "keepMine.sh %O %A %B"
git add -A
git commit -m "prepare myBranch with .gitattributes merge strategy"
[myBranch ec202aa] prepare myBranch with .gitattributes merge strategy
हमारे पास निर्देशिका .gitattributes
में एक फ़ाइल परिभाषित है dirWithCopyMerge
(केवल उस शाखा में परिभाषित की गई है जहाँ विलय होगा:) myBranch
, और हमारे पास एक .git\config
फ़ाइल है जिसमें अब एक मर्ज ड्राइवर है।
[merge "keepMine"]
name = always keep mine during merge
driver = keepMine.sh %O %A %B
यदि आप अभी तक KeepMine.sh को परिभाषित नहीं करते हैं, और मर्ज को किसी भी तरह लॉन्च करते हैं, तो यहां आपको वही मिलेगा।
git merge hisBranch
sh: keepMine.sh: command not found
fatal: Failed to execute internal merge
git st
# On branch myBranch
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: dirWithConflicts/a.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
type dirWithConflicts\a.txt
a
<<<<<<< HEAD:dirWithConflicts/a.txt
myLineForA
=======
hisLineForA
>>>>>>> hisBranch:dirWithConflicts/a.txt
यह ठीक है:
a.txt
विलय के लिए तैयार है और इसमें संघर्ष है
b.txt
अभी भी अछूता नहीं है, क्योंकि मर्ज ड्राइवर को इसका ध्यान रखना चाहिए ( .gitattributes
इसकी निर्देशिका में फाइल में निर्देश के कारण )।
keepMine.sh
अपने %PATH%
(या $PATH
हमारे यूनिक्स दोस्त के लिए कहीं भी परिभाषित करें । मैं दोनों कोर्स करता हूं: मेरे पास वर्चुअलबॉक्स सत्र में एक उबंटू सत्र है)
जैसा कि lrkwz द्वारा टिप्पणी की गई है , और कस्टमाइज़िंग गिट - गिट एट्रिब्यूट्स के " मर्ज स्ट्रैटेजीज़ " खंड में वर्णित है , आप शेल स्क्रिप्ट को शेल कमांड से बदल सकते हैं ।true
git config merge.keepMine.driver true
लेकिन सामान्य स्थिति में, आप एक स्क्रिप्ट फ़ाइल को परिभाषित कर सकते हैं:
keepMine.sh
# I want to keep MY version when there is a conflict
# Nothing to do: %A (the second parameter) already contains my version
# Just indicate the merge has been successfully "resolved" with the exit status
exit 0
(है कि एक साधारण मर्ज ड्राइवर था,) (उस मामले, उपयोग में भी सरल true
)
(आप दूसरे संस्करण रखने के लिए, बस से पहले जोड़ने चाहता है तो exit 0
लाइन:
cp -f $3 $2
।
यही है आप मिला चालक aways संस्करण दूसरे से आते रहते हैं। शाखा, किसी भी स्थानीय परिवर्तन को ओवरराइड करते हुए)
अब, शुरुआत से मर्ज को पुन: प्रयास करें:
git reset --hard
HEAD is now at ec202aa prepare myBranch with .gitattributes merge strategy
git merge hisBranch
Auto-merging dirWithConflicts/a.txt
CONFLICT (content): Merge conflict in dirWithConflicts/a.txt
Auto-merging dirWithCopyMerge/b.txt
Automatic merge failed; fix conflicts and then commit the result.
मर्ज विफल हो जाता है ... केवल a.txt के लिए ।
A.txt को संपादित करें और 'hisBranch' से लाइन छोड़ें, फिर:
git add -A
git commit -m "resolve a.txt by accepting hisBranch version"
[myBranch 77bc81f] resolve a.txt by accepting hisBranch version
आइए देखें कि इस मर्ज के दौरान b.txt को संरक्षित किया गया है
type dirWithCopyMerge\b.txt
b
myLineForB
अंतिम वचन पूर्ण मर्ज का प्रतिनिधित्व करता है :
git show -v 77bc81f5e
commit 77bc81f5ed585f90fc1ca5e2e1ddef24a6913a1d
Merge: ec202aa 658c31c
git merge hisBranch
Already up-to-date.
(मर्ज के साथ शुरू होने वाली रेखा यह साबित करती है)
विचार करें कि आप मर्ज ड्राइवर को परिभाषित, संयोजित और / या अधिलेखित कर सकते हैं, जैसा कि Git होगा:
- जांच
<dir>/.gitattributes
(जो प्रश्न में पथ के समान निर्देशिका में है): .gitattributes
निर्देशिका में दूसरे पर प्रबल होगी
- तब यह जांच करता है
.gitattributes
(जो मूल निर्देशिका में है), केवल पहले से सेट न होने पर निर्देश निर्धारित करेगा
- अंत में यह जांच करता है
$GIT_DIR/info/attributes
। इस फ़ाइल का उपयोग इन-ट्री सेटिंग को ओवरराइड करने के लिए किया जाता है। यह <dir>/.gitattributes
निर्देशों को अधिलेखित कर देगा ।
"संयोजन" से मेरा मतलब है कि "मर्ज" कई मर्ज ड्राइवर।
निक ग्रीन की कोशिश करता, टिप्पणी में , वास्तव में मर्ज ड्राइवरों गठबंधन करने के लिए: देखें " मर्ज पोम के माध्यम से अजगर Git ड्राइवर "।
हालांकि, जैसा कि उनके अन्य प्रश्न में उल्लेख किया गया है , यह केवल संघर्षों (दोनों शाखाओं में समवर्ती संशोधन) के मामले में काम करता है।