git undo keep changes — الأسئلة الشائعة لكل تهجئةٍ خائفة
الأسئلة الشائعة لكل تهجئة من تهجئات «ألغِ التبريز واحتفظ بالعمل» — أمرٌ واحد يجيب عن العائلة كلها، والخيار الوحيد الذي يمحو العمل لا يُطلب أبدًا.
■ space · مسار النثر · الأسئلة الشائعة
أمرٌ واحد يجيب عن العائلة كلها — git reset --soft HEAD~1 يدرّ لصيقة الفرع تبريزةً واحدةً إلى الوراء ويعيد إليك عملك مُرهَّنًا جاهزًا.
undo وcancel وrevert ليست ثلاث خصائص في git. اثنان منها نفس الـreset بلهجتين مختلفتين؛ وrevert هو الشاذ في العائلة لأنه يضيف تاريخًا بدل ترديد الشريط إلى الوراء.
دفعته مسبقًا؟ revert، ولا ترديد أبدًا — فكل من سحبَ يحمل التبريزات القديمة.
git reset --soft HEAD~1 هو الجواب عن كل تهجئةٍ من تهجئات keep-changes: فاللصيقة تدرّ تبريزةً إلى الوراء ويعود عملك مُرهَّنًا جاهزًا لإعادة التبريز. وهل دفعت التبريزة أصلًا؟ فاستعمل git revert HEAD بدلًا منه — فهو يضيف تبريزةً معاكسة ولا يعيد كتابة شيء.جدول الأفعال
كل كلمةٍ يكتبها الناس، وما يفعله git حقًا، وهل ينجو العمل:
| الفعل الذي يكتبه الناس | ما يفعله git حقًا | يحفظ العمل؟ | الأمر |
|---|---|---|---|
| "undo" | لصيقة الفرع تدرّ تبريزةً إلى الوراء؛ والتغييرات تعود مُرهَّنة | نعم — في الدليل | git reset --soft HEAD~1 |
| "cancel" | الـreset الافتراضي: اللصيقة تدرّ، والتغييرات تعود بلا رهن | نعم — في شجرة العمل | git reset HEAD~1 |
| "revert" | تُضاف تبريزةٌ جديدة تُبطل القديمة؛ ولا يُعاد كتابة التاريخ أبدًا | نعم — بوصفه فرقًا معاكسًا | git revert HEAD |
| "unstage" | المسارات تغادر الدليل؛ ومحتوى الملفات لم يُمسّ | نعم — لم يغادر شيء شجرة العمل | git restore --staged file.txt |
| "دفعه جانبًا حاليًا" | يُعبَّأ العمل ويوضع على رفٍّ يمكنك سحبه لاحقًا | نعم — في كومة الـstash | git stash push -m "wip" |
القرار الوحيد الذي يهم: هل سحبه أحد؟
لا — فهو ما يزال لك: git reset --soft HEAD~1. تلصيقة تدرّ، ويعود عملك مُرهَّنًا. نعم — فقد سحبه أحد: git revert HEAD. فينمأ التاريخ تبريزةً معاكسةً؛ ولا يُعاد كتابة ما سحبه أحد. وفي الحالتين ينجو العمل — والاختيار لا يتعدى الأمر الذي تظل نسخته من التاريخ صائبة. وإن كان الخيار الذي يخيفك هو --hard: فهو العضو الوحيد في العائلة الذي يمحو العمل، ولا يُطلب أبدًا لكي تحفظ التغييرات. لقد وجدت هذه الصفحة تحديدًا كي لا تحتاج إلى كتابته قط.
ما الذي يحفظه --soft فعلًا؟
كل شيء، ومُرهَّنًا. فالتبريزة تغادر الفرع، والفرق يعود إلى الدليل بذاته كما تبرّز، ويقرأ git status «changes to be committed». أصلح ما أردتَ أن تصلح ثم أعِد التبريز — أو ادمج عملًا إضافيًا أولًا. ويخالف --amend خلفيته خطوةً واحدة: فالـamend يعيد كتابة التبريزة الأخيرة في مكانها، والـsoft يلغيها ويترقّبك.
أليس الـamend إلغاءً؟
إلغاءٌ صغير، للتبريزة الأخيرة وحدها. فالـgit commit --amend --no-edit يدمج التغييرات المُرهَّنة في التبريزة التي أقدمت عليها للتو — مثالي للملف المنسي. وقاعدة القسم الخاص بالتبريزات المدفوعة تظل صحيحة: تبديل التبريزة المدفوعة يعيد كتابة التاريخ، فاجعل الـrevert بدلًا منه على الفرع المشترك.
متى يكون --hard هو الجواب الصائب فعلًا؟
حين تريد أن تطابق شجرة العمل تبريزةً ذاتها تمامًا، وقد نظرت فيما سيضيع. فإن الـgit reset --hard HEAD~1 يبيد التبريزة والتعديلات غير المبريزة في حركة واحدة — ولن يسأل git مرتين. وطقس الأمان سطرٌ واحد: نفّذ git branch backup-before-reset أولًا؛ فالفروع مجانية. وإن كنت قد نفّذته فقد، فالـgit reflog يتذكر مكان HEAD منذ نحو 90 يومًا — ليعيده git reset --hard HEAD@{1} إلى الوراء.
كيف أرمي تعديلات ملفٍ واحد فقط؟
git restore file.txt — وهو الرسم الحديث للـgit checkout -- file القديم. فهو يبيد تعديلات شجرة العمل لذلك المسار وحده ولا يلمس شيئًا آخر: لا حركةَ فرع، ولا تغييرَ في الرهن. ولإعادة ملفٍ إلى تبريزةٍ بعينها: git restore --source <sha> file.txt.
أين يقع الـstash في العائلة؟
الـstash هو الفعل الوحيد الذي يعبّئ العمل جانبًا بدل أن يعيد تموضعه. فالـgit stash push -m "wip" يرفع تعديلاتك على الرف ويسلّمك شجرةً نظيفة؛ والـgit stash pop يُعيد إليك إياها. وهو الأداة الصائبة حين تنتقل بين الفروع في منتصف المهمة — ويأخذ مسارًا محددًا (pathspec)، فيمكن رفع ملفٍ واحد على الرف بقاءَ البقية قذرة.
نفّذتُ الأمر الغلط أصلًا. هل ذهب العمل؟
كاد أن يكون لا أبدًا. فالـreset يحرّك لصيقةً؛ والـrevert يضيف تبريزةً؛ ولا يمحو أيٌّ منهما كائنات. والـgit reflog يسرد كل مكانٍ قام إليه HEAD منذ نحو 90 يومًا — فجد الطلب السابق للخطأ وسيعيدك git reset --hard HEAD@{n} إلى هناك. والمجموعة غير القابلة للاسترجاع حقًا ضيّقة: ملفاتٌ غير متتبَّعة محوها الـgit clean -f، وطلباتُ قام الـreflog تجاوز ساعتها.
نهاية عائلة الأفعال · لا شيء مُجلب · كل شيء محلي