لماذا يكون التفرع والاندماج أسهل في Mercurial منه في Subversion؟

StackOverflow https://stackoverflow.com/questions/43995

سؤال

يعد التعامل مع عمليات الدمج المتعددة في الفروع في Subversion أو CVS أحد الأشياء التي يجب تجربتها.من الأسهل للغاية تتبع الفروع وعمليات الدمج في Mercurial (وربما أي نظام موزع آخر) ولكني لا أعرف السبب.هل يعرف أي شخص آخر؟

ينبع سؤالي من حقيقة أنه مع Mercurial يمكنك اعتماد ممارسة عمل مشابهة لتلك الخاصة بالمستودع المركزي لـ Subversions/CVS وكل شيء سيعمل على ما يرام.يمكنك إجراء عمليات دمج متعددة في نفس الفرع ولن تحتاج إلى قصاصات ورق لا نهاية لها تحتوي على أرقام الالتزام وأسماء العلامات.

أعلم أن الإصدار الأخير من Subversion لديه القدرة على تتبع عمليات الدمج إلى الفروع حتى لا تواجه نفس الدرجة من المتاعب ولكنه كان تطورًا ضخمًا وكبيرًا من جانبهم وما زال لا يفعل كل ما يفعله فريق التطوير مثل ذلك للقيام به.

يجب أن يكون هناك اختلاف جوهري في الطريقة التي يعمل بها كل شيء.

هل كانت مفيدة؟

المحلول

في Subversion (وCVS)، يكون المستودع في المقام الأول.في Git و Mercurial ، لا يوجد حقًا مفهوم المستودع بنفس الطريقة ؛التغييرات هنا هي الموضوع المركزي.

+1

تأتي المتاعب في CVS/SVN من حقيقة أن هذه الأنظمة تفعل ذلك لاتذكر أبوة التغييرات.في Git و Mercurial ، لا يمكن للالتزام أن يكون لها العديد من الأطفال ، بل يمكن أن يكون لها أيضًا العديد من الآباء!

ويمكن ملاحظة ذلك بسهولة باستخدام إحدى الأدوات الرسومية، gitk أو hg view.في المثال التالي ، تم تشويه الفرع رقم 2 من المرتبة الأولى في الالتزام A ، ومنذ ذلك الحين تم دمجه مرة واحدة (في M ، تم دمجه مع الالتزام ب):

o---A---o---B---o---C         (branch #1)
     \       \
      o---o---M---X---?       (branch #2)

لاحظ كيف أن A وB لديهما طفلان، بينما M لديه طفلان آباء.هذه العلاقات مسجل في المستودع.دعنا نقول أن مشرف الفرع رقم 2 يريد الآن دمج أحدث التغييرات من الفرع رقم 1 ، ويمكنهم إصدار أمر مثل:

$ git merge branch-1

وستعرف الأداة تلقائيًا أن قاعدة هل تم تسجيله في Commice M ، وهو سلف طرف رقم 2-وأنه يتعين عليه دمج ما حدث بين B و C.لا تسجل CVS هذه المعلومات ، كما لم تكن SVN قبل الإصدار 1.5.في هذه الأنظمة ، سيبدو الرسم البياني:

o---A---o---B---o---C         (branch #1)
     \    
      o---o---M---X---?       (branch #2)

حيث يكون M مجرد التزام "سحق" عملاق كل ما حدث بين A و B ، يطبق فوق M.لاحظ أنه بعد الانتهاء من الفعل، هناك لم يتبق أي أثر (باستثناء من المحتمل في التعليقات القابلة للقراءة البشرية) من أين نشأت م ولا كم عدد انهارت الالتزامات معا-صنع التاريخ أكثر لا يمكن اختراقه.

والأسوأ من ذلك أن إجراء الدمج الثاني يصبح كابوسًا:على المرء أن يكتشف ما هي قاعدة الدمج في وقت الاندماج الأول (وواحد لديه ل يعرفأنه كان هناك دمج في المقام الأول!) ، ثم قدم هذه المعلومات إلى الأداة بحيث لا تحاول إعادة تشغيل A..B على رأس M.كل هذا صعب بما فيه الكفاية عند العمل في التعاون الوثيق ، ولكنه ببساطة مستحيل في بيئة موزعة.

هناك مشكلة (ذات صلة) وهي أنه لا توجد طريقة للإجابة على السؤال:"هل يحتوي x على ب؟" حيث B هو إصلاح خطأ محتمل.لذا ، لماذا لا تسجل هذه المعلومات فقط في الالتزام ، لأنه هو معروف في وقت الدمج!

ملاحظة.- ليس لدي أي خبرة مع قدرات التسجيل SVN 1.5+ ، ولكن يبدو أن سير العمل أكثر مفتعلة بكثير من الأنظمة الموزعة.إذا كان هذا هو الحال بالفعل ، فربما يكون ذلك بسبب-كما ذكر في التعليق أعلاه-يتم التركيز على تنظيم المستودع بدلاً من التغييرات نفسها.

نصائح أخرى

لأن Subversion (على الأقل الإصدار 1.4 وما دونه) لا يتتبع ما تم دمجه.بالنسبة إلى Subversion، فإن الدمج هو في الأساس نفس أي التزام بينما في التحكم في الإصدار الآخر مثل Git، يتم تذكر ما تم دمجه.

لم يتأثر Hg بأي من الإجابات المقدمة بالفعل، فقد قدم إمكانات دمج فائقة لأنه يستخدم المزيد من المعلومات عند دمج التغييرات (hginit.com):

على سبيل المثال ، إذا قمت بتغيير وظيفة ما قليلاً ، ثم نقلها في مكان آخر ، فإن التخريب لا يتذكر تلك الخطوات حقًا ، لذلك عندما يحين الوقت للاندماج ، قد يعتقد أن وظيفة جديدة ظهرت للتو من اللون الأزرق .في حين أن الزئبق سوف يتذكر تلك الأشياء بشكل منفصل:تم تغيير الوظيفة ، تم نقل الوظيفة ، مما يعني أنه إذا قمت أيضًا بتغيير هذه الوظيفة قليلاً ، فمن الأرجح أن Mercurial ستعمل على دمج تغييراتنا بنجاح.

وبطبيعة الحال، فإن تذكر ما تم دمجه آخر مرة (النقطة التي تناولتها معظم الإجابات المقدمة هنا) يعد أيضًا فوزًا كبيرًا.

ومع ذلك، فإن كلا التحسينات مشكوك فيها نظرًا لأن الإصدار 1.5+ يخزن معلومات دمج إضافية في شكل خصائص التخريب:مع توفر هذه المعلومات، لا يوجد سبب واضح لعدم تمكن Subversion merge من تنفيذ الدمج بنجاح مثل Hg أو Git.لا أعرف إذا كان الأمر كذلك، ولكن يبدو بالتأكيد أن مطوري البرامج التخريبية في طريقهم للتغلب على هذه المشكلة.

أفترض أن هذا قد يكون جزئيًا لأن Subversion لديه فكرة وجود خادم مركزي بالإضافة إلى جدول زمني مطلق للمراجعات.يتم توزيع Mercurial حقًا وليس له مثل هذه الإشارة إلى خط زمني مطلق.يسمح هذا لمشاريع Mercurial بتشكيل تسلسلات هرمية أكثر تعقيدًا للفروع لإضافة ميزات ودورات اختبار حسب المشروع الفرعي، ولكن تحتاج الفرق الآن إلى متابعة عمليات الدمج بشكل أكثر نشاطًا للبقاء على اطلاع دائم حيث لا يمكنهم فقط الضغط على التحديث والانتهاء منه .

في Subversion (وCVS)، يكون المستودع في المقام الأول.في git وmercurial، لا يوجد حقًا مفهوم المستودع بنفس الطريقة؛هنا التغييرات هي الموضوع المركزي.

لم أفكر كثيرًا في كيفية التنفيذ أيضًا ولكن انطباعي (استنادًا إلى الخبرة المريرة والكثير من القراءة) هو أن هذا الاختلاف هو ما يجعل الدمج والتفرع أسهل بكثير في الأنظمة غير القائمة على المستودعات.

ليس لدي سوى خبرة في Subversion ولكن يمكنني أن أخبرك أن شاشة الدمج في TortoiseSVN معقدة للغاية.لحسن الحظ أنها تحتوي على زر التشغيل الجاف حتى تتمكن من معرفة ما إذا كنت تقوم بذلك بشكل صحيح.يكمن التعقيد في تكوين ما تريد دمجه في المكان الذي تريد دمجه فيه.بمجرد الانتهاء من هذا الإعداد للدمج، يصبح الدمج جيدًا بشكل عام.فأنت بحاجة إلى حل جميع التعارضات ثم إرسال نسخة العمل المدمجة إلى المستودع.

إذا كان بإمكان Mercurial أن يجعل تكوين الدمج أسهل، فيمكنني أن أقول إن ذلك سيجعل الدمج أسهل بنسبة 100٪ من Subversion.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top