كيف يمكنك إزالة مراجعة محددة في سجل git؟

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

  •  09-06-2019
  •  | 
  •  

سؤال

لنفترض أن سجل git الخاص بك يبدو كما يلي:

1 2 3 4 5

1-5 هي مراجعات منفصلة.تحتاج إلى إزالة 3 مع الاحتفاظ بالأرقام 1 و2 و4 و5.كيف يمكن القيام بذلك؟

هل هناك طريقة فعالة عندما تكون هناك مئات المراجعات بعد المراجعة التي سيتم حذفها؟

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

المحلول

لدمج المراجعة 3 و4 في مراجعة واحدة، يمكنك استخدام git rebase.إذا كنت تريد إزالة التغييرات في المراجعة 3، فستحتاج إلى استخدام أمر التحرير في وضع إعادة الأساس التفاعلي.إذا كنت تريد دمج التغييرات في مراجعة واحدة، فاستخدم الاسكواش.

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

من وثائق بوابة:

ابدأ مع الالتزام الأقدم الذي تريد الاحتفاظ به كما هو:

git rebase -i <after-this-commit>

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

pick deadbee The oneline of this commit
pick fa1afe1 The oneline of the next commit
...

الأوصاف الموجودة على الإنترنت هي فقط من أجل المتعة الخاصة بك؛لن ينظر git-rebase إليها ولكن إلى أسماء الالتزام ("deadbee" و"fa1afe1" في هذا المثال)، لذا لا تحذف الأسماء أو تحررها.

من خلال استبدال الأمر "pick" بالأمر "edit"، يمكنك إخبار git-rebase بالتوقف بعد تطبيق هذا الالتزام، بحيث يمكنك تحرير الملفات و/أو رسالة الالتزام، وتعديل الالتزام، ومتابعة إعادة التأسيس.

إذا كنت تريد دمج التزامين أو أكثر في التزام واحد، فاستبدل الأمر "pick" بـ "squash" للالتزام الثاني واللاحق.إذا كان للالتزامات مؤلفون مختلفون، فسوف ينسب الالتزام المسحوب إلى مؤلف الالتزام الأول.

نصائح أخرى

فيما يلي طريقة لإزالة ملف محدد بشكل غير تفاعلي <commit-id>, ، معرفة فقط <commit-id> تريد إزالة:

git rebase --onto <commit-id>^ <commit-id> HEAD

لكل هذا التعليق (وتأكدت من صحة هذا)، إجابة رادو قريبة جدًا ولكنها تترك git في حالة رأس منفصلة.بدلاً من ذلك، قم بإزالة HEAD واستخدام هذا لإزالة <commit-id> من الفرع الذي أنت فيه:

git rebase --onto <commit-id>^ <commit-id>

كما لوحظ من قبل بوابة-rebase(1) هو صديقك.على افتراض أن الالتزامات موجودة في ملفك master فرع، سوف تفعل:

git rebase --onto master~3 master~2 master

قبل:

1---2---3---4---5  master

بعد:

1---2---4'---5' master

من بوابة rebase (1):

يمكن أيضًا إزالة مجموعة من الالتزامات مع Rebase.إذا كان لدينا الموقف التالي:

E---F---G---H---I---J  topicA

ثم الأمر

git rebase --onto topicA~5 topicA~3 topicA

من شأنه أن يؤدي إلى إزالة الالتزامات F و G:

E---H'---I'---J'  topicA

هذا مفيد إذا كان F و G معيبًا بطريقة ما ، أو لا ينبغي أن يكون جزءًا من Topica.لاحظ أن الوسيطة إلى-into والمعلمة يمكن أن تكون أي التزام صالح.

إذا كان كل ما تريد فعله هو إزالة التغييرات التي تم إجراؤها في المراجعة 3، فقد ترغب في استخدام git revert.

يقوم Git revert ببساطة بإنشاء مراجعة جديدة مع التغييرات التي تتراجع عن جميع التغييرات في المراجعة التي تقوم بإعادتها.

ما يعنيه هذا هو أنك تحتفظ بمعلومات حول كل من الالتزام غير المرغوب فيه والالتزام الذي يزيل تلك التغييرات.

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

جميع الإجابات حتى الآن لا تعالج القلق الزائد:

هل هناك طريقة فعالة عندما يكون هناك مئات المراجعات بعد الحذف؟

تتبع الخطوات، ولكن للإشارة، دعونا نفترض التاريخ التالي:

[master] -> [hundreds-of-commits-including-merges] -> [C] -> [R] -> [B]

ج:الالتزام فقط بعد الالتزام المراد إزالته (نظيف)

ر:الالتزام المراد إزالته

ب:الالتزام الذي يسبق الالتزام المراد إزالته (قاعدة)

بسبب قيد "مئات المراجعات"، أفترض الشروط المسبقة التالية:

  1. هناك بعض الالتزامات المحرجة التي تتمنى لو لم تكن موجودة أبدًا
  2. لا توجد أي التزامات لاحقة تعتمد فعليًا على هذا الالتزام المحرج (لا توجد تعارضات عند العودة)
  3. لا يهمك أنه سيتم إدراجك بصفتك "الملتزم" بمئات الالتزامات المتدخلة (سيتم الاحتفاظ بكلمة "المؤلف")
  4. لم تقم بمشاركة المستودع مطلقًا
    • أو أن لديك بالفعل تأثيرًا كافيًا على جميع الأشخاص الذين قاموا باستنساخ التاريخ بهذا الالتزام لإقناعهم باستخدام تاريخك الجديد
    • وأنت لا تهتم عن إعادة كتابة التاريخ

هذه مجموعة قيود مقيدة جدًا، ولكن هناك إجابة مثيرة للاهتمام تعمل بالفعل في هذه الحالة الزاوية.

فيما يلي الخطوات:

  1. git branch base B
  2. git branch remove-me R
  3. git branch save
  4. git rebase --preserve-merges --onto base remove-me

إذا لم تكن هناك أي صراعات حقًا، فيجب المضي قدمًا دون أي انقطاعات أخرى.إذا كانت هناك صراعات، يمكنك حلها و rebase --continue أو تقرر أن تعيش مع الإحراج و rebase --abort.

الآن يجب أن تكون على master التي لم تعد لديها التزام ر فيه.ال save يشير الفرع إلى المكان الذي كنت فيه من قبل، في حال كنت ترغب في المصالحة.

إن الطريقة التي تريد بها ترتيب نقل أي شخص آخر إلى سجلك الجديد أمر متروك لك.سوف تحتاج إلى التعرف عليها stash, reset --hard, ، و cherry-pick.ويمكنك حذف base, remove-me, ، و save الفروع

إذن هذا هو السيناريو الذي واجهته وكيف قمت بحله.

[branch-a]

[Hundreds of commits] -> [R] -> [I]

هنا R هو الالتزام الذي كنت بحاجة إلى إزالته، و I هو التزام واحد يأتي بعد ذلك R

لقد قمت بالتزام العودة وسحقتهم معًا

git revert [commit id of R]
git rebase -i HEAD~3

أثناء عملية الاسكواش التفاعلية، تم تنفيذ آخر عمليتين.

لقد هبطت أيضًا في وضع مماثل.استخدم rebase التفاعلي باستخدام الأمر أدناه وأثناء التحديد، قم بإسقاط الالتزام الثالث.

git rebase -i remote/branch

إجابات رادو وكريم لا تفعل شيئًا بالنسبة لي (تظهر فقط الرسالة "الفرع الحالي محدث".).من المحتمل أن يحدث هذا لأن الرمز "^" لا يعمل في وحدة تحكم Windows.ومع ذلك، وفقا ل هذا تعليق، استبدال '^' بـ '~1' يحل المشكلة.

git rebase --onto <commit-id>^ <commit-id>

لإزالة سجل الالتزام القديم من git repo:

قم بالتشغيل الأول أسفل cmd

rm -rf .git

- إعادة إنشاء الريبو من الحالي

git init                                                                           
git add .                                                  
git commit -m "first commit"

- ادفع إلى مستودعات github البعيدة

git remote add origin git@github.com<your git mail>   
git push -u --force origin master
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top