كيفية دمج أو اختيار التغييرات بشكل انتقائي من فرع آخر في git؟

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

سؤال

أنا أستخدم git في مشروع جديد له فروع تنمية متوازية - ولكن حاليًا - حاليًا -:

  • master: استيراد قاعدة الكود الموجودة بالإضافة إلى بعض التعديلات التي أنا متأكد بشكل عام
  • exp1: الفرع التجريبي رقم 1
  • exp2: الفرع التجريبي #2

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

ما هي أفضل طريقة لدمج التغييرات الانتقائية من فرع التنمية إلى آخر مع ترك كل شيء آخر؟

النهج التي فكرت فيها:

  1. git merge --no-commit تليها يدويًا لا يدوي لعدد كبير من التعديلات التي لا أرغب في جعلها شائعة بين الفروع.

  2. النسخ اليدوي للملفات المشتركة إلى دليل مؤقت يليه git checkout للانتقال إلى الفرع الآخر ثم المزيد من النسخ اليدوي من الدليل المؤقت إلى شجرة العمل.

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

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

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

المحلول

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

إذا لم يكن التغيير (التغييرات) التي تريدها في الالتزامات الفردية ، فاستخدم الطريقة الموضحة هنا تقسيم الالتزام إلى الالتزامات الفرد. بالمعنى الدلا ، يمكنك استخدامه git rebase -i للحصول على الالتزام الأصلي بتحرير ، ثم git reset HEAD^ لعودة التغييرات بشكل انتقائي ، ثم git commit لارتكاب هذا الشيء كالتزام جديد في التاريخ.

هناك طريقة لطيفة أخرى هنا في مجلة ريد هات ، حيث يستخدمون git add --patch أو ربما git add --interactive مما يتيح لك إضافة أجزاء فقط من قطعة كبيرة ، إذا كنت ترغب في تقسيم تغييرات مختلفة إلى ملف فردي (ابحث في تلك الصفحة عن "الانقسام").

بعد تقسيم التغييرات ، يمكنك الآن اختيار الكرز فقط.

نصائح أخرى

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

ملخص:

  • الخروج عن المسار (المسار) من الفرع الذي تريد دمجه ،

    $ git checkout source_branch -- <paths>...
    

    تلميح: إنه يعمل أيضًا بدون -- مثل النظر في المنشور المرتبط.

  • أو لدمج الكتل بشكل انتقائي

    $ git checkout -p source_branch -- <paths>...
    

    بدلاً من ذلك ، استخدم إعادة تعيين ثم أضف مع الخيار -p,

    $ git reset <paths>...
    $ git add -p <paths>...
    
  • ارتكب أخيرا

    $ git commit -m "'Merge' these changes"
    

لدمج الملفات بشكل انتقائي من فرع إلى فرع آخر ، قم بتشغيله

git merge --no-ff --no-commit branchX

أين branchX هو الفرع الذي تريد الاندماج من الفرع الحالي.

ال --no-commit سيقوم الخيار بتنظيم الملفات التي تم دمجها بواسطة GIT دون ارتكابها بالفعل. سيمنحك هذا الفرصة لتعديل الملفات المدمجة كما تريد ، ثم تلتزم بها بنفسك.

اعتمادًا على كيفية رغبتك في دمج الملفات ، هناك أربع حالات:

1) تريد دمج حقيقي.

في هذه الحالة ، تقبل الملفات المدمجة بالطريقة التي دمجتها تلقائيًا ثم تلتزم بها.

2) هناك بعض الملفات التي لا تريد دمجها.

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

لتحديد الإصدار في الفرع الحالي ، قم بتشغيل:

git checkout HEAD file1

هذا سيسترجع نسخة من file1 في الفرع الحالي والكتابة فوق file1 السيارات من قبل git.

3) إذا كنت تريد الإصدار في BranchX (وليس دمج حقيقي).

يجري:

git checkout branchX file1

هذا سيسترجع نسخة من file1 في branchX والكتابة file1 ذبابة تلقائية بواسطة git.

4) الحالة الأخيرة هي إذا كنت تريد تحديد دمج محددة فقط في file1.

في هذه الحالة ، يمكنك تعديل التعديل file1 مباشرة ، قم بتحديثه إلى كل ما تريد إصداره file1 لتصبح ، ثم ارتكاب.

إذا لم تتمكن GIT من دمج ملف تلقائيًا ، فسيقوم بإبلاغ الملف باسم ""غير مرغوب فيه"وإنتاج نسخة حيث ستحتاج إلى حل النزاعات يدويًا.



لشرح المزيد مع مثال ، دعنا نقول أنك تريد الاندماج branchX في الفرع الحالي:

git merge --no-ff --no-commit branchX

ثم تقوم بتشغيل git status أمر لعرض حالة الملفات المعدلة.

فمثلا:

git status

# On branch master
# Changes to be committed:
#
#       modified:   file1
#       modified:   file2
#       modified:   file3
# Unmerged paths:
#   (use "git add/rm <file>..." as appropriate to mark resolution)
#
#       both modified:      file4
#

أين file1, file2, ، و file3 هي الملفات التي نجحت في الحصول على تلقائي.

ما يعنيه هذا هو أن التغييرات في master و branchX لجميع هذه الملفات الثلاثة تم دمجها معًا دون أي صراعات.

يمكنك فحص كيف تم الاندماج عن طريق تشغيل git diff --cached;

git diff --cached file1
git diff --cached file2
git diff --cached file3

إذا وجدت بعض الدمج غير مرغوب فيها ، فيمكنك

  1. تحرير الملف مباشرة
  2. حفظ
  3. git commit

إذا كنت لا تريد الاندماج file1 وترغب في الاحتفاظ بالنسخة في الفرع الحالي

يجري

git checkout HEAD file1

إذا كنت لا تريد الاندماج file2 وتريد فقط الإصدار في branchX

يجري

git checkout branchX file2

إذا أردت file3 ليتم دمجها تلقائيًا ، لا تفعل أي شيء.

لقد دمجها GIT بالفعل في هذه المرحلة.


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


أخيرًا ، لا تنسى ذلك git commit.

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

لا يوجد --interactive حجة يمكنك المرور إلى دمج git.

هذا هو البديل:

لديك بعض التغييرات في "ميزة" الفرع وتريد إحضار بعضها ولكن ليس كلها إلى "Master" بطريقة غير قذرة (أي أنك لا تريد اختيار الكرز وارتكاب كل واحد)

git checkout feature
git checkout -b temp
git rebase -i master

# Above will drop you in an editor and pick the changes you want ala:
pick 7266df7 First change
pick 1b3f7df Another change
pick 5bbf56f Last change

# Rebase b44c147..5bbf56f onto b44c147
#
# Commands:
# pick = use commit
# edit = use commit, but stop for amending
# squash = use commit, but meld into previous commit
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#

git checkout master
git pull . temp
git branch -d temp

لذا ، فقط لف ذلك في برنامج نصي shell ، قم بتغيير Master إلى $ إلى الميزة وتغييرها إلى $ من أن تكون على ما يرام:

#!/bin/bash
# git-interactive-merge
from=$1
to=$2
git checkout $from
git checkout -b ${from}_tmp
git rebase -i $to
# Above will drop you in an editor and pick the changes you want
git checkout $to
git pull . ${from}_tmp
git branch -d ${from}_tmp

هناك طريقة أخرى تذهب:

git checkout -p

إنه مزيج بين git checkout و git add -p وقد يكون بالضبط ما تبحث عنه:

   -p, --patch
       Interactively select hunks in the difference between the <tree-ish>
       (or the index, if unspecified) and the working tree. The chosen
       hunks are then applied in reverse to the working tree (and if a
       <tree-ish> was specified, the index).

       This means that you can use git checkout -p to selectively discard
       edits from your current working tree. See the “Interactive Mode”
       section of git-add(1) to learn how to operate the --patch mode.

على الرغم من أن بعض هذه الإجابات جيدة جدًا ، إلا أنني أشعر أن أياً من الإجابة على قيود OP الأصلية: اختيار ملفات معينة من فروع معينة. هذا الحل يفعل ذلك ، ولكن قد يكون مملاً إذا كان هناك العديد من الملفات.

لنقول أن لديك master, exp1, ، و exp2 الفروع. تريد دمج ملف واحد من كل فرع من الفروع التجريبية في سيد. سأفعل شيئًا كهذا:

git checkout master
git checkout exp1 path/to/file_a
git checkout exp2 path/to/file_b

# save these files as a stash
git stash
# merge stash with master
git merge stash

سيعطيك هذا فرقًا في الملف لكل ملف من الملفات التي تريدها. لا شيء آخر. لا شيء اقل. من المفيد أن تكون لديك تغييرات مختلفة بشكل جذري بين الإصدارات-في حالتي ، وتغيير تطبيق من Rails 2 إلى Rails 3.

تعديل: سيؤدي ذلك إلى دمج الملفات ، ولكنه يقوم بدمج ذكي. لم أتمكن من معرفة كيفية استخدام هذه الطريقة للحصول على معلومات DIF في ملف (ربما لا يزال من الممكن أن يتم دمج الأشياء الصغيرة المزعجة مثل Whitespace إلا إذا كنت تستخدم -s recursive -X ignore-all-space اختيار)

1800 إجابة معلومات صحيحة تمامًا. بصفتي git noob ، على الرغم من ذلك ، لم يكن "استخدام Git Cherry-Pick" كافياً بالنسبة لي لمعرفة ذلك دون المزيد من الحفر على الإنترنت ، لذا اعتقدت أنني سأقوم بنشر دليل أكثر تفصيلاً في حالة وجود أي شخص آخر في قارب مماثل.

كانت حالة الاستخدام الخاصة بي ترغب في سحب التغييرات بشكل انتقائي من فرع GitHub لشخص آخر إلى بلدي. إذا كان لديك بالفعل فرع محلي مع التغييرات التي تحتاجها فقط للقيام بالخطوات 2 و 5-7.

  1. قم بإنشاء (إن لم يتم إنشاؤه) فرعًا محليًا مع التغييرات التي تريد إحضارها.

    $ git branch mybranch <base branch>

  2. التبديل فيه.

    $ git checkout mybranch

  3. سحب التغييرات التي تريدها من حساب الشخص الآخر. إذا لم تكن قد ترغب بالفعل في إضافتها كجهاز تحكم عن بعد.

    $ git remote add repos-w-changes <git url>

  4. سحب كل شيء من فرعهم.

    $ git pull repos-w-changes branch-i-want

  5. عرض سجلات الالتزام لمعرفة التغييرات التي تريدها:

    $ git log

  6. انتقل إلى الفرع الذي تريد سحب التغييرات إليه.

    $ git checkout originalbranch

  7. Cherry اختيار ارتباطاتك ، واحدة تلو الأخرى ، مع التجزئة.

    $ git cherry-pick -x hash-of-commit

طرف القبعة: http://www.sourcemage.org/git_guide

هنا كيف يمكنك استبدال Myclass.java إملأ master فرع مع Myclass.java في feature1 فرع. ستعمل حتى لو Myclass.java غير موجود master.

git checkout master
git checkout feature1 Myclass.java

لاحظ أن هذا سوف يكتب - لا يندمج - وتجاهل التغييرات المحلية في الفرع الرئيسي بدلاً من ذلك.

الطريقة البسيطة ، في الواقع دمج ملفات محددة من فرعين ، وليس فقط استبدال ملفات محددة بفرع من فرع آخر.

الخطوة الأولى: فرق الفروع

git diff branch_b > my_patch_file.patch

ينشئ ملف تصحيح للفرق بين الفرع الحالي و Branch_B

الخطوة الثانية: قم بتطبيق التصحيح على الملفات التي تطابق نمطًا

git apply -p1 --include=pattern/matching/the/path/to/file/or/folder my_patch_file.patch

ملاحظات مفيدة على الخيارات

يمكنك استخدام * كبطاقة البرية في النمط تشمل.

لا تحتاج إلى هروب.

أيضًا ، يمكنك استخدام -Exclude بدلاً من ذلك وتطبيقه على كل شيء باستثناء الملفات التي تطابق النمط ، أو عكس التصحيح باستخدام -r

خيار -P1 هو عقد من أمر *Unix Patch وحقيقة أن محتويات ملف التصحيح تعطي كل اسم ملف بـ a/ أو b/ (أو أكثر اعتمادًا على كيفية إنشاء ملف التصحيح) الذي تحتاج إلى تجريده حتى يتمكن من اكتشاف الملف الحقيقي إلى المسار إلى الملف الذي يجب تطبيقه على التصحيح.

تحقق من صفحة MAN للحصول على GIT-Apply لمزيد من الخيارات.

الخطوة الثالثة: لا توجد خطوة الثالثة

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

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

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

git merge --no-ff --no-commit -s ours branchname1

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

git checkout branchname1 -- file1 file2 etc

إذا كنت تندمج من أكثر من فرع آخر ، كرر حسب الحاجة.

git checkout branchname2 -- file3 file4 etc

الآن الملفات من الفرع الآخر موجودة في الفهرس ، جاهزة للالتزام ، مع التاريخ.

git commit

وسيكون لديك الكثير من الشرح للقيام به في هذه الرسالة الالتزام.

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

أعلم أنني متأخر قليلاً ، لكن هذا هو سير العمل الخاص بي لدمج الملفات الانتقائية.

#make a new branch ( this will be temporary)
git checkout -b newbranch
# grab the changes 
git merge --no-commit  featurebranch
# unstage those changes
git reset HEAD
(you can now see the files from the merge are unstaged)
# now you can chose which files are to be merged.
git add -p
# remember to "git add" any new files you wish to keep
git commit

وجدت هذا المشنور لاحتواء أبسط إجابة. فقط افعل:

$ #git checkout <branch from which you want files> <file paths>

مثال:

$ #pulling .gitignore file from branchB into current branch
$ git checkout branchB .gitignore

انظر المنشور لمزيد من المعلومات.

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

git checkout [branch with file] [path to file you would like to merge]

اذا ركضت

git status

سترى الملف الذي تم عرضه بالفعل ...

ثم اركض

git commit -m "Merge changes on '[branch]' to [file]"

بسيط.

من الغريب أن GIT لا يزال ليس لديه مثل هذه الأداة المريحة "خارج الصندوق". أستخدمه بشدة عند تحديث بعض فروع الإصدار القديم (الذي لا يزال لديه الكثير من مستخدمي البرامج) بواسطة القليل فقط bugfixes من فرع الإصدار الحالي. في هذه الحالة ، غالبًا ما تكون هناك حاجة إلى الحصول عليها بسرعة القليل فقط خطوط رمز من الملف في Trunk ، متجاهلة الكثير من التغييرات الأخرى (ليس من المفترض أن تدخل في الإصدار القديم) ... وبالطبع التفاعلية ثلاثية هناك حاجة إلى دمج في هذه الحالة ، git checkout --patch <branch> <file path> لا يمكن استخدامه لهذا الغرض الانتقائي الانتقائي.

يمكنك أن تفعل ذلك بسهولة:

فقط أضف هذا الخط إلى [alias] قسم في عالمك .gitconfig أو محلي .git/config ملف:

[alias]
    mergetool-file = "!sh -c 'git show $1:$2 > $2.theirs; git show $(git merge-base $1 $(git rev-parse HEAD)):$2 > $2.base; /C/BCompare3/BCompare.exe $2.theirs $2 $2.base $2; rm -f $2.theirs; rm -f $2.base;' -"

إنه يعني أنك تستخدم ما وراء المقارنة. ما عليك سوى التغيير إلى البرامج التي تختارها إذا لزم الأمر. أو يمكنك تغييره إلى ثلاث اتجاهات الحركة التلقائية إذا لم تكن بحاجة إلى دمج انتقائي تفاعلي:

[alias]
    mergetool-file = "!sh -c 'git show $1:$2 > $2.theirs; git show $(git merge-base $1 $(git rev-parse HEAD)):$2 > $2.base; git merge-file $2 $2.base $2.theirs; rm -f $2.theirs; rm -f $2.base;' -"

ثم استخدم مثل هذا:

git mergetool-file <source branch> <file path>

هذا سوف يمنحك الانتقائية الحقيقية طريق الأشجار دمج فرصة لأي ملف فقط في فرع آخر.

ليس بالضبط ما كنت تبحث عنه ، لكنه كان مفيدًا بالنسبة لي:

git checkout -p <branch> -- <paths> ...

إنه مزيج من بعض الإجابات.

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

الأمر من الرابط أعلاه:

#You are in the branch you want to merge to
git checkout <branch_you_want_to_merge_from> <file_paths...>

سأفعل

git diff الالتزام 1..Commit2 filepattern | git-apply-index && git

وبهذه الطريقة يمكنك الحد من نطاق الالتزامات للحصول على فرع من فرع.

سرقت من: http://www.gelato.unsw.edu.au/archives/git/0701/37964.html

أنا أحب إجابة "git-interaction-merge" أعلاه ، ولكن هناك أسهل. دع git تفعل هذا من أجلك باستخدام مزيج من Rebase من التفاعل وعلى:

      A---C1---o---C2---o---o feature
     /
----o---o---o---o master

لذا فإن الحالة هي أنك تريد C1 و C2 من "الميزة" الفرعية (الفرع "أ") ، ولكن لا شيء من الباقي في الوقت الحالي.

# git branch temp feature
# git checkout master
# git rebase -i --onto HEAD A temp

الذي ، كما هو مذكور أعلاه ، يسقطك إلى المحرر التفاعلي حيث يمكنك تحديد خطوط "اختيار" لـ C1 و C2 (على النحو الوارد أعلاه). احفظ وتوقف ، وبعد ذلك سوف يمتد مع Rebase ويمنحك فرع "Temp" ويتجه أيضًا إلى Master + C1 + C2:

      A---C1---o---C2---o---o feature
     /
----o---o---o---o-master--C1---C2 [HEAD, temp]

بعد ذلك ، يمكنك فقط تحديث Master للرأس وحذف فرع Temp وأنت على ما يرام:

# git branch -f master HEAD
# git branch -d temp

أعلم أن هذا السؤال قديم وهناك العديد من الإجابات الأخرى ، لكنني كتبت السيناريو الخاص بي المسمى "Pmerge" لدمج الدلائل جزئيًا. إنه عمل مستمر وما زلت أتعلم كلاً من البرمجة النصية والباش.

يستخدم هذا الأمر git merge --no-commit ثم قم بتطبيق التغييرات التي لا تتطابق مع المسار المقدم.

الاستخدام: git pmerge branch path
مثال: git merge develop src/

لم أختبرها على نطاق واسع. يجب أن يكون دليل العمل خاليًا من أي تغييرات غير ملتزم بها وملفات غير متوفرة.

#!/bin/bash

E_BADARGS=65

if [ $# -ne 2 ]
then
    echo "Usage: `basename $0` branch path"
    exit $E_BADARGS
fi

git merge $1 --no-commit
IFS=$'\n'
# list of changes due to merge | replace nulls w newlines | strip lines to just filenames | ensure lines are unique
for f in $(git status --porcelain -z -uno | tr '\000' '\n' | sed -e 's/^[[:graph:]][[:space:]]\{1,\}//' | uniq); do
    [[ $f == $2* ]] && continue
    if git reset $f >/dev/null 2>&1; then
        # reset failed... file was previously unversioned
        echo Deleting $f
        rm $f
    else
        echo Reverting $f
        git checkout -- $f >/dev/null 2>&1
    fi
done
unset IFS

ماذا عن git reset --soft branch ؟ أنا مندهش من أنه لم يذكرها أحد بعد.

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

يمكنك استخدام read-tree لقراءة أو دمج الشجرة البعيدة في الفهرس الحالي ، على سبيل المثال:

git remote add foo git@example.com/foo.git
git fetch foo
git read-tree --prefix=my-folder/ -u foo/master:trunk/their-folder

لأداء الدمج ، استخدم -m في حين أن.

أنظر أيضا: كيف يمكنني دمج دليل فرعي في Git؟

نهج بسيط لدمج/الالتزام الانتقائي حسب الملف:

git checkout dstBranch git merge srcBranch // make changes, including resolving conflicts to single files git add singleFile1 singleFile2 git commit -m "message specific to a few files" git reset --hard # blow away uncommitted changes

إذا لم يكن لديك الكثير من الملفات التي تغيرت ، فإن هذا سيتركك بدون ارتكاب إضافي.

1. فرع مكرر مؤقتًا
$ git checkout -b temp_branch

2. إعادة تعيين لآخر مطلوب الالتزام
$ git reset --hard HEAD~n, ، أين n هل عدد الالتزامات التي تحتاجها للعودة

3. الخروج من كل ملف من الفرع الأصلي
$ git checkout origin/original_branch filename.ext

الآن يمكنك الالتزام والقوة الدفع (للكتابة المرتفعة عن بُعد) ، إذا لزم الأمر.

عندما تغير عدد قليل من الملفات بين الالتزامات الحالية من الفرعين ، أقوم بدمج التغييرات يدويًا عن طريق المرور عبر الملفات المختلفة.

git difftoll <branch-1>..<branch-2>

إذا كنت بحاجة فقط إلى دمج دليل معين وترك كل شيء آخر سليمة وحافظ على التاريخ ، فيمكنك تجربة هذا ... إنشاء جديد target-branch قبالة master قبل التجربة.

الخطوات أدناه تفترض أن لديك فرعين target-branch و source-branch, والدليل dir-to-merge التي تريد دمجها في source-branch. افترض أيضًا أن لديك أدلة أخرى مثل dir-to-retain في الهدف الذي لا تريد تغيير التاريخ والاحتفاظ به. أيضا ، يفترض أن هناك تعارضات دمج في dir-to-merge.

git checkout target-branch
git merge --no-ff --no-commit -X theirs source-branch
# the option "-X theirs", will pick theirs when there is a conflict. 
# the options "--no--ff --no-commit" prevent a commit after a merge, and give you an opportunity to fix other directories you want to retain, before you commit this merge.

# the above, would have messed up the other directories that you want to retain.
# so you need to reset them for every directory that you want to retain.
git reset HEAD dir-to-retain
# verify everything and commit.
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top