git - كيفية حل النزاعات دمج في جيت





git-merge merge-conflict-resolution git-conflict-resolution (26)


هذه الإجابات هي إضافة بديل لمستخدمي VIM مثل I الذي يفضل القيام بكل شيء داخل المحرر.

TL، DR

جاء Tpope مع هذا البرنامج المساعد الكبير ل VIM دعا fugitive . بمجرد التثبيت يمكنك تشغيل :Gstatusللتحقق من الملفات التي بها تعارض :Gdiffوفتح Git في دمج بطرق ثلاث طرق.

بمجرد دمج 3 طرق ، سيسمح لك الهارب بإدخال التغييرات على أي فرع من الفروع التي تقوم بدمجها بالطريقة التالية:

  • :diffget //2، احصل على تغييرات من الفرع الأصلي ( الرأس ):
  • :diffget //3 ، احصل على تغييرات من دمج الفرع:

بمجرد الانتهاء من دمج الملف ، اكتب :Gwriteفي المخزن المؤقت المدمج. أصدرت Vimcast video رائع يشرح بالتفصيل هذه الخطوات.

هل هناك طريقة جيدة لشرح كيفية حل نزاعات الدمج في جيت؟




أنا أتابع العملية أدناه.

عملية إصلاح التعارض الدمج:

  1. أولاً ، اسحب الأحدث من فرع الوجهة الذي تريد الدمج إليه git pull origin develop

  2. أثناء حصولك على أحدث ما تم التوصل إليه من الوجهة ، يمكنك الآن حل التعارض يدويًا في بيئة تطوير متكاملة (IDE) عن طريق حذف هذه الأحرف الزائدة.

  3. يمكنك git addإضافة هذه الملفات المحررة إلى قائمة git بحيث يمكن أن تكون commitوإلى pushنفس الفرع الذي تعمل عليه.

  4. كما git addهو الحال ، افعل git commitلارتكاب التغييرات.

  5. الآن دفع التغييرات إلى فرع عملك من قبل git push origin HEAD

هذا هو وسوف ترى حلها في طلب السحب الخاص بك إذا كنت تستخدم Bitbucket أو GitHub.




إذا كنت تستخدم intelliJ كـ IDE حاول دمج الأم إلى الفرع الخاص بك بواسطة

git checkout <localbranch>
git merge origin/<remotebranch>

وسوف تظهر كل الصراعات مثل هذا

A_MBPro: test anu $ git merge origin / Auto-merging src / test / java / com /.../ TestClass.java CONFLICT (content): دمج التعارض في src / test / java / com /.../ TestClass.java

الآن لاحظ أن الملف TestClass.java يظهر باللون الأحمر في intelliJ ستظهر أيضًا الحالة git

Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified:   src/test/java/com/.../TestClass.java

فتح الملف في intelliJ ، سيكون لديك أقسام مع

  <<<<<<< HEAD
    public void testMethod() {
    }
    =======
    public void testMethod() { ...
    }
    >>>>>>> origin/<remotebranch>

حيث يكون HEAD عبارة عن تغييرات على الفرع المحلي والأصل / هو التغييرات من الفرع البعيد. احتفظ هنا بالأشياء التي تحتاجها وقم بإزالة الأشياء التي لا تحتاج إليها.بعد ذلك يجب أن تفعل الخطوات العادية. هذا هو

   git add TestClass.java
   git commit -m "commit message"
   git push



انظر كيف يتم تقديم التعارضات ، أو في Git ، git merge وثائق git merge لفهم ما هي علامات دمج التعارض.

يشرح قسم " كيفية حل التعارضات" أيضًا كيفية حل التعارضات :

بعد رؤية التعارض ، يمكنك تنفيذ أمرين:

  • تقرر عدم دمج. عمليات التنظيف الوحيدة التي تحتاج إليها هي إعادة تعيين ملف الفهرس إلى HEAD الالتزام بالعكس 2. ولتنظيف التغييرات في شجرة العمل التي تم إجراؤها بواسطة 2. و 3؛ git merge --abort يمكن استخدام git merge --abort لهذا الغرض.

  • حل النزاعات. ستحدد بوابة التعارضات في شجرة العمل. تحرير الملفات إلى الشكل و git add إلى الفهرس. استخدام git commit بختم الصفقة.

يمكنك العمل من خلال التعارض مع عدد من الأدوات:

  • استخدم mergetool. git mergetool لإطلاق mergetool رسومية والتي ستعمل من خلال الدمج.

  • انظر إلى الاختلافات. سيعرض git diff MERGE_HEAD ، يبرز التغييرات من كل من الإصدارين HEAD و MERGE_HEAD .

  • انظر إلى الاختلافات من كل فرع. git log --merge -p <path> على الإصدارات أولاً لإصدار HEAD ثم إصدار MERGE_HEAD .

  • انظر إلى النسخ الأصلية. git show :1:filename يعرض السلف المشترك ، git show :2:filename يُظهر إصدار HEAD ، و git show :3:filename يُظهر إصدار MERGE_HEAD .

يمكنك أيضًا قراءة حول دمج علامات التعارض وكيفية حلها في قسم Pro Git Book Basge Conflicts .




إذا كنت تلتزم بعمليات صغيرة متكررة ، فابدأ بالبحث عن تعليقات الالتزام باستخدام git log --merge . ثم سوف git diff تظهر لك الصراعات.

بالنسبة إلى التعارضات التي تتضمن أكثر من بضعة أسطر ، يكون من الأسهل رؤية ما يحدث في أداة واجهة المستخدم الرسومية الخارجية. أنا أحب opendiff - GIT كما يدعم vimdiff ، gvimdiff ، kdiff3 ، tkdiff ، meld ، xxdiff ، الخروج من مربع ويمكنك تثبيت الآخرين: git config merge.tool "your.tool" سوف تحدد الأداة التي اخترتها ثم git mergetool بعد أن يعرض لك دمج فاشل الاختلافات في السياق.

في كل مرة تقوم فيها بتحرير ملف لحل تعارض ، ستقوم git add filename بتحديث الفهرس ولن يعود الاختلاف معه. عندما يتم التعامل مع جميع التعارضات وملفاتها تمت git add git commit ، ستقوم git commit بإكمال الدمج الخاص بك.




جرب: git mergetool

يفتح واجهة المستخدم الرسومية التي تخطو خلال كل تعارض ، ويمكنك اختيار كيفية الدمج. في بعض الأحيان يتطلب الأمر بعض التعديل اليدوي بعد ذلك ، ولكنه عادة ما يكون كافيا بحد ذاته. إنه أفضل بكثير من فعل كل شيء باليد بالتأكيد.

وفقًا لتعليقJoshGlover:

لا يقوم الأمر بالضرورة بفتح واجهة المستخدم الرسومية إلا إذا قمت بتثبيت واحد. تشغيل git mergetool vimdiff لي أدى إلى استخدام vimdiff . يمكنك تثبيت أحد الأدوات التالية لاستخدامها بدلاً من ذلك: opendiff ، kdiff3 ، tkdiff ، xxdiff ، xxdiff ، tortoisemerge ، gvimdiff ، diffuse ، ecmerge ، p4merge ، araxis ، vimdiff ، emerge .

أدناه هو الإجراء عينة لاستخدام vimdiff لـ تعارضات دمج حل. على أساس هذا الرابط

الخطوة 1 : قم بتشغيل الأوامر التالية في الجهاز الخاص بك

git config merge.tool vimdiff
git config merge.conflictstyle diff3
git config mergetool.prompt false

سيؤدي ذلك إلى تعيين vimdiff كأداة الدمج الافتراضية.

الخطوة 2 : تشغيل الأمر التالي في المحطة الطرفية

git mergetool

الخطوة 3 : سترى عرض vimdiff بالتنسيق التالي

  +----------------------+
  |       |      |       |
  |LOCAL  |BASE  |REMOTE |
  |       |      |       |
  +----------------------+
  |      MERGED          |
  |                      |
  +----------------------+

هذه الاراء هي 4

LOCAL - هذا ملف من الفرع الحالي

BASE - سلف مشترك ، كيف بدا الملف قبل كل من التغييرات

REMOTE - الملف الذي تقوم بدمجه في الفرع الخاص بك

MERGED - دمج النتيجة ، وهذا هو ما يتم حفظه في الريبو

يمكنك التنقل بين طرق العرض هذه باستخدام ctrl+w . يمكنك الوصول مباشرةً إلى طريقة عرض MERGED باستخدام ctrl+w متبوعة ب j .

مزيد من المعلومات حول vimdiff الملاحة here here

الخطوة 4 . يمكنك تعديل طريقة عرض MERGED بالطريقة التالية

إذا كنت ترغب في الحصول على تغييرات من REMOTE

:diffg RE  

إذا كنت ترغب في الحصول على تغييرات من BASE

:diffg BA  

إذا كنت ترغب في الحصول على تغييرات من LOCAL

:diffg LO 

الخطوة 5 . الحفظ والخروج والالتزام والتنظيف

:wqa حفظ والخروج من السادس

git commit -m "message"

git clean إزالة ملفات إضافية (على سبيل المثال * .orig) تم إنشاؤها بواسطة أداة diff.




بالنسبة لمستخدمي Emacs الذين يرغبون في حل تعارضات الدمج بشكل شبه يدوي:

git diff --name-status --diff-filter=U

يعرض كافة الملفات التي تتطلب حل التعارض.

افتح كل ملف من تلك الملفات واحدًا تلو الآخر ، أو كل مرة في:

emacs $(git diff --name-only --diff-filter=U)

عند زيارة مخزن مؤقت يتطلب تعديلات في Emacs ، اكتب

ALT+x vc-resolve-conflicts

سيؤدي هذا إلى فتح ثلاثة مخازن مؤقتة (الألغام الخاصة بهم ، والمخزن المؤقت للإخراج). انتقل عن طريق الضغط على 'n' (المنطقة التالية) ، 'p' (المنطقة السابقة). اضغط على "a" و "b" لنسخ المنجم أو المنطقة الخاصة بهم إلى المخزن المؤقت للإخراج ، على التوالي. و / أو تحرير المخزن المؤقت للإخراج مباشرة.

عند الانتهاء: اضغط على "q". يسألك Emacs إذا كنت تريد حفظ هذا المخزن المؤقت: نعم. بعد الانتهاء من علامة المخزن المؤقت وحلها عن طريق تشغيل من teriminal:

git add FILENAME

عند الانتهاء من جميع أنواع المخازن المؤقتة

git commit

لإنهاء الدمج.




إذا كنت تريد الدمج من فرع (اختبار) إلى إتقان ، فيمكنك اتباع الخطوات التالية:

الخطوة 1: اذهب إلى الفرع

git checkout test

الخطوة 2: git pull --rebase origin master

الخطوة 3: إذا كانت هناك بعض التعارضات ، فانتقل إلى هذه الملفات لتعديلها.

الخطوة 4: إضافة هذه التغييرات

git add #your_changes_files

الخطوة الخامسة: git rebase --continue

الخطوة 6: إذا كان لا يزال هناك تعارض ، ارجع إلى الخطوة 3 مرة أخرى. إذا لم يكن هناك تعارض ، فقم بما يلي:git push origin +test

الخطوة 7: ثم لا يوجد تعارض بين الاختبار والماجستير. يمكنك استخدام الدمج مباشرة.




لأولئك الذين يستخدمون Visual Studio (2015 في حالتي)

  1. إغلاق المشروع الخاص بك في VS. خاصة في المشاريع الكبيرة يميل VS إلى النزول عند الدمج باستخدام واجهة المستخدم.

  2. هل الدمج في القيادة الاوامر.

    بوابة الخروج

    بوابة دمج

  3. ثم افتح المشروع في VS وانتقل إلى Team Explorer -> الفرع. توجد الآن رسالة تقول أن Merge قيد المراجعة ويتم سرد الملفات المتعارضة أسفل الرسالة مباشرةً.

  4. انقر فوق الملف المتعارض وسيكون لديك خيار الدمج ، المقارنة ، أخذ المصدر ، أخذ الهدف. أداة الدمج في VS سهلة الاستخدام للغاية.




يمكن أن يحدث دمج النزاعات في حالات مختلفة:

  • عند تشغيل "git fetch" ثم "git merge"
  • عند تشغيل "git fetch" ثم "git rebase"
  • عند تشغيل "git pull" (وهو في الواقع يساوي أحد الشروط المذكورة أعلاه)
  • عند تشغيل "git stash pop"
  • عندما تقوم بتطبيق تصحيحات بوابة (git patches) (التي يتم تصديرها إلى ملفات ليتم نقلها ، على سبيل المثال ، عبر البريد الإلكتروني)

تحتاج إلى تثبيت أداة دمج متوافق مع Git لحل التعارضات. أنا شخصيا استخدم KDiff3 ، ولقد وجدت أنها لطيفة ومفيد. يمكنك تنزيل إصدار Windows الخاص به هنا:

https://sourceforge.net/projects/kdiff3/files/

راجع للشغل إذا قمت بتثبيت Git Extensions يوجد خيار في معالج الإعداد الخاص به لتثبيت Kdiff3.

ثم تكوين git configs لاستخدام Kdiff كـ mergetool الخاص به:

$ git config --global --add merge.tool kdiff3
$ git config --global --add mergetool.kdiff3.path "C:/Program Files/KDiff3/kdiff3.exe"
$ git config --global --add mergetool.kdiff3.trustExitCode false

$ git config --global --add diff.guitool kdiff3
$ git config --global --add difftool.kdiff3.path "C:/Program Files/KDiff3/kdiff3.exe"
$ git config --global --add difftool.kdiff3.trustExitCode false

(تذكر استبدال المسار بالمسار الفعلي لملف Kdiff exe.)

ثم في كل مرة تواجه فيها تعارضًا للدمج ، تحتاج فقط إلى تشغيل هذا الأمر:

$git mergetool

ثم يفتح Kdiff3 ، ويحاول أولاً حل تعارضات الدمج تلقائيًا. سيتم حل معظم النزاعات بشكل تلقائي وتحتاج إلى إصلاح بقية الصور يدويًا.

إليك ما يبدو عليه Kdiff3:

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

للتحقق من دمج كل شيء بنجاح ، قم بتشغيل الأمر mergetool مرة أخرى ، يجب أن تحصل على هذه النتيجة:

$git mergetool
No files need merging



هناك 3 خطوات:

  1. البحث عن الملفات التي تسبب التعارضات بالأمر

    git status
    
  2. تحقق من الملفات التي ستجد فيها التعارضات التي تحمل علامة

    <<<<<<<<head
    blablabla
    
  3. تغييره بالطريقة التي تريدها ، ثم ارتكبت مع الأوامر

    git add solved_conflicts_files
    git commit -m 'merge msg'
    



استخدام patience

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

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

git merge -s recursive -X patience other-branch

من الوثائق:

With this option, merge-recursive spends a little extra time to avoid 
mismerges that sometimes occur due to unimportant matching lines 
(e.g., braces from distinct functions). Use this when the branches to 
be merged have diverged wildly.

مقارنة مع سلف مشترك

إذا كان لديك تعارض في الدمج وترغب في رؤية ما كان يفكر فيه الآخرون عند تعديل فرعهم ، فمن الأسهل أحيانًا مقارنة فرعهم مباشرة مع السلف المشترك (بدلاً من فرعنا). لذلك يمكنك استخدام merge-base:

git diff $(git merge-base <our-branch> <their-branch>) <their-branch>

عادةً ما تريد فقط مشاهدة التغييرات لملف معين:

git diff $(git merge-base <our-branch> <their-branch>) <their-branch> <file>



git log --merge -p [[--] path]

لا يبدو أنه يعمل دائما بالنسبة لي وعادة ما ينتهي عرض كل الالتزام الذي كان مختلفا بين الفرعين ، يحدث هذا حتى عند استخدام -- لفصل المسار عن الأمر.

ما أفعله للتغلب على هذه المشكلة هو فتح سطرين للأمر وفي عملية واحدة

git log ..$MERGED_IN_BRANCH --pretty=full -p [path]

وفي الآخر

git log $MERGED_IN_BRANCH.. --pretty=full -p [path]

استبدال $MERGED_IN_BRANCH و [path] مع الملف المتعارض. سيقوم هذا الأمر بتسجيل كل الإلتزامات ، في شكل ورقي ، بين ( .. ) مرتين. إذا تركت جانبًا فارغًا كما هو الحال في الأوامر المذكورة أعلاه ، فسيستخدم git تلقائيًا العنوان (الفرع الذي تقوم بدمجه في هذه الحالة).

سيسمح لك هذا بمعرفة ما تم ارتكابه في الملف في الفرعين بعد اختلافهما. إنه عادة ما يسهل حل الصراعات.




يحدث تعارضات دمج عند إجراء تغييرات على ملف في نفس الوقت. هنا كيفية حلها.

git CLI

فيما يلي خطوات بسيطة ما يجب فعله عند الدخول في حالة تعارض:

  1. لاحظ قائمة الملفات التي تم Unmerged paths مع: git status (تحت قسم Unmerged paths ).
  2. حل التعارضات بشكل منفصل لكل ملف بواسطة أحد الأساليب التالية:

    • استخدام واجهة المستخدم الرسومية لحل الصراعات: git mergetool (أسهل طريقة).

    • لقبول الإصدار البعيد / الآخر ، استخدم: git checkout --theirs path/file . سيؤدي هذا إلى رفض أي تغييرات محلية قمت بها لهذا الملف.

    • لقبول المحلية / git checkout --ours path/file ، استخدم: git checkout --ours path/file

      ومع ذلك عليك أن تكون حذرا ، والتغييرات عن بعد أن الصراعات التي أجريت لسبب ما.

      ذات الصلة: ما هو المعنى الدقيق ل "لنا" و "ملكهم" في بوابة؟

    • قم بتحرير الملفات المتعارضة يدويًا وابحث عن كتلة التعليمة البرمجية بين <<<<< / >>>>> ثم اختر الإصدار إما من أعلى أو أسفل ===== . انظر: كيف يتم تقديم النزاعات .

    • يمكن حل تعارضات المسار واسم الملف بواسطة git add / git rm .

  3. وأخيرًا ، راجع الملفات الجاهزة للالتزام باستخدام git status .

    إذا كان لا يزال لديك أي ملفات تحت Unmerged paths ، وقمت بحل التضارب يدويًا ، فتأكد من أن Git تعرف أنك حلته من خلال: git add path/file .

  4. إذا تم حل كافة التعارضات بنجاح ، فقم بإجراء التغييرات من خلال: git commit -a والضغط على بعيد كالمعتاد.

راجع أيضًا: حل تعارض الدمج من سطر الأوامر في GitHub

DiffMerge

لقد نجحت في استخدام DiffMerge الذي يمكنه مقارنة الملفات ودمجها بشكل مرئي على Windows و MacOS و Linux / Unix.

يمكن أن يظهر بشكل بياني التغييرات بين 3 ملفات ويسمح بالدمج التلقائي (عندما يكون ذلك آمنًا) والتحكم الكامل في تحرير الملف الناتج.

مصدر الصورة: DiffMerge (لقطة شاشة لنظام التشغيل Linux)

ببساطة تحميل البرنامج وتشغيل في repo على النحو التالي:

git mergetool -t diffmerge .

ماك

على نظام MacOS ، يمكنك التثبيت عبر:

brew install caskroom/cask/brew-cask
brew cask install diffmerge

وربما (إذا لم يتم توفيره) فأنت تحتاج إلى الغلاف الإضافي البسيط التالي الموجود في المسار الخاص بك (على سبيل المثال /usr/bin ):

#!/bin/sh
DIFFMERGE_PATH=/Applications/DiffMerge.app
DIFFMERGE_EXE=${DIFFMERGE_PATH}/Contents/MacOS/DiffMerge
exec ${DIFFMERGE_EXE} --nosplash "[email protected]"

ثم يمكنك استخدام اختصارات لوحة المفاتيح التالية:

  • - Alt - لأعلى / لأسفل للانتقال إلى التغييرات السابقة / التالية.
  • - Alt - يسار / يمين لقبول التغيير من اليسار أو اليمين

بدلا من ذلك يمكنك استخدام opendiff (جزء من أدوات Xcode) الذي يتيح لك دمج ملفين أو أدلة معا لإنشاء ملف ثالث أو دليل.




هذه حالة استخدام محتملة ، من الأعلى:

ستقوم بإجراء بعض التغييرات ، ولكن ، لا تكون حديثًا:

git fetch origin
git pull origin master

From ssh://[email protected]:22/projectname
 * branch            master     -> FETCH_HEAD
Updating a030c3a..ee25213
error: Entry 'filename.c' not uptodate. Cannot merge.

حتى تحصل على ما يصل إلى التاريخ وحاول مرة أخرى ، ولكن لديك صراع:

git add filename.c
git commit -m "made some wild and crazy changes"
git pull origin master

From ssh://[email protected]:22/projectname
 * branch            master     -> FETCH_HEAD
Auto-merging filename.c
CONFLICT (content): Merge conflict in filename.c
Automatic merge failed; fix conflicts and then commit the result.

لذلك قررت أن تلقي نظرة على التغييرات:

git mergetool

يا لي ، يا ، تغيرت المنبع بعض الأشياء ، ولكن فقط لاستخدام التغييرات الخاصة بي ... لا ... تغييراتهم ...

git checkout --ours filename.c
git checkout --theirs filename.c
git add filename.c
git commit -m "using theirs"

ثم نحاول الوقت النهائي

git pull origin master

From ssh://[email protected]:22/projectname
 * branch            master     -> FETCH_HEAD
Already up-to-date.

تا-دا!




أرغب في الحصول على النسخة الخاصة بي بالكامل أو ترغب في مراجعة التغييرات الفردية وتحديد كل منها.

اقبل تمامًا النسخة الخاصة بي أو الخاصة بهم :

اقبل إصداري (محلي ، خاص بنا):

git checkout --ours -- <filename>
git add <filename>              # Marks conflict as resolved
git commit -m "merged bla bla"  # An "empty" commit

قبول نسختهم (عن بعد ، ملكهم):

git checkout --theirs -- <filename>
git add <filename>
git commit -m "merged bla bla"

إذا كنت تريد أن تفعل لجميع ملفات الصراع تشغيل:

git merge --strategy-option ours

أو

git merge --strategy-option theirs

مراجعة جميع التغييرات وقبولها بشكل فردي

  1. git mergetool
  2. مراجعة التغييرات وقبول أي إصدار لكل منها.
  3. git add <filename>
  4. git commit -m "merged bla bla"

mergetool الافتراضي يعمل في سطر الأوامر . يجب أن تكون كيفية استخدام mergetool سطر الأوامر سؤال منفصل.

يمكنك أيضًا تثبيت أداة مرئية لهذا ، مثل meld والتشغيل

git mergetool -t meld

وسوف تفتح النسخة المحلية (لنا) ، "قاعدة" أو "دمج" نسخة (النتيجة الحالية للدمج) والإصدار عن بعد (لهم). قم بحفظ النسخة المدمجة عند الانتهاء ، قم بتشغيل git mergetool -t meld مرة أخرى حتى تحصل على "No files need merging" ، ثم انتقل إلى Steps 3. و 4.




والطريقة الأكثر أمانًا لحل النزاعات هي استخدام git-mediate (الحلول الشائعة المقترحة هنا هي خطأ شديد الإملاء).

شاهد هذه المشاركة لمقدمة سريعة حول كيفية استخدامها.




علاوة:

عند التحدث عن السحب / الجلب / الدمج في الإجابات السابقة ، أود مشاركة خدعة شيقة ومثمرة ،

git pull --rebase

هذا الأمر أعلاه هو الأمر الأكثر فائدة في حياتي git التي أنقذت الكثير من الوقت.

قبل دفع تغييرك الملتزم حديثًا إلى الخادم البعيد ، جرّب git pull --rebase بدلاً من git pull merge اليدوي وسيقوم تلقائيًا بمزامنة أحدث تغييرات الخادم البعيد (مع الجلب + الدمج) git pull --rebase المحلي الأخير في الأعلى في بوابة سجل. لا داعي للقلق حول السحب اليدوي / الدمج.

في حالة النزاع ، استخدم فقط

git mergetool
git add conflict_file
git rebase --continue

العثور على التفاصيل في: http://gitolite.com/git-pull--rebase




اعتبارًا من 12 ديسمبر 2016 ، يمكنك دمج الفروع وحل النزاعات على github.com

وبالتالي ، إذا كنت لا ترغب في استخدام سطر الأوامر أو أي أدوات تابعة لجهات خارجية يتم تقديمها هنا من إجابات أقدم ، فانتقل إلى أداة GitHub الأصلية.

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




أنا دائما اتبع الخطوات التالية لتجنب الصراعات.

  • git checkout master (تعال إلى الفرع الرئيسي)
  • سحب git (تحديث الرئيسي الخاص بك للحصول على أحدث رمز)
  • git checkout -b mybranch (تحقق من فرع جديد وابدأ بالعمل على هذا الفرع حتى يبقى سيدك دائماً في قمة الجذع).
  • غيت اضيف. و git ارتكاب و git push (في الفرع المحلي الخاص بك بعد التغييرات)
  • git checkout master (أعود إلى سيدك).

الآن يمكنك أن تفعل الشيء نفسه وتحافظ على أكبر عدد ممكن من الفروع المحلية التي تريدها وتعمل في نفس الوقت الذي أقوم به عند القيام بواجب الدخول إلى فرعك عند الضرورة.




أجد أدوات الدمج نادرا ما تساعدني على فهم الصراع أو القرار. أنا عادة أكثر نجاحا في النظر إلى علامات الصراع في محرر النص واستخدام سجل بوابة كمكمل.

هنا بعض النصائح:

نصيحة واحدة

أفضل ما وجدته هو استخدام نمط التعارض "diff3":

git config merge.conflictstyle diff3

هذا ينتج علامات الصراع مثل هذا:

<<<<<<<
Changes made on the branch that is being merged into. In most cases,
this is the branch that I have currently checked out (i.e. HEAD).
|||||||
The common ancestor version.
=======
Changes made on the branch that is being merged in. This is often a 
feature/topic branch.
>>>>>>>

القسم الأوسط هو ما بدا عليه سلف المشترك. وهذا مفيد لأنه يمكنك مقارنته بالنسختين العلوية والسفلية للحصول على فكرة أفضل عما تم تغييره في كل فرع ، مما يمنحك فكرة أفضل عن الغرض من كل تغيير.

إذا كان النزاع مجرد خطوط قليلة ، فإن هذا يجعل الصراع واضحًا بشكل عام. (إن معرفة كيفية إصلاح الصراع مختلفة تمامًا ؛ عليك أن تكون مدركًا لما يعمل عليه الآخرون. إذا كنت مرتبكًا ، فمن الأفضل أن تتصل بهذا الشخص في غرفتك حتى يتمكنوا من رؤية ما تبحث عنه في.)

إذا كان النزاع أطول ، فسوف أقوم بقص كل قسم من الأقسام الثلاثة ولصقها في ثلاثة ملفات منفصلة ، مثل "mine" و "common" و "theirs".

بعد ذلك ، يمكنني تشغيل الأوامر التالية للاطلاع على الكتلتين المتعارضتين اللتين تسببتا في حدوث التعارض:

diff common mine
diff common theirs

هذا ليس مثل استخدام أداة دمج ، حيث ستشمل أداة الدمج جميع الكتل المختلفة غير المتضاربة أيضًا. أجد أن يكون تشتيت.

نصيحة الثانية

لقد ذكر أحدهم ذلك بالفعل ، لكن فهم القصد من وراء كل فرق كبير مفيد بشكل عام في فهم مصدر النزاع وكيفية التعامل معه.

git log --merge -p <name of file>

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

نصيحة الثالثة

تحقق من تغييراتك باستخدام الأدوات التلقائية.

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

تلميح الرابع

خطط مسبقا؛ التواصل مع زملاء العمل.

التخطيط المسبق والوعي بما يعمل الآخرون يمكن أن يساعد في منع دمج النزاعات و / أو المساعدة في حلها في وقت سابق - في حين أن التفاصيل لا تزال جديدة في الاعتبار.

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

بالنسبة للمخلفات الكبرى التي تتخلل مساحة كبيرة من الكود ، يجب أن تفكر في العمل بشكل متسلسل: الجميع يتوقف عن العمل في تلك المنطقة من الشفرة بينما يقوم شخص واحد بإعادة البناء الكامل.

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

نصيحة خمسة

إذا كنت غير متأكد من الدمج ، فلا تجبره.

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

على المدى الطويل ، فإن التخطيط المسبق والوعي بما يعمل عليه الآخرون هو أفضل أدوات توقع تعارض الدمج وإعداد نفسك لحلها بشكل صحيح في وقت أقل.




ببساطة ، إذا كنت تعرف جيدًا أن التغييرات في أحد المستودعات ليست مهمة ، وتريد حل جميع التغييرات لصالح الآخر ، فاستخدم:

git checkout . --ours

لحل التغييرات في صالح المستودع الخاص بك ، أو

git checkout . --theirs

لحل التغييرات لصالح الآخر أو المستودع الرئيسي .

وإلا فسيتعين عليك استخدام أداة دمج واجهة المستخدم الرسومية p4merge الملفات واحدة تلو الأخرى ، أو أن تكون أداة الدمج p4merge ، أو كتابة اسم أي شخص قمت بتثبيته بالفعل

git mergetool -t p4merge

وبعد الانتهاء من ملف ، سيتعين عليك الحفظ والإغلاق ، بحيث يتم فتح الملف التالي.




اطّلع على الإجابات في سؤال . إحباط عملية دمج في Git ، خصوصًا جواب Charles Bailey الذي يوضح كيفية عرض الإصدارات المختلفة من الملف مع مشاكل ، على سبيل المثال ،

# Common base version of the file.
git show :1:some_file.cpp

# 'Ours' version of the file.
git show :2:some_file.cpp

# 'Theirs' version of the file.
git show :3:some_file.cpp



يمكنك إصلاح التعارضات دمج في عدد من الطرق كما قد تفصيلية أخرى.

أعتقد أن المفتاح الحقيقي هو معرفة كيفية تدفق التغييرات مع المستودعات المحلية والبعيدة. مفتاح هذا هو فهم الفروع تتبع. لقد وجدت أنني أفكر في فرع التعقب بأنه "القطعة المفقودة في المنتصف" بيني دليل الملفات الفعلي المحلي والمعروف عن بعد كأصل.

أنا شخصيا حصلت على عادة من 2 أشياء للمساعدة في تجنب هذا.

بدلا من:

git add .
git commit -m"some msg"

الذي له عيبان -

أ) يتم إضافة جميع الملفات الجديدة / التي تم تغييرها والتي قد تتضمن بعض التغييرات غير المرغوب فيها.
ب) لا يمكنك مراجعة قائمة الملفات أولاً.

لذلك أنا أفعل:

git add file,file2,file3...
git commit # Then type the files in the editor and save-quit.

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

[تحديث - مع مرور الوقت ، قمت بتحويل المزيد إلى:

git status # Make sure I know whats going on
git add .
git commit # Then use the editor

]

أيضا (وأكثر ملاءمة لوضعك) ، أحاول تجنب:

git pull

أو

git pull origin master.

نظرًا لأن السحب يتضمن دمجًا وإذا كان لديك تغييرات محليًا لا تريد دمجها ، فيمكنك بسهولة إنهاء الشفرة المدمجة و / أو دمج التعارضات لرمز لم يكن يجب دمجه.

بدلا من ذلك أحاول القيام به

git checkout master
git fetch   
git rebase --hard origin/master # or whatever branch I want.

قد تجد أيضًا هذا مفيدًا:

git branch، fork، fetch، merge، rebase and clone، what are the difference؟




يرجى اتباع الخطوات التالية لإصلاح دمج التعارضات في Git:

  1. تحقق من حالة Git: git status

  2. احصل على patchset: إحضار git (الخروج التصحيح الصحيح من التزام Git الخاص بك)

  3. الخروج فرع محلي (temp1 في المثال الخاص بي هنا): git checkout -b temp1

  4. سحب محتويات الأخيرة من الرئيسي: سحب جيت - سيد المنشأ الأثيوبية

  5. ابدأ في mergetool وتحقق من التعارضات واصلاحها ... وتحقق من التغييرات في الفرع البعيد مع فرعك الحالي: git mergetool

  6. تحقق من الحالة مرة أخرى: حالة git

  7. حذف الملفات غير المرغوب فيها التي تم إنشاؤها محليًا بواسطة mergetool ، عادة ما تقوم mergetool بإنشاء ملف إضافي بامتداد * .orig. يرجى حذف هذا الملف لأن ذلك هو مجرد تكرار التغييرات والإصلاح محليًا وإضافة الإصدار الصحيح لملفاتك. إضافة git #your_changed_correct_files

  8. تحقق من الحالة مرة أخرى: حالة git

  9. قم بإدخال التغييرات على نفس معرف الالتزام (هذا يتجنب مجموعة تصحيح منفصلة جديدة): git commit --amend

  10. ادفع إلى الفرع الرئيسي: git push (إلى مستودع Git الخاص بك)




إذا كنت ترغب في التراجع عن ذلك بشكل دائم وكنت قد استنسخت بعض المستودع

يمكن رؤية معرف الالتزام

git log 

ثم يمكنك القيام به -

git reset --hard <commit_id>

git push origin <branch_name> -f




git git-merge merge-conflict-resolution git-conflict-resolution