git stash: احفظ عملك مؤقتاً وعد إليه لاحقاً
أنت في منتصف العمل على قائمة التنقل، والكود نصف مكتوب ولا يعمل. فجأة يصلك بلاغ: خطأ عاجل في الموقع يجب إصلاحه الآن. لا تريد حفظ commit بكود مكسور، ولا تريد أن تخسر ما كتبته. الحل هو git stash: يضع تعديلاتك جانباً، ويعيد المجلد نظيفاً، ثم يرجعها لك متى شئت.
تخيّل stash مثل دُرج المكتب: تجمع الأوراق المبعثرة وتضعها فيه لتفرغ سطح المكتب لمهمة عاجلة، ثم تخرجها وتكمل من حيث توقفت.
الحفظ والاسترجاع
Section titled “الحفظ والاسترجاع”عدّلنا index.html وأنشأنا ملفاً جديداً draft.html:
git status --short M index.html?? draft.htmlgit stashSaved working directory and index state WIP on main: 53be69f Revert "إضافة شريط متحرك"WIP اختصار «عمل قيد التنفيذ» (Work In Progress). لنرَ الحالة الآن:
git status --short?? draft.htmlتعديل index.html اختفى وعاد الملف كما في آخر commit. لكن draft.html ما زال موجوداً! السبب: git stash يخزّن افتراضياً تعديلات الملفات المتتبَّعة فقط، ويترك الملفات الجديدة في مكانها.
للاسترجاع:
git stash popOn branch mainChanges not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: index.html
Untracked files: (use "git add <file>..." to include in what will be committed) draft.html
no changes added to commit (use "git add" and/or "git commit -a")Dropped refs/stash@{0} (e4abac08bff563df57b9248b8607d9e71a84d343)pop أعادت التعديلات إلى الملفات، وحذفت المخزون (السطر الأخير: Dropped).
تخزين الملفات الجديدة أيضاً: -u
Section titled “تخزين الملفات الجديدة أيضاً: -u”لتخزين كل شيء، بما فيه الملفات غير المتتبَّعة، أضف -u:
git stash -ugit status --shortالأمر الثاني لا يطبع شيئاً: المجلد نظيف تماماً، و draft.html دخل المخزون مع التعديل.
السيناريو الكامل: إصلاح عاجل
Section titled “السيناريو الكامل: إصلاح عاجل”الآن والمجلد نظيف، ننفّذ الإصلاح العاجل كما تعلمت في درس الفروع:
git switch -c hotfix# ... نصلح الخطأ ونحفظه ...git commit -am "تصحيح عنوان README"git switch maingit merge hotfixgit branch -d hotfixثم نعود لعملنا:
git stash popعاد تعديل index.html وملف draft.html فوق النسخة الجديدة التي فيها الإصلاح. أكملنا من حيث توقفنا كأن شيئاً لم يقاطعنا.
أكثر من مخزون
Section titled “أكثر من مخزون”يمكنك تخزين عدة أعمال، وكل مخزون جديد يوضع فوق السابق. وحتى لا تنسى محتوى كل واحد، أعطه اسماً بـ -m:
git stash push -u -m "قائمة التنقل"# ... تجربة أخرى: غيّرنا لون العنوان ...git stash push -m "تجربة لون أحمر"git stash liststash@{0}: On main: تجربة لون أحمرstash@{1}: On main: قائمة التنقلstash@{0}هو الأحدث دائماً، والأرقام تكبر مع الأقدم.git stash pushهو الاسم الكامل للأمر، وgit stashوحدها اختصار له.
لمعرفة ما بداخل مخزون دون استرجاعه:
git stash show stash@{0} about.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)وأضف -p لرؤية الأسطر المتغيرة نفسها.
apply و drop
Section titled “apply و drop”pop تسترجع وتحذف. إذا أردت الاسترجاع مع إبقاء المخزون، مثلاً لتطبيقه على أكثر من فرع، استخدم apply:
git stash apply stash@{1}git stash liststash@{0}: On main: تجربة لون أحمرstash@{1}: On main: قائمة التنقلالتعديلات عادت إلى الملفات، والمخزونان ما زالا في القائمة. وللحذف يدوياً:
git stash drop stash@{0}Dropped stash@{0} (c65a4b7018b02329d1e506822daea45299686b8c)| الأمر | الوظيفة |
|---|---|
git stash pop |
استرجاع الأحدث وحذفه من القائمة |
git stash apply |
استرجاع مع إبقاء المخزون |
git stash drop |
حذف مخزون دون استرجاعه |
git stash clear |
حذف كل المخزونات |
بدون رقم، تعمل هذه الأوامر على stash@{0}.
عندما يفشل الاسترجاع
Section titled “عندما يفشل الاسترجاع”بعد apply السابقة حفظنا العمل في commit، ثم نفّذنا pop للمخزون نفسه:
git stash popdraft.html already exists, no checkouterror: could not restore untracked files from stashThe stash entry is kept in case you need it again.Git رفض أن يكتب فوق draft.html الموجود. والمهم هو السطر الأخير: عند أي فشل يبقى المخزون في القائمة ولا يضيع شيء. الأمر نفسه إذا تعارضت تعديلات المخزون مع ما تغيّر في الملفات: تظهر علامات التعارض التي تعرفها، فتحلها ثم تحذف المخزون بـ git stash drop.
من مخزون إلى فرع
Section titled “من مخزون إلى فرع”أحياناً تكتشف أن التجربة المخزَّنة تستحق فرعاً مستقلاً:
git stash branch css-ideaSwitched to a new branch 'css-idea'On branch css-ideaChanges not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: about.css
no changes added to commit (use "git add" and/or "git commit -a")Dropped refs/stash@{0} (6c9ab3df9388f8de89d171f39ba8fc96860a20dd)أمر واحد أنشأ الفرع، وانتقل إليه، واسترجع التعديلات، وحذف المخزون.
جرّب بنفسك
Section titled “جرّب بنفسك”- عدّل ملفاً متتبَّعاً وأنشئ ملفاً جديداً، ثم نفّذ
git stashولاحظ أي الملفين بقي. - استرجع بـ
git stash pop، ثم أعد التخزين بـgit stash -uوتأكد أن المجلد نظيف. - أنشئ مخزونين باسمين مختلفين، واعرضهما بـ
git stash list، واسترجع الأقدم منهما بـapply. - تحدٍّ: حاكِ السيناريو الكامل: عمل ناقص، ثم
stash، ثم إصلاح على فرعhotfixودمجه، ثمpop.
أخطاء شائعة
Section titled “أخطاء شائعة”- نسيان الملفات الجديدة:
git stashبدون-uيترك الملفات غير المتتبَّعة في المجلد. - نسيان المخزون: تتراكم مخزونات قديمة لا تتذكر محتواها. سمّها بـ
-m، وراجعgit stash listبين حين وآخر. stash clearبتسرع: يحذف كل المخزونات دون سؤال، واستعادتها صعبة.- pop على فرع آخر: التعديلات تعود إلى الفرع الحالي أياً كان. تأكد من الفرع بـ
git statusقبل الاسترجاع.
اختبر نفسك
Section titled “اختبر نفسك”سؤال
ما الفرق بين git stash pop و git stash apply؟
كلتاهما تعيد التعديلات، لكن apply تترك المخزون في القائمة لاستخدامه مرة أخرى.
سؤال
أنشأت ملفاً جديداً لم تضفه بـ git add، ثم نفّذت git stash. أين الملف؟
لتخزين الملفات غير المتتبَّعة أيضاً استخدم git stash -u.
الخلاصة
Section titled “الخلاصة”git stashيخزّن التعديلات غير المحفوظة ويعيد المجلد نظيفاً، و-uتضم الملفات الجديدة.git stash popيسترجع ويحذف، وapplyيسترجع ويبقي، وdropيحذف.git stash listيعرض المخزونات، و-mتعطيها أسماء، وstash@{0}هو الأحدث.- عند فشل الاسترجاع يبقى المخزون سليماً في القائمة.
git stash branchيحوّل المخزون إلى فرع، والمخزون للمقاطعات القصيرة فقط.