دليل Git المتقدم: Git Stash و Reset و Rebase والمزيد
نشرت: 2022-03-11يجب أن يكون لدى كل مطور فهم جيد للتحكم في الإصدار ، وقد أصبح Git المعيار الفعلي للتحكم في الإصدار في تطوير البرامج.
في كثير من الأحيان ، يتعلم المطورون فقط بعض الأوامر البسيطة ويتغاضون عن قوة سجل Git والأشياء الأخرى التي يمكن لـ Git القيام بها لتجعلك أكثر كفاءة. على سبيل المثال ، تعد إدارة الإصدارات أمرًا سهلاً للغاية باستخدام Git باستخدام git tag
.
أخذت دورة متقدمة في Git عبر الإنترنت (مع Github) وشرعت في تدريس فصل Git للمبتدئين بالاشتراك مع Github. عندما لاحظت عدم وجود العديد من المقالات الفنية حول ميزات Git المفضلة لدي ، انتهزت الفرصة لمشاركتها مع زملائي المطورين. في هذا المنشور ، ستتعلم كيفية الاستفادة من وظائف Git المتقدمة التالية:
-
git stash
، مما يجعل حفظًا مؤقتًا محليًا لشفرتك -
git reset
، والتي تتيح لك ترتيب التعليمات البرمجية الخاصة بك قبل تنفيذ الالتزام -
git bisect
، وظيفة تسمح لك بمطاردة المخالفات السيئة -
git squash
، الذي يسمح لك بدمج التزاماتك -
git rebase
، والذي يسمح بتطبيق التغييرات من فرع إلى آخر
جيت ستاش
يمكّنك Git stash من حفظ التعليمات البرمجية الخاصة بك دون الالتزام. كيف هذا مفيد؟ تصور السيناريو التالي:
لقد قمت بالفعل بثلاثة إلتزامات منظمة ومرتبة ، ولكن لديك أيضًا بعض التعليمات البرمجية غير الملتزم بها والتي تكون فوضوية تمامًا ؛ لن ترغب في إلزامه دون إزالة رمز التصحيح أولاً. ثم ، لسبب ما ، تحتاج فجأة إلى حضور مهمة أخرى وتضطر إلى تبديل الفروع. يمكن أن يحدث هذا غالبًا إذا كنت في فرعك main
، ونسيت إنشاء فرع جديد لميزتك. في الوقت الحالي ، يبدو الرمز الخاص بك كما يلي:
$ git status On branch my-feature Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: css/common.scss no changes added to commit (use "git add" and/or "git commit -a")
$ git diff diff --git a/css/common.scss b/css/common.scss index 2090cc4..90fd457 100644 --- a/css/common.scss +++ b/css/common.scss @@ -13,6 +13,6 @@ body { font-family: "Proxima Nova", Arial, sans-serif; font-size: 13px; - color: #333; + color: red; background-color: #f00; }
عند تشغيل git stash
، تختفي التعليمات البرمجية غير الملتزم بها دون الالتزام. التخزين مثل حفظ التزام محلي مؤقت لفرعك. ليس من الممكن دفع المخبأ إلى مستودع بعيد ، لذا فإن المخبأ مخصص فقط لاستخدامك الشخصي.
$ git stash Saved working directory and index state WIP on my-feature: 49ee696 Change text color
يظهر فرعك الآن كما كان عندما أجريت آخر التزام لك. الآن ، يمكنك تغيير الفروع بأمان دون فقد رمزك أو الالتزام الفوضوي. عندما ترجع إلى الفرع الخاص بك وتقوم بتشغيل git stash list
، سترى قائمة من المخبأ التي تبدو كالتالي:
$ git stash list stash@{0}: WIP on my-feature: 49ee696 Change text color
يمكنك بسهولة إعادة تطبيق المحتوى المخفي عن طريق تشغيل git stash apply
. يمكنك أيضًا تطبيق مخبأ معين (إذا كنت قد خبأت أكثر من مرة) عن طريق تشغيل git stash apply stash@{1}
(يشير الرقم "1" إلى الثانية قبل المخبأ الأخير). فيما يلي مثال على إخفاء أكثر من التزام وتطبيق مخبأ مختلف:
$ git diff diff --git a/css/common.scss b/css/common.scss index 2090cc4..90fd457 100644 --- a/css/common.scss +++ b/css/common.scss @@ -13,6 +13,6 @@ body { font-family: "Proxima Nova", Arial, sans-serif; font-size: 13px; - color: #333; + color: red; background-color: #f00; } $ git stash Saved working directory and index state WIP on my-feature: 49ee696 Change text color $ git diff diff --git a/css/common.scss b/css/common.scss index 2090cc4..b63c664 100644 --- a/css/common.scss +++ b/css/common.scss @@ -13,6 +13,6 @@ body { font-family: "Proxima Nova", Arial, sans-serif; font-size: 13px; - color: #333; + color: red; background-color: #f00; } $ git stash Saved working directory and index state WIP on my-feature: 49ee696 Change text color
$ git stash list stash@{0}: WIP on my-feature: 49ee696 Change text color stash@{1}: WIP on my-feature: 49ee696 Change text color stash@{2}: WIP on my-feature: 49ee696 Change text color $ git stash apply stash@{2} On branch my-feature Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: css/common.scss no changes added to commit (use "git add" and/or "git commit -a")
git stash apply stash@{2}
طبق أقدم كود مخبأ ، عندما قمنا بتغيير لون النص إلى اللون الأحمر.
$ git diff diff --git a/css/common.scss b/css/common.scss index 2090cc4..90fd457 100644 --- a/css/common.scss +++ b/css/common.scss @@ -13,6 +13,6 @@ body { font-family: "Proxima Nova", Arial, sans-serif; font-size: 13px; - color: #333; + color: red; background-color: #f00; }
إذا قررت عدم الالتزام بعملك بمجرد استعادة المخبأ ، فيمكنك تشغيل git checkout .
، والتي تعيد تعيين جميع التعليمات البرمجية غير الملتزم بها.
كمثال آخر على كيفية استخدام Git stash: لنفترض أن لديك بعض الملفات الجديدة ، أحدها به خلل. اترك الكل باستثناء ملف الأخطاء المشتبه به بدون مراحل (يجب تنظيم الكود ليتم تخزينه) ، ثم يمكنك تخزين هذا الملف واستكشاف المشكلة وإصلاحها. إذا لم يكن الملف المخبأ هو المشكلة ، يمكنك استعادة المخبأ.
$ git status On branch my-feature Untracked files: (use "git add <file>..." to include in what will be committed) css/colors.scss nothing added to commit but untracked files present (use "git add" to track)
$ git add css/colors.scss $ git stash Saved working directory and index state WIP on my-feature: 0d8deef delete colors $ git status On branch my-feature nothing to commit, working tree clean $ git stash apply stash@{0} On branch my-feature Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: css/colors.scss
يمكنك أيضًا نقل التزاماتك المخبأة إلى فرع ميزة جديد أو فرع تصحيح الأخطاء باستخدام git stash branch
:
$ git status On branch my-feature Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: css/common.scss no changes added to commit (use "git add" and/or "git commit -a") $ git stash Saved working directory and index state WIP on my-feature: 66f3f3b Add colors file $ git stash branch debugging-branch M css/common.scss Switched to a new branch 'debugging-branch' Unstaged changes after reset: M css/common.scss On branch debugging-branch Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: css/common.scss Dropped refs/stash@{0} (d140624f60d8deef7bceb0d11fc80ed4fd47e0a1)
لاحظ أنه عند قيامك بتطبيق مخبأ ، لا يتم حذف المخبأ. يمكنك إزالة المخبأ بشكل فردي باستخدام git drop
، أو إزالة جميع المخبأ باستخدام git stash clear
:
$ git stash list stash@{0}: WIP on my-feature: 66f3f3b Add colors file stash@{1}: WIP on my-feature: 0d8deef delete colors stash@{2}: WIP on my-feature: 49ee696 Change text color $ git stash drop stash@{2} Dropped stash@{2} (8ed6d2ce101aa2e28c8ccdc94cb12df8e5c468d6) $ git stash list stash@{0}: WIP on my-feature: 66f3f3b Add colors file stash@{1}: WIP on my-feature: 0d8deef delete colors $ git stash clear $ git stash list $
إعادة تعيين بوابة
إذا وجدت نفسك في الموقف الذي ارتكبت فيه عن طريق الخطأ بعض التعليمات البرمجية الفوضوية ، فيمكنك إجراء إعادة تعيين "بسيطة". هذا يعني أن الكود يظهر كما لو لم يتم الالتزام به بعد. ثم يمكنك ترتيب الكود الخاص بك في IDE الخاص بك قبل إجراء التزام أكثر نظافة. للقيام بذلك يمكنك تشغيل git reset --soft HEAD~1
. سيؤدي هذا إلى إعادة تعيين أحدث التزام. يمكنك إعادة تعيين أكثر من التزام واحد عن طريق تغيير الرقم بعد ~
على سبيل المثال git reset --soft HEAD~2
.
$ git reset --soft HEAD~1 $ git status On branch debugging-branch Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: css/common.scss Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: css/common.scss
$ git diff diff --git a/css/common.scss b/css/common.scss index 2090cc4..90fd457 100644 --- a/css/common.scss +++ b/css/common.scss @@ -13,6 +13,6 @@ body { font-family: "Proxima Nova", Arial, sans-serif; font-size: 13px; - color: $grey; + color: red; background-color: #f00; }
تعد إعادة تعيين Git مربكة بعض الشيء ، خاصة عند تعليم مستخدمي Git الجدد. يجب حجز إعادة ضبط بسيطة لخطأ حقيقي بينما يمكن استخدام مخبأ لمبادلة الرمز داخل وخارج.
يمكنك أيضًا إجراء إعادة تعيين إلى إعدادات المصنع ( git reset --hard HEAD~1
). هذا النوع من إعادة التعيين يمحو بشكل أساسي الالتزام الأخير. يجب أن تكون حريصًا جدًا بشأن إجراء عمليات إعادة تعيين ثابتة ، خاصة إذا قمت بدفع الفرع الخاص بك ، حيث لا توجد طريقة لاستعادة الالتزام.
بوابة المنصف
أداة Git المفضلة لدي هي git bisect
. لقد احتجت إليها بضع مرات فقط ولكن عندما احتجت إليها ، كانت لا تقدر بثمن! لقد استخدمته بشكل أساسي على قواعد بيانات كبيرة حيث كانت هناك مشكلة لم يجد أحد سببها الجذري ، حتى بعد بعض التصحيح القوي.
يقوم git bisect
بشكل أساسي بإجراء بحث ثنائي بين التزامين معينين ثم يقدم لك تفاصيل التزام معين. تحتاج أولاً إلى منح Git التزامًا جيدًا ، حيث تعلم أن وظيفتك كانت تعمل ، والتزامًا سيئًا. لاحظ أنه طالما أن لديك التزامًا جيدًا وآخر سيئًا ، فقد تفصل بين الالتزامات سنوات (على الرغم من أنه كلما تراجعت في الزمن ، كلما أصبح الأمر أكثر صعوبة!).
الشيء الأكثر متعة في git bisect
هو أنك عادة لا تعرف حقًا من كتب ارتكاب عربات التي تجرها الدواب عندما تبدأ. تسببت الإثارة في اكتشاف مكان ظهور الخطأ أكثر من مرة في تجمع عدد قليل من زملاء العمل حول جهاز الكمبيوتر الخاص بي!
للبدء ، تحقق من فرع عربات التي تجرها الدواب وابحث عن الالتزامات الجيدة. ستحتاج إلى استعراض سجل الالتزام الخاص بك والعثور على تجزئة الالتزام ، ثم التحقق من هذا الالتزام المحدد واختبار الفرع الخاص بك. بمجرد أن تجد مكانًا جيدًا وسيئًا للعمل منه ، يمكنك تشغيل git bisect
.
في هذا السيناريو ، يكون النص باللون الأحمر على موقع الويب هذا (على الرغم من أنه يمكن استخدام مصمم واجهة المستخدم) ولكننا لا نعرف كيف ومتى تم جعله باللون الأحمر. هذا مثال بسيط للغاية ، في سيناريو من الحياة الواقعية ، من المحتمل أن تواجه مشكلة أقل وضوحًا ، مثل عدم إرسال / تشغيل النموذج.
عندما نقوم بتشغيل git log
، يمكننا رؤية قائمة الالتزامات للاختيار من بينها.
$ git log commit a3cfe7f935c8ad2a2c371147b4e6dcd1a3479a22 (HEAD -> main) Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:52:57 2021 +0100 Update .gitignore file for .DS_Store commit 246e90977790967f54e878a8553332f48fae6edc Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:51:23 2021 +0100 Change styling of page commit d647ac489ad43b3c6eaea5aceb02b0a7d7e5cf8e Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:50:48 2021 +0100 Change text color commit 032a41136b6653fb9f7d81aef573aed0dac3dfe9 Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:42:57 2021 +0100 Change text color commit 246e90977790967f54e878a8553332f48fae6edc Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:41:23 2021 +0100 delete colors commit d647ac489ad43b3c6eaea5aceb02b0a7d7e5cf8e Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:50:48 2021 +0100 Change text color commit ce861e4c6989a118aade031020fd936bd28d535b Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:07:36 2021 +0100 ...
إذا فتحت صفحة الويب الخاصة بي على أحدث تجزئة الالتزام ، فسيكون النص باللون الأحمر ، لذلك أعلم أن لدي مشكلة.
نبدأ الآن في النصف ونخبر Git أن لدينا التزامًا سيئًا.
$ git bisect start $ git bisect bad 8d4615b9a963ef235c2a7eef9103d3b3544f4ee1
الآن نعود بالزمن إلى الوراء لمحاولة العثور على التزام حيث لم يكن النص باللون الأحمر. هنا أحاول التحقق من أول التزام ...
$ git checkout ce861e4c6989a118aade031020fd936bd28d535b Note: checking out 'ce861e4c6989a118aade031020fd936bd28d535b'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -b with the checkout command again. Example: git checkout -b <new-branch-name> HEAD is now at ce861e4 Add CSS styles
... وتحديث صفحة الويب ...
النص لم يعد أحمر ، لذلك هذا التزام جيد! كلما حدث الالتزام الأحدث - أي كلما اقتربنا من الالتزام السيئ ، كان ذلك أفضل:
$ git checkout d647ac489ad43b3c6eaea5aceb02b0a7d7e5cf8e Previous HEAD position was ce861e4c6989a118aade031020fd936bd28d535b Add CSS styles HEAD is now at d647ac4 Change text color
سيخبرك Git الآن بعدد الالتزامات التي يتعين عليه البحث عنها قبل العثور على الالتزام الصحيح. يعتمد عدد الالتزامات التي ستجتازها Git على عدد الالتزامات بين الالتزام الجيد والسيئ (كلما طال الوقت ، زاد عدد المرات التي يحتاج فيها Git إلى التكرار).
الآن ، ستحتاج إلى اختبار الفرع الخاص بك مرة أخرى ومعرفة ما إذا كانت مشكلتك قد اختفت. في بعض الأحيان ، قد يكون هذا مرهقًا بعض الشيء إذا كنت تقوم بتحديث الوحدات بانتظام ، حيث قد تحتاج إلى إعادة تثبيت وحدات العقدة في مستودع الواجهة الأمامية. إذا كانت هناك تحديثات لقاعدة البيانات ، فقد تحتاج أيضًا إلى تحديثها.
يقوم git bisect
تلقائيًا بفحص الالتزام في منتصف التزاماتك الجيدة والسيئة. هنا يتم تقدير خطوة واحدة للعثور على الالتزام السيئ.
$ git bisect good 1cdbd113cad2f452290731e202d6a22a175af7f5 Bisecting: 1 revision left to test after this (roughly 1 step) [ce861e4c6989a118aade031020fd936bd28d535b] Add CSS styles $ git status HEAD detached at ce861e4 You are currently bisecting, started from branch '8d4615b'. (use "git bisect reset" to get back to the original branch)
قم بتحديث الصفحة ومعرفة ما إذا كانت مشكلتك قد اختفت. لا تزال المشكلة قائمة ، لذلك نقول لـ Git أن هذا لا يزال التزامًا سيئًا. لا داعي للإشارة إلى تجزئة الالتزام هذه المرة لأن Git سيستخدم الالتزام الذي قمت بسحبه. سنحتاج إلى تكرار هذه العملية حتى يتجاوز Git جميع الخطوات الممكنة.
$ git bisect bad Bisecting: 0 revisions left to test after this (roughly 0 steps) [cbf1b9a1be984a9f61b79ae5f23b19f66d533537] Add second paragraph to page
قم بتحديث الصفحة ، واختفت مشكلتنا مرة أخرى ، لذا يعد هذا التزامًا جيدًا:

في هذه المرحلة ، وجد Git أول ارتكاب سيئ:
$ git bisect good ce861e4c6989a118aade031020fd936bd28d535b is the first bad commit commit ce861e4c6989a118aade031020fd936bd28d535b Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:52:57 2021 +0100 Add CSS styles :000000 100644 0000000000000000000000000000000000000000 092bfb9bdf74dd8cfd22e812151281ee9aa6f01a M css
يمكننا الآن استخدام git show
لإظهار الالتزام نفسه وتحديد المشكلة:
$ git show ce861e4c6989a118aade031020fd936bd28d535b commit ce861e4c6989a118aade031020fd936bd28d535b Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:52:57 2021 +0100 Add CSS styles diff --git a/css/base.scss b/css/base.scss index e69de29..26abf0f 100644 --- a/css/base.scss +++ b/css/base.scss @@ -1,7 +1,7 @@ body { background-color: $white; margin: 0px; line-height: 20px; - color: $grey; + color: red; }
عند الانتهاء ، يمكنك تشغيل git bisect reset
تعيين الفرع الخاص بك إلى حالة العمل العادية.
كلما اقتربت الالتزامات معًا ، كان من الأسهل لـ Git العثور على المشكلة ، لكنني استغرقت 10 خطوات من قبل وما زلت أجد الالتزام السيئ بسهولة. إنه غير مضمون للعمل ، لكنه وجد المشكلة في معظم الأحيان بالنسبة لي. تهانينا ، أنت الآن عالم آثار مشفر!
سحق التزاماتك
عملت سابقًا بدوام كامل في مشروع مفتوح المصدر لمنظمة عالمية وسرعان ما تعلمت مدى أهمية سحق - أو دمج - التزاماتك. أعتقد أنها عادة رائعة أن تمارسها ، حتى لو لم يطلبها صاحب العمل. إنه يراعي بشكل خاص المطورين الآخرين الذين سيحتاجون إلى مراجعة وتحرير الميزات التي قمت بإنشائها لاحقًا.
لماذا الاسكواش الخاص بك؟
- من الأسهل على المساهمين في المستودع الخاص بك قراءتها. تخيل لو كان لديك قائمة تنفيذ مثل ذلك:
- تنفيذ شريط التمرير الدائري
- أضف التصميم إلى الرف الدائري
- أضف أزرارًا إلى الرف الدائري
- إصلاح مشكلة غريبة في IE مع دائري
- ضبط الهوامش في الرف الدائري
من الأسهل بكثير جمعها في التزام واحد يقول "إضافة مكتبة إلى الصفحة الرئيسية".
- يشجعك على إبقاء رسائل الالتزام مفهومة وذات صلة إذا كنت في كل مرة تقدم فيها طلب سحب ، عليك أن تسحق التزاماتك في واحدة. كم مرة رأيت التزامًا بعنوان "ويب" أو "إصلاح خطأ لصفحة تسجيل الدخول" أو "إصلاح الخطأ المطبعي"؟ من المهم أن يكون لديك أسماء التزام ذات صلة ، مثل "Bugfix لصفحة تسجيل الدخول # 444 - إصلاح الوميض بسبب فقدان وظيفة النطاق $".
قد يكون السبب وراء عدم رغبتك في سحق التزاماتك هو أنك تعمل على ميزة مفصلة للغاية وطويلة ، وتريد الاحتفاظ بسجل يومي لنفسك في حالة مواجهة أخطاء في وقت لاحق. ومن ثم فإن الميزة الخاصة بك أسهل في التصحيح. ومع ذلك ، عند التحقق من الميزة الخاصة بك في الفرع الرئيسي الخاص بك وأنت واثق من أنه خالٍ من الأخطاء ، فلا يزال من المنطقي سحقها.
في هذا السيناريو ، قمت بخمسة التزامات ، لكن جميعها مرتبطة بميزة واحدة. ترتبط رسائل الالتزام أيضًا ارتباطًا وثيقًا بفصل الجدارة - كل التزاماتي تتعلق بتصميم الصفحة لهذه الميزة الجديدة:
$ git log commit a8fbb81d984a11adc3f72ce27dd0c39ad24403b7 (HEAD -> main) Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 11:16:10 2021 +0100 Import colors commit e2b3ddd5e8b2cb1e61f88350d8571df51d43bee6 Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 11:15:32 2021 +0100 Add new color commit d647ac489ad43b3c6eaea5aceb02b0a7d7e5cf8e Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:50:48 2021 +0100 Change text color commit c005d9ceeefd4a8d4e553e825fa40aaafdac446e Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 09:59:57 2021 +0100 Add CSS styles commit 9e046b7df59cef07820cc90f694fabc666731bd2 Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 09:56:28 2021 +0100 Add second paragraph to page commit 5aff973577d67393d914834e8af4c5d07248d628 Author: Ursula Clarke <[email protected]> Date: Mon Jan 10 16:04:22 2021 +0100 Add colors CSS file and edit background color
يمكنك أيضًا استخدام git merge --squash
، لكنني أعتقد أنه من الواضح استخدام rebase
لأنه عندما تختار جيدًا التزاماتك ، يكون من الأسهل رؤية وصف الالتزام. إذا قمت بتشغيل git merge --squash
، فسيتعين عليك أولاً إعادة ضبط التزاماتك ( git reset --hard HEAD~1
) ، ومن السهل الخلط بينك وبين عدد الالتزامات التي تحتاج إلى القيام بذلك. أجد أن git rebase
تكون أكثر وضوحًا.
ابدأ بتشغيل git rebase -i --root
وسيتم فتح محرر النصوص الافتراضي الخاص بك في سطر الأوامر بقائمة التزاماتك:
pick eb1eb3c Update homepage pick 5aff973 Add colors CSS file and edit background color pick 9e046b7 Add second paragraph to page pick c005d9c Add CSS styles pick d647ac4 Change text color pick e2b3ddd Add new color pick a8fbb81 Import colors # Rebase a8fbb81 onto b862ff2 (7 commands) # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # d, drop = remove commit # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. # # However, if you remove everything, the rebase will be aborted. # # Note that empty commits are commented out
قد ترغب فقط في سحق التزاماتك القليلة الأخيرة ، وفي هذه الحالة يمكنك تشغيل git rebase -i HEAD~3
مع التزاماتك الثلاثة الأخيرة:
pick eb1eb3c Update homepage pick 5aff973 Add colors CSS file and edit background color pick 9e046b7 Add second paragraph to page # Rebase b862ff2..9e046b7 onto b862ff2 (3 commands) # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # d, drop = remove commit # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. # # However, if you remove everything, the rebase will be aborted. # # Note that empty commits are commented out
الآن يمكننا سحق جميع الالتزامات في أول التزام كما هو موضح أدناه.
pick eb1eb3c Update homepage squash 5aff973 Add colors CSS file and edit background color squash 9e046b7 Add second paragraph to page # Rebase b862ff2..9e046b7 onto b862ff2 (3 commands) # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # d, drop = remove commit # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. # # However, if you remove everything, the rebase will be aborted. # # Note that empty commits are commented out
عند حفظ الملف ، سيفتح Git رسالة الالتزام لتحريرها.
# This is a combination of 3 commits. # This is the 1st commit message: Update homepage # This is the commit message #2: Add colors CSS file and edit background color # This is the commit message #3: Add second paragraph to page # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # Date: Wed Jan 13 18:31:28 2021 +0100 # # interactive rebase in progress; onto b862ff2 # Last commands done (3 commands done): # squash 5aff973 Add colors CSS file and edit background color # squash 9e046b7 Add second paragraph to page # No commands remaining. # You are currently rebasing branch 'main' on 'b862ff2'. # # Changes to be committed: # new file: .gitignore # new file: css/base.css # new file: css/base.scss # new file: css/colors.css # new file: css/colors.css.map # new file: css/colors.scss # new file: css/common.css # new file: css/common.scss # new file: index.html #
أثناء قيامنا بإعادة الأساسي ، يمكننا أيضًا تعديل وصف الالتزام بحيث يسهل قراءته.
Implement new design for homepage. Add .gitignore file for Sass folder. # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. #
احفظ هذا الملف مرة أخرى وانتهيت! عندما نلقي نظرة أخرى على سجل Git ، يمكننا أن نرى أن هناك التزامًا واحدًا نظيفًا.
[detached HEAD 574ec7e] Implement new design for homepage. Add .gitignore file for Sass folder. Date: Wed Jan 13 18:31:28 2021 +0100 10 files changed, 215 insertions(+) create mode 100644 .gitignore create mode 100644 css/base.css create mode 100644 css/base.scss create mode 100644 css/colors.css create mode 100644 css/colors.css.map create mode 100644 css/colors.scss create mode 100644 css/common.css create mode 100644 css/common.scss create mode 100644 index.html create mode 100644 verylargefile.txt Successfully rebased and updated refs/heads/main. $ git log commit 574ec7e5d7d7a96427e049cad9806cdef724aedd (HEAD -> main) Author: Ursula Clarke <[email protected]> Date: Wed Jan 13 18:31:28 2021 +0100 Implement new design for homepage. Add .gitignore file for Sass folder.
Git Rebase
عادةً ما يتردد المطورون في استخدام git rebase
لأنهم يعرفون أنه يمكن استخدام rebase لحذف الملفات نهائيًا من قاعدة التعليمات البرمجية الخاصة بك.
كما رأينا أعلاه ، يمكن استخدام git rebase
للحفاظ على التعليمات البرمجية الخاصة بك وترتيبها وكذلك الحذف - ولكن ماذا لو كنت تريد حقًا إزالة ملف نهائيًا من السجل؟
لقد شاهدت ذات مرة سيناريو قام فيه أحد أعضاء فريق التطوير لدينا بطريق الخطأ بإدخال ملف كبير جدًا إلى قاعدة التعليمات البرمجية. كان جزءًا من فرع أكبر بكثير ، لذا فقد ذهب الملف الكبير دون أن يلاحظه أحد في مراجعة الكود وتم فحصه عن طريق الخطأ في الفرع الرئيسي. أصبحت هذه مشكلة كلما أراد أي شخص إعادة استنساخ المستودع - استغرق التنزيل وقتًا طويلاً جدًا! وبالطبع ، كان الملف المعني غير ضروري. لن تكون مشكلة إذا كان الملف هو آخر التزام للفرع الرئيسي - في هذه الحالة يمكنك فقط تشغيل إعادة تعيين ثابت ( git reset --hard HEAD~1
) وفرض دفع الفرع.
وبالمثل ، إذا كان الملف هو التغيير الوحيد في التزام معين ، فيمكنك فقط إزالة الالتزام بالكامل عن طريق تشغيل git reset --hard <commit-id>
. في السيناريو الخاص بنا ، على الرغم من ذلك ، تم الالتزام بالملف الكبير جنبًا إلى جنب مع التعليمات البرمجية الأخرى التي أردنا الاحتفاظ بها في التاريخ ، مثل الالتزام الثاني إلى الأخير.
بمجرد العثور على الالتزام المزعج ، تحقق منه باستخدام git checkout
وتجزئة الالتزام:
$ git checkout ce861e4c6989a118aade031020fd936bd28d535b Note: checking out 'ce861e4c6989a118aade031020fd936bd28d535b'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -b with the checkout command again. Example: git checkout -b <new-branch-name> HEAD is now at ce861e4 Add CSS styles
قم بإزالة الملف ، أو تحرير التعليمات البرمجية الخاصة بك ، وترك الرمز (أو الملفات) التي تريد الاحتفاظ بها كما هي.
$ rm verylargefile.txt $ git status HEAD detached at ce861e4 Changes not staged for commit: (use "git add/rm <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) deleted: verylargefile.txt no changes added to commit (use "git add" and/or "git commit -a")
تأكد من تشغيل git add -A
بحيث يتم تنظيم ملفك المحذوف ويعرف Git أنه يزيله. الآن قم بتشغيل git commit --amend -v
منك Git تعديل رسالة الالتزام.
بعد ذلك ، قم بتشغيل الأمر git rebase --onto HEAD <commit-id> main
. هذا هو المكان الذي يمكن أن تصادف فيه بعض تعارضات الدمج ، مما يعني وجود تعارض بين الالتزام الجديد والتعليمات البرمجية القديمة. سيطلب منك Git حل النزاع:
$ git add -A $ git status HEAD detached at ce861e4 Changes to be committed: (use "git reset HEAD <file>..." to unstage) deleted: verylargefile.txt $ git commit --amend -v [detached HEAD 7c9516a] Add CSS styles Date: Thu Jan 14 14:43:54 2021 +0100 3 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 css/common.css.map delete mode 100644 verylargefile.txt $ git status HEAD detached from ce861e4 nothing to commit, working tree clean $ git rebase --onto HEAD ce861e4 First, rewinding head to replay your work on top of it... Fast-forwarded HEAD to HEAD.
إذا فتحت الملف في محرر النصوص الخاص بك ، فسترى أن Git قد حدد نسختين من ملف الفهرس. ما عليك سوى إزالة واحد أو تعديل واحد للاحتفاظ بالتغييرات التي تريدها.
<p> Toptal was created by engineers. We are entrepreneurs, all passionate about working with top tech talent and exciting companies from all over the world. </p> <<<<<<< HEAD <p> Toptal connects the top 3% of freelance talent all over the world. </p> </main> </body> </html> ======= </main> </body> </html> >>>>>>> Add index file
الكود بين <<<<<<< HEAD
وسطر علامات يساوي هو إصدار واحد ، والشفرة بين علامات يساوي و >>>>>>> Add index file
هو الإصدار من "إضافة ملف فهرس" . لذلك يمكنك أن ترى أن أحد الإصدارات يحتوي على فقرة إضافية من "Toptal يربط بين أفضل 3٪ من المواهب المستقلة في جميع أنحاء العالم" ، بينما لا يحتوي الإصدار الآخر على ذلك.
احفظ الملف الذي تم تحريره وقم بتشغيل git add filename
متبوعًا بـ git rebase --continue
. إذا لم تكن هناك تغييرات ، يمكنك أيضًا تشغيل git rebase --skip
. قد تستغرق عملية إعادة التأسيس بعض الوقت إذا كان هناك الكثير من الالتزامات بين الالتزام "بالملف الكبير" وآخر التزام في main.
تحلى بالصبر ، وإذا كنت في فريق كبير فتأكد من الحصول على رأي ثان! من المهم بشكل خاص التشاور مع الشخص (الأشخاص) الذي كتب الالتزام (الالتزامات) التي تدمجها ، إن أمكن.
تذكر أن تغييرات الدمج ذات صلة بالالتزام المحدد في السجل ، وليست أحدث التغييرات التي أجريتها. أي إذا كنت تقوم بتحرير التزام من وقت كان النص الموجود على موقعك هو Arial ، وهو الآن Verdana ، فلا يزال يتعين عليك الالتزام بتاريخ Arial باعتباره وجه الخط.
لاحظ أيضًا أنه إذا رأى Git مسافة أو نهاية حرف السطر ، فقد يتسبب ذلك في حدوث تعارض في الدمج ، لذا كن حذرًا!
أكثر من مجرد الالتزام والسحب
Git أقوى مما يعتقده الكثير من المطورين. إذا كنت تقدم مبتدئًا ، فتأكد من إعطائهم بعض النصائح حول هذه الميزات التي لا تقدر بثمن. يجعل سير العمل أكثر كفاءة.
هل تبحث عن معرفة المزيد عن Git؟ ألق نظرة على صفحة نصائح وممارسات Toptal's Git.