البحث في الموقع
المحتوى عن 'merge'.
-
يعرض هذا المقال أساسيات التفريع والدمج في Git. نبدأ بمثال سهل لسيناريو يحدث كثيرا أثناء تطوير البرمجيات ونرى كيفية تطبيقه على التفريع والدمج. لنفترض حدوث الخطوات التالية: كنت تعمل على موقع ويب وأنجزت الجزء الأهم وهو الآن مفتوح للزوار. أنشأت تفريعا جديدا وبدأت العمل على ميزات ستضيفها لاحقا للموقع. عند هذه النقطة وردك اتصال يخبرك عن مشكل في الموقع. المشكل خطير ويحتاج حلا سريعا. تنتقل لنسخة الموقع الموجودة على بيئة الإنتاج (إصدار الموقع المفتوح للزوار). أي أنك انتقلت للتفريع الذي أطلقت منه الموقع (وليكن التفريع master). تنشئ تفريعا جديدا انطلاقا من تفريع الإنتاج بهدف إصلاح الخلل (الترقيع). تعمل على التفريع الجديد وتختبر التعديلات حتى تتأكد من جاهزيتك لإضافتها إلى بيئة الإنتاج. تدمج تفريع الترقيع مع تفريع الإنتاج وتدفع التغييرات إلى الموقع. أصلحت المشكل وبإمكانك الآن العودة إلى تفريع تحسين الميزات الذي كنت تعمل عليه قبل ورود الاتصال. المبادئ الأساسية للتفريع نفرض أنك تعمل على مشروع سبق أن أضفت إليه إيداعين. سجل إيداعات مستقيم قررت أنك ستعمل على إضافة الميزة رقم 53. تنشئ لهذا الغرض تفريعا جديدا. لإنشاء تفريع والانتقال للعمل عليه في نفس الوقت نستخدم الأمر git checkout مع الخيار b-: git checkout -b iss53 Switched to a new branch "iss53" هذا الأمر هو اختصار للأمرين: git branch iss53 git checkout iss53 إنشاء مؤشر تفريع جديد تنفيذ أمر git checkout يعني نقل المؤشر HEAD ليحيل إلى التفريع iss53. استمريت في العمل على موقعك، وتنفيذ إيداعات: vim index.html git commit -a -m 'added a new footer [issue 53]' وهو ما يجعل التفريع iss53 يتقدم بتتالي الإيداعات: تقدّم التفريع iss53 بتوالي الإيداعات يأتي الآن الاتصال الذي ينبئ بوجود مشكل في الموقع؛ ويجب التغلب على هذا المشكل في أقرب وقت. لا تحتاج مع Git لنشر الترقيع العاجل مع ترقيع الميزة 53؛ كما أنك لا تحتاج لبذل الكثير من الجهد للتراجع عن التعديلات التي أضفتها أثناء عملك على الميزة 53 حتى تعود إلى حالة الموقع الموجود الآن أمام الزوار. كل ما عليك فعله هو العودة إلى التفريع الرئيس master وترك التفريع iss53 لحين الفراغ من العمل العاجل. انتبه إلى أن Git لن يسمح لك بالانتقال إلى تفريع جديد إن كان مجلد العمل أو منطقة الإدراج يحوي تغييرات تتعارض مع التفريع الذي تريد الانتقال إليه. توجد طرق للالتفاف حول هذا الأمر، وهي ادّخار الإيداعات Stashing وتصحيحها Amending وهو ما سنتطرّق إليه لاحقا عند الحديث عن الادّخار والتنظيف Cleaning. سنفترض في الوقت الحالي أن جميع التعديلات أودعت وبإمكننا الانتقال إلى التفريع الرئيس: git checkout master Switched to branch 'master' يكون مجلد العمل في المشروع بالوصول إلى هذه النقطة مماثلا تماما لما كان عليه قبل بدء العمل على الميزة 53، ويمكنك الآن التركيز على العلة العاجلة. من المهم تذكر هذا الأمر: يعيد Git عند الانتقال إلى تفريع، مجلد العمل إلى ما كان عليه بعد آخر مرة نفّذت فيها إيداعا على هذا التفريع. فيضيف ملفات وينقل أخرى أو يغيرها تلقائيا للتأكد من أن نسخة مجلد العمل مطابقة لما كان عليه بعد آخر عملية إيداع على التفريع. لدينا ترقيع عاجل يجب إصداره. ننشئ تفريعا خاصا hotfix للعمل على إصدار ترقيع في أقرب وقت: git checkout -b hotfix Switched to a new branch 'hotfix' vim index.html git commit -a -m 'fixed the broken email address' [hotfix 1fb7853] fixed the broken email address 1 file changed, 2 insertions(+) إنشاء تفريع hotfix انطلاقا من التفريع master يمكن الآن اختبار التعديلات والتأكد من أن الترقيع يؤدي العمل المطلوب ثم بعد ذلك ندمج التفريع hotfix (باستخدام أمر git merge) مع التفريع الرئيس لنشره على بيئة الإنتاج. ننفذ الأوامر التالية لهذا الغرض: git checkout master git merge hotfix Updating f42c576..3a0874c Fast-forward index.html | 2 ++ 1 file changed, 2 insertions(+) لاحظ جملة fast-forward (تقدّم سريع) بعد تنفيذ أمر الدمج. يعود السبب في ذلك إلى أن الإيداع الذي يشير إليه التفريع الذي دمجت فيه يوجد ضمن سوابق الإيداع الذي دمجته. بعبارة أخرى؛ عندما تريد دمج إيداع “أ” مع إيداع “ب” يوجد من بين سوابق الإيداع المدموج ("أ") فإن Git يسهّل الأمر بتقديم مؤشر التفريع “ب” ليحيل إلى الإيداع “أ”؛ يفعل Git هذا الأمر بسبب عدم وجود إيداعات متنافرة بين التفريعين لدمجها. بمعنى أنه في حالتنا لم يطرأ أي إيداع على التفريع master منذ إنشاء التفريع hotfix. نقول في هذه الحالة إن Git أجرى تقدما سريعا fast-forward. توجد التعديلات الآن في اللقطة التي يشير إليها التفريع master ويمكن نشر الترقيع ليصبح متاحا للعموم. التقدم السريع للتفريع master إلى التفريع hotfix أنت جاهز بعد نشر الترقيع العاجل للعودة إلى العمل الذي انقطعت عنه. لكن يجب أولا حذفُ تفريع hotfix الذي لم تعد تحتاج إليه؛ تفريع master يشير الآن إلى نفس الإيداع. يمكن حذف التفريع hotfix باستخدام أمر git branch مع خيار d-: git branch -d hotfix Deleted branch hotfix (3a0874c). يمكن العودة إلى التفريع iss53 واستكمال العمل على الميزة 53: git checkout iss53 Switched to branch "iss53" vim index.html git commit -a -m 'finished the new footer [issue 53]' [iss53 ad82d7a] finished the new footer [issue 53] 1 file changed, 1 insertion(+) استكمال العمل على الميزة 53 يجب الانتباه هنا إلى أن العمل المضاف إلى التفريع hotfix غير موجود في ملفات التفريع iss53. يوجد لديك خياران لإضافة تعديلات hotfix؛ إما دمج التفريع الرئيس في تفريع iss53 أو الانتظار حتى تكمل العمل على التفريع iss53 ثم تدمجه في التفريع الرئيس. المبادئ الأساسية لدمج التفريعات أكملت العمل على الميزة 53 وأنت جاهز لدمجها في التفريع الرئيس. يجري دمج التفريع iss53 في التفريع الرئيس بنفس الطريقة التي دمجنا بها التفريع hotfix في التفريع الرئيس: الانتقال إلى التفريع الرئيس بالأمر git checkout ثم تنفيذ أمر الدمج: git checkout master Switched to branch 'master' git merge iss53 Merge made by the 'recursive' strategy. index.html | 1 + 1 file changed, 1 insertion(+) يوجد اختلاف بين الدمج في هذه الحالة ودمج التفريع hotfix السابق. مصدر الاختلاف هو حدوث إيداعات على كل من التفريعين بالتوازي؛ الإيداع الذي يشير إليه التفريع الرئيس الآن ليس هو الإيداع الذي كان يشير إليه عند إنشاء التفريع iss53. يعني هذا أن على Git اتخاذ طريقة مغايرة للتقدم السريع آنفة الذكر. ينفذ Git في هذه الحالة ما يعرف بالدمج الثلاثي Three-way merge فيستخدم اللقطتين المشار إليهما في الصورة أدناه والإيداع المشترك بين الفرعين. 3 لقطات مستخدمة في الدمج ينشئ Git، بدلا من تقديم المؤشر إلى آخر إيداع في التفريع iss53 مثل ما فعل مع التفريع hotfix، ينشئ لقطة جديدة ناتجة عن الدمج الثلاثي، وينشئ تلقائيا إيداعا جديدا يشير إلى اللقطة الجديدة. يُسمّى هذا الإيداع بإيداع الدمج Merge commit، ويتميز بكونه جزءا من متتاليتي إيداعات (أي أن له سابقين). إيداع دمج تجدر الإشارة هنا إلى أن Git يحدّد الإيداع الأفضل من بين الإيداعات السابقة لاستخدامه قاعدة للدمج. يختلف الأمر عن نظم إدارة نسخ أخرى مثل CVS وSubversion (قبل الإصدار 1.5) يُطلب فيها من المطور تحديد أفضل قاعدة إيداعات للدمج وفقا لها؛ وهو ما يجعل دمج التفريعات في Git أسهل كثيرا من النظم الأخرى. لم نعد نحتاج الآن، بعد دمج الميزة في التفريع الرئيس، للتفريعة 53. يمكن إغلاق التذكرة Ticket في نظام إدارة التذاكر لديك وحذف التفريع: git branch -d iss53 التعارض في عمليات الدمج لا تجري الأمور دائما بنفس السهولة المذكورة في الفقرة السابقة. إن غيّرت نفس الأجزاء من نفس الملف في فرعين تريد دمجهما فلن يكون بمقدور Git دمجهما بطريقة صحيحة. مثلا، إن عدّل العمل على الميزة 53 والترقيع في التفريع hotfix نفس الجزء من نفس الملف فسيظهر لديك تعارض Conflict في الدمج كما في المثال أدناه: git merge iss53 Auto-merging index.html CONFLICT (content): Merge conflict in index.html Automatic merge failed; fix conflicts and then commit the result. لم ينشئ Git في المثال أعلاه إيداعا للدمج؛ بل أوقف عملية الدمج إلى أن تحل مشكلة التعارض. إن أردت رؤية الملفات التي لم تطلها عملية الدمج بعد فيمكنك تنفيذ الأمر git status: git status On branch master You have unmerged paths. (fix conflicts and run "git commit") Unmerged paths: (use "git add <file>..." to mark resolution) both modified: index.html no changes added to commit (use "git add" and/or "git commit -a") تظهر جميع الملفات التي يوجد بها تعارض يمنع دمجها تحت بند Unmerged (غير مدموج). يضيف Git علامات قياسية لحل التعارض إلى الملفات المعنية ليمكن للمطور فتحها ومن ثم حلّ التعارضات. يحوي الملف فقرة تشبه ما يلي: <<<<<<< HEAD:index.html <div id="footer">contact : email.support@github.com</div> ======= <div id="footer"> please contact us at support@github.com </div> >>>>>>> iss53:index.html يعني هذا أن النسخة التي يحيل إليها المؤشر HEAD هي تلك الموجودة في الأعلى (كل ما يوجد فوق الخط ======)؛ بينما يظهر محتوى الملف الموجود في التفريع iss53 في الأسفل. للتذكير، يحيل المؤشر HEAD إلى التفريع الرئيس الآن، ويعود السبب في ذلك إلى أننا انتقلنا إليه بتنفيذ الأمر git checkout قبل محاولة الدمج. يجب اختيار محتوى أحد الملفين أو دمجهما يدويا. يمكن على سبيل المثال تغيير كامل الجزء المعلّم (يبدأ بـ<<<<<<< وينتهي بـ >>>>>>>) ووضع محتوى جديد مكانه: <div id="footer"> please contact us at email.support@github.com </div> يحوي هذا الحل جزءًا من كل فقرة، ويُلاحظ أن الأسطر >>>>>>>، <<<<<<< و ======= اختفت بالكامل. نفذ أمر git add على كل ملف بعد التخلص من التعارض. إضافة ملف به تعارض إلى منطقة الإدراج في Git يعني أن التعارض في الملف حُلّ. نفّذ أمر git mergetool إن أردت استخدام أداة رسومية لحل التعارضات. يُظهِر الأمر الأداة الرسومية المناسبة لحل التعارضات: git mergetool This message is displayed because 'merge.tool' is not configured. See 'git mergetool --tool-help' or 'git help config' for more details. 'git mergetool' will now attempt to use one of the following tools: opendiff kdiff3 tkdiff xxdiff meld tortoisemerge gvimdiff diffuse diffmerge ecmerge p4merge araxis bc3 codecompare vimdiff emerge Merging: index.html Normal merge conflict for 'index.html': {local}: modified file {remote}: modified file Hit return to start merge resolution tool (meld): اضغط زر Enter للبدء في استخدام الأداة الافتراضية (في المثال أعلاه يظهر اسم الأداة meld بين قوسين لأن المستخدم يشغّل نظام لينكس). إن أردت استخدام أداة مغايرة فيمكنك الاختيار بين الأدوات المدعومة التي يسردها أمر git mergetool مباشرة بعد جملة one of the following tools ثم كتابة اسم الأداة والضغط على زر Enter. يسألك Git بعد الخروج من الأداة ما إذا كان الدمج ناجحا. فإن أجبت بنعم (زر y على لوحة المفاتيح) فإنه يعلمّ الملفات للإشارة لتجاوز التعارض ويضيفها بالتالي إلى منطقة الإدراج. يمكن تنفيذ أمر git statusمرة أخرى للتأكد من أن جميع التعارضات حُلّت: git status On branch master All conflicts fixed but you are still merging. (use "git commit" to conclude merge) Changes to be committed: modified: index.html ثم تنفيذ أمر الإيداع git commit لاستكمال الدمج، بعد التأكد من أن جميع الملفات التي يوجد بها تعارض أضيفت إلى منطقة الإدراج. تبدو رسالة الإيداع المبدئية على النحو التالي (عند تنفيذ أمر git commit بعد دمج الملفات المتعارضة): Merge branch 'iss53' Conflicts: index.html # # It looks like you may be committing a merge. # If this is not correct, please remove the file # .git/MERGE_HEAD # and try again. # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # On branch master # All conflicts fixed but you are still merging. # # Changes to be committed: # modified: index.html # يمكنك تعديل الرسالة لإضافة تفصيلات عن كيفية حل التعارض إن كنت ترى أن ذلك سيفيد الآخرين عند النظر في هذا الدمج في المستقبل. لماذا فعلت ما فعلت، خصوصا إن لم يكن بديهيا. ترجمة -بتصرف- للفصل Git Branching - Basic Branching and Merging من كتاب Pro Git لصاحبه Scott Chacon.
-
توجد طريقتان أساسيتان في Git لتضمين التعديلات من تفريع إلى آخر: merge و rebase. يشرح هذا المقال ماهية إعادة تأسيس التفريعات Rebasing، كيفيتها، الفائدة منها والحالات التي يجدر بك عدم استخدام إعادة التأسيس فيها. مبادئ إعادة التأسيس يمكن بالعودة إلى المثال في درس المبادئ الأساسية لدمج التفريعات رؤية تمايز أعمالك بإضافة إيداعات إلى كلٍّ من التفريعين. استخدام أمر git merge هو أسهل طريقة، مثل ما رأينا سابقا، لتضمين تفريع في آخر. ينفّذ الأمرُ الدمجَ الثلاثي بين آخر لقطتين في كلّ تفريع (C3 وC4) واللقطة المشتركة الأقرب (C2) منشئا بذلك لقطة (وإيداعا) جديدة. إلا أنه توجد طريقة أخرى: يمكنك أخذ الترقيع Patch الذي أضافه الإيداع C4 ثم تطبيقه على الإيداع C3. تسمى هذه العملية في Git بإعادة التأسيس. يتيح الأمر rebase أخذ جميع الإيداعات التي أضيفت إلى تفريع وتكرارها على تفريع آخر. يكون تطبيق هذا المبدأ على المثال في الصورة بتنفيذ الأمر على النحو التالي: git checkout experiment git rebase master First, rewinding head to replay your work on top of it... Applying: added staged command يعمل الأمر بالرجوع إلى الإيداع السابق المشترك بين التفريعين (التفريع الذي تعمل عليه الآن، والتفريع الذي تريد إعادة التأسيس عليه)، الحصول على التغييرات التي أدرجها كل إيداع على التفريع الحالي وتخزينها في ملف ظرفي، ضبط التفريع الحالي على آخر إيداع في التفريع الذي نريد إعادة التأسيس عليه ثم في الأخير تطبيق التعديلات بالترتيب. نستطيع بالوصول إلى هذه النقطة العودة إلى التفريع master وتنفيذ دمج بتقدم سريع: git checkout master git merge experiment يشير الإيداع 'C4 إلى نفس اللقطة التي يشير إليها الإيداع C5 في مثال الدمج الذي تحدثنا عنه في البداية. لا يوجد فرق في المنتوج النهائي بين الاثنين؛ إلا أن إعادة التأسيس تجعل سجل التعديلات أكثر وضوحا. يبدو سجل الإيداعات في تفريع أعيد تأسيسه خطيًّا: تظهر الأعمال كما لو أنها حدثت بالتتالي، حتى لو كان الواقع أنها كانت بالتوازي. يُلجَأ عادة لتأسيس التفريعات للتأكد من أن الإيداعات تُطبَّق دون مشاكل على تفريع بعيد؛ مثلا عند المشاركة في مشروع لا تتولى صيانته. تعمل في هذه الحالة على تفريع ثم تعيد تأسيس التفريع على origin/master عندما تكون جاهزا لإرسال الترقيع إلى المشروع الرئيس. لن يحتاج مسؤول المشروع في هذه الحالة إلا إلى دمج سريع. انتبه إلى أن اللقطة التي يشير إليها التفريع هي نفسها، سواء كانت الأخيرة من إيداعات بعد إعادة تأسيس التفريع أو إيداع دمج. وجه الاختلاف هو فقط سجل التغييرات. تكرّر إعادة التأسيس التغييرات من خط عمل على آخر بالترتيب الذي حدثت به في حين يأخذ الدمج نقطتي النهاية ويدمجهما معا. إعادات تأسيس متقدمة يتيح Git إمكانية تطبيق إعادة التأسيس على أمور أخرى غير التفريع المستهدف بإعادة التأسيس. نأخذ المثال الموضَّح في الصورة أدناه. أنشأت تفريعا جديدا باسم server (تفريع موضوع Topic branch) لإضافة ميزات من جهة الخادوم إلى مشروعك وأضفت إيداعا إلى هذا التفريع؛ ثم أنشأت بعدها تفريعا جديدا لميزات تعمل في جانب العميل client وأضفت عليه إيداعات متتابعة. عدت في الأخير إلى تفريع server وأضفت إليه إيداعات أخرى. نريد الآن دمج التغييرات في جانب العميل إلى التفريع الرئيس وفي نفس الوقت ترك التعديلات في جانب الخادوم لاختبارها أكثر. نستخدم خيار onto-- مع أمر git rebase لأخذ الإيداعات الموجودة على التفريع client دون أن تكون موجودة على server (أي الإيداعات C8 وC9): git rebase --onto master server client يمكن تفسير الأمر السابق بـ”افحص تفريع client، اعثر على الإيداعات التالية للإيداع المشترك بينه والتفريع server ثم طبقها على التفريع master“. يبدو الأمر معقّدا إلا أن النتيجة مذهلة. يمكن بعدها تطبيق دمج سريع على التفريع الرئيس: git checkout master git merge client نرغب الآن في تضمين التفريع server أيضا. تمكننا إعادة تأسيس التفريع server على التفريع master دون الحاجة لفحصه أولا بتنفيذ الأمر [git rebase [basebranch] [topicbranc. يفحص الأمر تفريع الموضوع (أي التفريع server في هذه الحالة) تلقائيا ثم يؤسسه على التفريع القاعدي (master): git rebase master server يُعيد الأمر تأسيس التفريع server على التفريع master على النحو الموضَّح في الصورة التالية. نطبق دمجا سريعا للتفريع القاعدي master: git checkout master git merge server يمكن الآن حذف التفريعين server وclient لأن جميع الأعمال فيهما أدمجت في التفريع الرئيس ولم تعد بحاجة إليها. git branch -d client git branch -d server يبدو سجل التعديلات كما يظهر في الصورة أدناه. مشاكل إعادة التأسيس يمكن إجمال مخاطر إعادة تأسيس التفريعات في النصيحة التالية: لا تُعِد تأسيس إيداعات موجودة خارج مستودعك. تهجُر عندما تعيد تأسيس تفريع، إيداعاتٍ موجودةً وتبدلها بأخرى جديدة مشابهة إلا أنها مختلفة. تصبح الأمور صعبة وغير مرتبة عند استخدام إعادة التأسيس بما يخالف النصيحة أعلاه، مثلا عندما تدفع إيداعات إلى مستودع مشترك ثم يجلبها آخرون ويعملون عليها، ثم تعيد كتابة الإيداعات باستخدام أمر git rebase وتدفعها إلى المستودع مرة أخرى. سيحتاج مشاركوك في هذه الحالة لإعادة دمج أعمالهم ويمكن أن تحدث مشاكل عندما يريدون دفع أعمالهم بعدك. فلنأخذ مثالا لحالة يمكن أن تؤدي فيها إيداعات - أعيد تأسيسها ووُفِّرت للعموم - إلى مشاكل. نفترض أنك نسخت مستودعا من خادوم مركزي ثم أجريت أعمالا عليه. يبدو سجل الإيداعات على النحو الموضَّح في الصورة التالية. يعمل أحدهم في هذه الأثناء على إضافة تعديلات إلى المستودع من ضمنها دمج تفريع ثم يدفع النتيجة إلى الخادوم المركزي، تأتي أنت وتفتش عن الجديد على المستودع البعيد وتدمج التفريع البعيد الجديد إلى عملك؛ يصبح سجل الإيداعات على النحو التالي. يقرّر الشخص الذي دفع التفريع المدموج التراجع وإعادة تأسيس التفريع بدلا من ذلك؛ ينفذ أمر: git push --force لتغيير سجل الإيداعات على الخادوم، ثم تأتي أنت للتفتيش عن جديد المستودع البعيد وتجلب الإيداعات الجديدة. أنتما الآن في ورطة: تنفيذك لأمر: git pull سينشئ إيداعَ دمج يتضمّن سجلي التعديلات وسيبدو المستودع لديك كالتالي: سيظهر عند تنفيذ أمر git log على سجل التعديلات أعلاه إيداعان لديهما نفس الكاتب، التاريخ والرسالة؛ أمر مربك. علاوة على ذلك، يؤدي دفع بيانات بسجل التغيير هذا إلى الخادوم إلى إدخال كل هذه الإيداعات المعاد تأسيسها إلى الخادوم وهو ما سيربك الآخرين أكثر. من الآمَن في هذه الحالة افتراضُ أن المطوّر الآخر لا يريد أن يَبقى الإيداعان C4 وC6 في سجل الإيداعات؛ ولهذا السبب أعاد التأسيس أصلا. إصلاح ما أفسدته إعادة التأسيس يوفر Git آليات إضافية لحالات مثل التي رأيناها في الفقرة السابقة. التحدي في المواقف التي يدفع فيها أحد أعضاء الفريق تعديلات تغير تلك التي أعدت تأسيس عملك عليها هو التفريق بين عملك وبين ما أعيدت كتابته. يحسب Git، إضافة إلى مجموع التحقق (دالة SHA-1) الخاص بالإيداع مجموع تحقق خاص بالترقيع Patch الذي أضيف مع الإيداع؛ يسمّى مجموع التحقق هذا بمعرّف الترقيع Patch id. يمكن لـGit، عندما تجلب بيانات أعيدت كتابتها ثم تعيد التأسيس لها على الإيداعات الجديدة من الشريك، أن يتعرّف على الإيداعات الخاصة بك ثم يطبقها على التفريع الجديد. بدلا من تنفيذ أمر git merge بعد أن نفّذ الشريك أمر git push --force في المثال السابق (الحالة الموضَّحة في الصورة قبل الأخيرة) نفّذ الأمر git rebase teamone/master وسيقوم Git بالتالي: تحديد الإيداعات الخاصة بتفريعك فقط (أي الإيداعات C6، C4، C3، C2 وC7). التعرف على الإيداعات التي ليست إيداعات دمج (C3، C2 وC4). تحديد الإيداعات التي لم تُعد كتابتها في التفريع الوجهة (التفريعان C2 وC3 فالإيداعان C4 و'C4 هما نفس الترقيع، أي أن تعديلاتهما هي نفسها). تطبيق هذه الإيداعات على التفريع teamone/master. ينتج عن الخطوات المتّبعة الوضعية التالية بدلا من تلك التي كنا سنجد فيها أنفسنا لو نفّذنا أمر git pull. تعمل الطريقة أعلاه فقط إن كان الإيداعان C4 و'C4 الذين أضافهما شريكك متطابقين تقريبا؛ وإلا فإن أمر rebase لن يكون قادرا على معرفة أيهما المكرَّر وسيضيف إيداعا جديدا مشابها لـ'C4 (يُحتمَل جدّا ألا يُطبَّق نظرا لأن التعديلات ستكون غالبا موجودة في مكان ما). يمكن تسهيل الأمر بتنفيذ git pull --rebase بدلا من git pull عادي؛ أو التأسيس يدويا بتنفيذ أمر git fetch تتبعه بـ git rebase teamone/master في هذه الحالة. توجد طريقة لجعل خيار rebase-- مبدئيا عند تنفيذ أمر git pull وهي إعداد المعطى pull.rebase في الإعدادات ليأخذ القيمة git config --global pull.rebase true. ستجري الأمور بخير ما دمت تستخدم إعادة التأسيس بوصفها طريقة لتنسيق الإيداعات والعمل عليها قبل دفعها وما ظللت ملتزما بإعادة تأسيس الإيداعات التي لم تتوفر أبدا للعموم دون غيرها. في الجانب الآخر، تتعرّض للكثير من المخاطر بإعادة التأسيس على إيداعات سبق دفعها إلى مستودعات عمومية ويمكن أن يكون بعض شركائك أسسوا عملهم عليها. تأكد من تنفيذ جميع أعضاء الفريق لأمر git pull --rebase لمحاولة التقليل من المشاكل بعد إعادة تأسيس أحدهم على إيداعات جلبها من المستودع العمومي. إعادة التأسيس أم الدمج؟ ربما تتساءل الآن بعد الخوض في كلّ من إعادة التأسيس والدمج، أيهما أنسب؟ سنعود إلى الوراء قليلا قبل الإجابة على التساؤل لندقّق في معنى سجل المستودع. يمكن رؤية الموضوع على أساس أن سجل المستودع هو تسجيل لما حدث فيه، بمعنى أنه وثيقة تاريخية قيّمة بذاتها، ولا يجوز التلاعب بها. يعدّ تغيير السجلّ من وجهة النظر هذه خطأ كبيرا؛ فذلك يعني تزوير الوقائع. ماذا لو حدثت فوضى في المستودع بعد متتالية من الإيداعات؟ هذه هي الوقائع ويجب أن تظل مسجّلة تقول وجهة النظر هذه. توجد رؤية مغايرة للموضوع، تقول إن سجل الإيداعات هو رواية لكيفية بناء المشروع. يحتاج دليل صيانة البرنامج لنفس الحذر الذي يتطلبه نشر كتاب، فلا يجوز أن تنشر كتابا مازال في طور المسودة. يتبنى وجهة النظر هذه من يستخدمون أدوات مثل git rebaseوgit filter-branch لسرد القصة بأفضل طريقة للقراء المستقبليين. يتضح الآن أن سؤال أيها أستخدم، إعادة التأسيس أم الدمج؟ ليس بتلك السهولة. Git أداة قوية تسمح بفعل الكثير من الأشياء للسجّل وبه؛ إلا أن كلّ فريق مختلف وكذلك المشاريع. يعود الأمر إليك، بعد فهم طريقة عمل الاثنين، لاختيار ما يناسب الفريق الذي تعمل معه والمشروع الذي تعمل عليه. المبدأ العام للحصول على أفضل ما في الطريقتين هو إعادة تأسيس التعديلات المحلية التي لم تشارَك بعد قبل أن تدفعها من أجل تقديم القصة؛ والابتعاد تماما عن إعادة تأسيس أي شيء سبق دفعه إلى مستودع عمومي. خاتمة غطينا في هذه السلسلة أساسيات التفريع والدمج في Git. يجدر بك أن تكون مرتاحا للعمل على إنشاء التفريعات الجديدة والانتقال للعمل عليها، التبديل بين التفريعات ودمجها ودمج التفريعات المحلية معا؛ بالإضافة إلى تشارك التفريعات بدفعها إلى خادوم مشترك، العمل مع آخرين على تفريعات مشتركة وإعادة تأسيس تفريعاتك فبل أن تشاركها. الخطوة الموالية هي معرفة ما تحتاجه لتشغيل خادوم Git خاص بك لتشارك المستودعات. ترجمة -بتصرف- للفصل Git Branching - Rebasing من كتاب Pro Git لصاحبه Scott Chacon.