এটি মূল অ্যালগরিদমের সীমাবদ্ধতার কারণে। মার্জ-কমিটগুলি পরিচালনা করার সময়, মূল অ্যালগোরিদম সম্পর্কযুক্ত পিতামাতাকে কাটাতে সরল মানদণ্ড ব্যবহার করে criteria বিশেষত, এটি পরীক্ষা করে, যদি কোনও অভিভাবক থাকে, তবে একই গাছ রয়েছে। যদি এইরকম কোনও পিতামাতাকে পাওয়া যায় তবে এটি মার্জ কমিটকে ভেঙে দেবে এবং পরিবর্তে পিতামাতার প্রতিশ্রুতি ব্যবহার করবে, ধরে নেওয়া হবে যে অন্যান্য পিতামাতার উপ-গাছের সাথে সম্পর্কিত নয় এমন পরিবর্তন রয়েছে। কিছু ক্ষেত্রে এর ফলে ইতিহাসের কিছু অংশ বাদ পড়বে, যার উপ-গাছের প্রকৃত পরিবর্তন রয়েছে। বিশেষত এটি কমিটের ক্রমগুলি ফেলে দেয় যা একটি উপ-গাছকে স্পর্শ করবে তবে ফলত একই উপ-গাছের মান।
এটি কীভাবে কাজ করে তা আরও ভাল করে বোঝার জন্য একটি উদাহরণ (যা আপনি সহজেই পুনরুত্পাদন করতে পারেন) দেখুন। নিম্নলিখিত ইতিহাস বিবেচনা করুন (লাইন ফর্ম্যাটটি হ'ল: [গাছ] বিষয় প্রতিশ্রুতিবদ্ধ):
% 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
, যেহেতু বাদ দেওয়া কমিটগুলির মধ্যে সাধারণত তাদের মধ্যে গুরুত্বপূর্ণ তথ্য থাকে না have দীর্ঘমেয়াদে, বাগটি সংশোধন করা দরকার, সুতরাং বিভক্ত ইতিহাসে 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