यह मूल एल्गोरिथ्म की सीमा के कारण है। मर्ज-कमिट्स को हैंडल करते समय, मूल एल्गोरिथ्म असंबंधित माता-पिता को काटने के लिए एक सरलीकृत मानदंड का उपयोग करता है। विशेष रूप से, यह जांचता है, अगर कोई माता-पिता है, जिसके पास एक ही पेड़ है। यदि ऐसा कोई माता-पिता पाया जाता है, तो यह मर्ज कमिट को ध्वस्त कर देगा और इसके बजाय पेरेंट कमिट का उपयोग करेगा, यह मानते हुए कि अन्य माता-पिता उप-पेड़ से असंबंधित परिवर्तन करते हैं। कुछ मामलों में इसके परिणामस्वरूप इतिहास के कुछ हिस्सों को छोड़ दिया जाएगा, जिसमें उप-वृक्ष के वास्तविक परिवर्तन हैं। विशेष रूप से यह आवागमन के क्रम को गिरा देगा, जो एक उप-वृक्ष को स्पर्श करेगा, लेकिन इसके परिणामस्वरूप समान उप-वृक्ष मूल्य होगा।
यह कैसे काम करता है यह समझने के लिए एक उदाहरण देखें (जिसे आप आसानी से पुन: पेश कर सकते हैं)। निम्नलिखित इतिहास पर विचार करें (रेखा प्रारूप है: प्रतिबद्ध [वृक्ष] विषय):
% git log --graph --decorate --pretty=oneline --pretty="%h [%t] %s"
* E [z] Merge branch 'master' into side-branch
|\
| * D [z] add dir/file2.txt
* | C [y] Revert "change dir/file1.txt"
* | B [x] change dir/file1.txt
|/
* A [w] add dir/file1.txt
इस उदाहरण में, हम विभाजित कर रहे हैं dir
। कमिट करता है D
और E
एक ही पेड़ है z
, क्योंकि हम प्रतिबद्ध हैं C
, जो पूर्ववत करते हैं B
, इसलिए B-C
अनुक्रम इसके लिए dir
कुछ भी नहीं करता है , हालांकि इसमें परिवर्तन होता है।
अब विभाजन करते हैं। पहले हम कमिट पर अलग हुए C
।
% git log `git subtree split -P dir C` ...
* C' [y'] Revert "change dir/file1.txt"
* B' [x'] change dir/file1.txt
* A' [w'] add dir/file1.txt
आगे हम कमिट पर बंट गए E
।
% git log `git subtree split -P dir E` ...
* D' [z'] add dir/file2.txt
* A' [w'] add dir/file1.txt
हां, हमने दो कमिट खो दिए। दूसरा स्प्लिट पुश करने का प्रयास करने पर यह त्रुटि उत्पन्न होती है, क्योंकि इसमें वे दो कमिट नहीं होते हैं, जो पहले से ही मूल में हैं।
आमतौर पर आप इस त्रुटि का उपयोग करके सहन कर सकते हैं push --force
, क्योंकि गिराए गए कामों में आमतौर पर महत्वपूर्ण जानकारी नहीं होगी। लंबी अवधि में, बग को ठीक करने की आवश्यकता है, इसलिए विभाजित इतिहास में वास्तव में सभी कमिट होंगे, जो स्पर्श करते हैंdir
कि उम्मीद के । मैं इस बात की उम्मीद करूंगा कि इस छिपी निर्भरता के लिए माता-पिता द्वारा किए गए गहन विश्लेषण को शामिल करने के लिए यह निर्णय सही होगा।
संदर्भ के लिए, यहां मूल कोड का हिस्सा है, जो व्यवहार के लिए जिम्मेदार है।
copy_or_skip()
...
for parent in $newparents; do
ptree=$(toptree_for_commit $parent) || exit $?
[ -z "$ptree" ] && continue
if [ "$ptree" = "$tree" ]; then
identical="$parent"
else
nonidentical="$parent"
fi
...
if [ -n "$identical" ]; then
echo $identical
else
copy_commit $rev $tree "$p" || exit $?
fi