Git: شرح مفصل لعمليات «Git reset» و«Undo»
يُعد «Reset» أمرًا قويًّا للتراجع في Git. باستخدام «Reset»، يمكنك التراجع عن عمليات الالتزام، وإلغاء تجهيز التغييرات، وإلغاء التعديلات. ويُعد فهم الأوضاع الثلاثة لـ «Reset» أمرًا بالغ الأهمية في إدارة الإصدارات.
1. إعادة النظر في المفاهيم الأساسية
(1) ما المقصود بـ«إعادة الضبط»؟
إعادة الضبط هي عملية تنقل الفرع الحالي إلى موقع محدد:
- نقل مؤشر الفرع: نقل HEAD ومؤشر الفرع إلى الالتزام المحدد
- تحديث منطقة التخزين المؤقت: تحديد ما إذا كان سيتم تحديث منطقة التخزين المؤقت بناءً على الوضع
- تحديث مساحة العمل: تحديد ما إذا كان سيتم تحديث مساحة العمل بناءً على الوضع
- التراجع عن الإجراءات: التراجع عن عمليات التسجيل، والتحضير، والتعديلات
graph TB
A[git reset] --> B{Pattern}
B -->|soft| C[Move only the pointer<br/>Preserve the temporary storage area and the workspace]
B -->|mixed| D[Move the pointer+Update the temporary storage area<br/>Save Workspace]
B -->|hard| E[Move the pointer+Update the temporary storage area+Update Workspace]
style C fill:#d4edda
style D fill:#fff3cd
style E fill:#f8d7da
(2) المجالات الثلاثة لـ Git
لفهم reset، عليك أولاً فهم مجالات العمل الثلاثة في Git:
graph TB
HEAD[HEADPointer] --> Branch[Branch pointer]
Branch --> Repo[Repository<br/>Repository]
Repo --> Stage[Buffer<br/>Staging Area]
Stage --> Work[Workspace<br/>Working Directory]
style HEAD fill:#f8d7da
style Repo fill:#c3e6cb
style Stage fill:#d4edda
style Work fill:#fff3cd
- HEAD: يشير إلى الفرع الحالي
- مؤشر الفرع: يشير إلى التزام معين
- المستودع: يخزن جميع عمليات التسجيل
- منطقة التجهيز: التغييرات الجاهزة للتثبيت
- مساحة العمل: الملفات التي تقوم بتحريرها فعليًّا
(3) إعادة ضبط الاتجاه
يمكنك إعادة الضبط للأمام أو للخلف:
- إعادة الضبط إلى الوراء: التراجع عن عملية التسجيل والعودة إلى الحالة السابقة
- إعادة الضبط إلى الأمام: الانتقال إلى الالتزام التالي (نادرًا ما يُستخدم)
2. ثلاثة أوضاع لإعادة الضبط
(1) إعادة الضبط البسيطة (--soft)
قم بنقل مؤشرات HEAD والفرع فقط، مع الحفاظ على منطقة التجهيز ومنطقة العمل.
▶ مثال: إعادة الضبط البسيطة
# View Current Status
git log --oneline -3
# Output:
# d4e5f6g (HEAD -> main) feat: Add FeatureC
# h7i8j9k feat: Add FeatureB
# k9l0m1n feat: Add FeatureA
# Soft reset to the previous commit
git reset --soft HEAD~1
# View Status
git status
# Output:
# On branch main
# Changes to be committed:
# (use "git restore --staged <file>..." to unstage)
# new file: feature-c.js
# View History
git log --oneline -3
# Output:
# h7i8j9k (HEAD -> main) feat: Add FeatureB
# k9l0m1n feat: Add FeatureA
# a1b2c3d Initial commit
# The commit is still in the staging area,You can resubmit it.
git commit -m "feat: Re-add FeatureC"
آثار إعادة الضبط البسيطة:
- ✅ التراجع عن الالتزام
- ✅ الاحتفاظ بالتغييرات في منطقة التجهيز (لا تزال التغييرات موجودة في منطقة التجهيز)
- ✅ الحفاظ على مساحة العمل (تظل الملفات دون تغيير)
(2) إعادة الضبط المختلط (--mixed، الإعداد الافتراضي)
نقل مؤشري HEAD والفرع، وتحديث منطقة التجهيز، والحفاظ على دليل العمل.
▶ مثال: إعادة الضبط المختلط
# View Current Status
git log --oneline -3
# Output:
# d4e5f6g (HEAD -> main) feat: Add FeatureC
# h7i8j9k feat: Add FeatureB
# k9l0m1n feat: Add FeatureA
# Mixed Reset(Default Mode)
git reset HEAD~1
# Or specify explicitly
git reset --mixed HEAD~1
# View Status
git status
# Output:
# On branch main
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
# feature-c.js
# View History
git log --oneline -3
# Output:
# h7i8j9k (HEAD -> main) feat: Add FeatureB
# k9l0m1n feat: Add FeatureA
# Edits in the workspace,Needs to be redoneadd
git add feature-c.js
git commit -m "feat: Re-add FeatureC"
آثار إعادة الضبط الهجينة:
- ✅ التراجع عن الالتزام
- ✅ إلغاء التجهيز (نقل التغييرات من منطقة التجهيز إلى منطقة العمل)
- ✅ الحفاظ على مساحة العمل (تظل الملفات دون تغيير)
(3) إعادة الضبط الكامل (--hard)
قم بتحريك مؤشرات HEAD والفرع، وقم بتحديث منطقة التجهيز والدليل العملي.
▶ مثال: إعادة الضبط الكامل
# View Current Status
git log --oneline -3
# Output:
# d4e5f6g (HEAD -> main) feat: Add FeatureC
# h7i8j9k feat: Add FeatureB
# k9l0m1n feat: Add FeatureA
# Hard Reset
git reset --hard HEAD~1
# Output:
# HEAD is now at h7i8j9k feat: Add FeatureB
# View Status
git status
# Output:
# On branch main
# nothing to commit, working tree clean
# View History
git log --oneline -3
# Output:
# h7i8j9k (HEAD -> main) feat: Add FeatureB
# k9l0m1n feat: Add FeatureA
# ⚠️ FeaturesCThe changes have been completely lost!
آثار إعادة الضبط الكامل:
- ✅ التراجع عن الالتزام
- ✅ إزالة من قائمة المفضلة
- ✅ تجاهل التغييرات في مساحة العمل (استعادة الملف إلى الحالة التي كان عليها عند التزام محدد)
⚠️ تحذير: ستؤدي إعادة الضبط الكاملة إلى فقدان جميع التغييرات التي لم يتم حفظها. استخدم هذه الميزة بحذر!
3. مقارنة بين أوضاع إعادة الضبط
(1) جدول مقارنة بين الأنماط الثلاثة
| الوضع | HEAD | منطقة التجهيز | دليل العمل | الغرض |
|---|---|---|---|---|
| soft | نقل | غير قابل للتغيير | غير قابل للتغيير | التراجع عن الإرسال، إعادة الإرسال |
| مختلط | نقل | تحديث | الاحتفاظ | التراجع والتجهيز |
| صعب | نقل | تحديث | تحديث | التراجع الكامل، إلغاء التغييرات |
(2) أمثلة توضيحية للأنماط الثلاثة
graph TB
subgraph Before the reset
A1[HEAD -> C3] --> B1[Buffer: C3Status]
B1 --> C1[Workspace: C3Status]
end
subgraph softReset
A2[HEAD -> C2] --> B2[Buffer: C3Status<br/>Retain]
B2 --> C2[Workspace: C3Status<br/>Retain]
end
subgraph mixedReset
A3[HEAD -> C2] --> B3[Buffer: C2Status<br/>Update]
B3 --> C3[Workspace: C3Status<br/>Retain]
end
subgraph hardReset
A4[HEAD -> C2] --> B4[Buffer: C2Status<br/>Update]
B4 --> C4[Workspace: C2Status<br/>Update]
end
(3) حدد الوضع المناسب
سيناريوهات استخدام «soft»:
- لقد ارتكبت خطأً في المعلومات التي قدمتها وأود إعادة تقديمها
- أريد دمج عدة عمليات التزام في عملية واحدة
- تعديل محتوى الطلب المقدم
سيناريوهات استخدام mixed:
- التراجع عن عملية الالتزام وإعادة تنظيم التغييرات
- قم بإلغاء تحديد الملفات الموجودة في منطقة التحضير، ثم أعد تحديد الملفات التي تريد إرسالها
- الوضع الافتراضي، وهو الأكثر استخدامًا
سيناريوهات استخدام كلمة "hard":
- إلغاء جميع التغييرات الحالية
- العودة إلى حالة معينة
- تنظيف مساحة العمل (يُستخدم بحذر)
4. شرح مفصل لعملية إعادة الضبط
(1) إعادة التعيين إلى التزام معين
▶ مثال: الرجوع إلى «كوميت» معين
# Revert to a Specific CommitID
git reset a1b2c3d
# Reset to a Specific Tag
git reset v1.0.0
# Reset to Relative Position
git reset HEAD~1 # Previous Commit
git reset HEAD~3 # Previous 3 commits
git reset HEAD^ # Previous Commit(Equivalent toHEAD~1)
git reset HEAD^^ # The first two commits
# Reset to a remote branch
git reset origin/main
(2) التراجع عن التخزين المؤقت
▶ مثال: إلغاء الإعداد
# View the Stash
git status
# Output:
# Changes to be committed:
# new file: file1.js
# new file: file2.js
# Uncheck "Save a file to the clipboard"
git reset file1.js
# Or userestore
git restore --staged file1.js
# Discard all changes
git reset
# View Status
git status
# Output:
# Untracked files:
# file1.js
# file2.js
(3) التراجع عن التغييرات التي أُجريت على مساحة العمل
▶ مثال: تجاهل التغييرات التي تم إجراؤها في مساحة العمل
# View Workspace Changes
git status
# Output:
# Changes not staged for commit:
# modified: README.md
# Discard Workspace Changes
git restore README.md
# Or use the old syntax
git checkout -- README.md
# Discard all workspace changes
git restore .
# Or
git checkout -- .
# ⚠️ This will permanently lose any unsaved changes.!
5. الفرق بين «إعادة الضبط» و«الرجوع»
(1) إعادة الضبط مقابل الرجوع إلى الحالة السابقة
| ميزة | إعادة الضبط | الرجوع |
|---|---|---|
| كيفية الاستخدام | تحريك المؤشر | إنشاء التزام جديد |
| السجل | حذف السجل | الاحتفاظ بالسجل |
| تم الإرسال | يتطلب إرسالًا قسريًّا | يمكن إرساله بشكل عادي |
| الأمان | قد تُفقد عمليات التسجيل | لن تُفقد عمليات التسجيل |
| حالات الاستخدام | عمليات التسجيل المحلية التي لم يتم إرسالها | عمليات التسجيل التي تم إرسالها |
(2) استخدم reset للتراجع عن عملية التثبيت المحلية
▶ مثال: استخدم reset للتراجع عن عملية التثبيت المحلية
# An incorrect commit was created locally
git commit -m "Incorrect Submission"
# Undo Commit(Keep the changes)
git reset --soft HEAD~1
# Resubmit after making corrections
git commit -m "Correct Submission"
# Regular Push Notifications
git push origin main
(3) استخدم revert للتراجع عن عملية «push» تم إجراؤها
▶ مثال: استخدم revert للتراجع عن عملية «push» تم إجراؤها
# Pushed commits
git push origin main
# UsagerevertCreate a Revert Commit
git revert a1b2c3d
# Output:
# [main d4e5f6g] Revert "Incorrect Submission"
# 1 file changed, 1 deletion(-)
# Regular Push Notifications
git push origin main
# The history will retain the original submission andrevertSubmit
git log --oneline
# Output:
# d4e5f6g Revert "Incorrect Submission"
# a1b2c3d Incorrect Submission
# h7i8j9k Normal submission
6. أفضل الممارسات لإعادة الضبط
(1) عملية إعادة تعيين الإعدادات الأمنية
▶ مثال: إعادة تعيين إعدادات الأمان
# 1. View Current Status
git status
git log --oneline -5
# 2. Confirm which commit to roll back to
git log --oneline
# 3. First, create a backup branch(Optional)
git branch backup-branch
# 4. Perform a reset
git reset --hard a1b2c3d
# 5. Verification Results
git log --oneline -5
git status
# If the reset is done incorrectly,Can be restored
git reset --hard backup-branch
(2) الاستعادة باستخدام reflog
▶ مثال: استعادة النظام بعد إعادة ضبط غير صحيحة
# Operational error:A hard reset caused the commit to be lost
git reset --hard HEAD~3
# Viewreflog
git reflog
# Output:
# a1b2c3d HEAD@{0}: reset: moving to HEAD~3
# d4e5f6g HEAD@{1}: commit: feat: Add FeatureC
# h7i8j9k HEAD@{2}: commit: feat: Add FeatureB
# k9l0m1n HEAD@{3}: commit: feat: Add FeatureA
# Restore to the state prior to the reset
git reset --hard d4e5f6g
# Verification and Recovery
git log --oneline -5
(3) إعادة تعيين مسار العمل
graph TB
A[The operation needs to be undone] --> B{Has the operation been pushed??}
B -->|Not pushed| C[Usagereset]
B -->|Pushed| D[Usagerevert]
C --> E{Keep or Discard Changes??}
E -->|Yes| F[reset --soft/--mixed]
E -->|No| G[reset --hard]
D --> H[Create a Revert Commit]
style C fill:#d4edda
style D fill:#fff3cd
style G fill:#f8d7da
❓ أسئلة شائعة
reset، ومتى يجب عليّ استخدام revert؟reset للتراجع عنها؛ أما بالنسبة لعمليات التسجيل التي تم إرسالها، فاستخدم revert لإنشاء عملية تسجيل عكسية. ويقوم reset بإعادة كتابة السجل، بينما يحافظ revert عليه.reset --hard إلى فقدان البيانات؟git add؟git reset <file> أو git restore --staged <file> لإزالة عنصر من منطقة التجهيز. استخدم git reset لإزالة جميع العناصر من منطقة التجهيز.git reflog لعرض سجل العمليات، وحدد موضع HEAD قبل إعادة الضبط، ثم استخدم git reset --hard <commit> لاستعادته. أو، إذا كان لديك فرع احتياطي، فما عليك سوى إعادة الضبط إلى ذلك الفرع.📖 ملخص
- إعادة الضبط هي عملية تنقل مؤشر الفرع إلى موقع محدد.
- ثلاثة أوضاع: «ناعم» (يحتفظ بالتغييرات)، و«مختلط» (يحتفظ بمساحة العمل)، و«قوي» (إعادة ضبط كاملة)
- إعادة الضبط الناعمة: التراجع عن عملية الالتزام مع الحفاظ على منطقة التجهيز ودليل العمل
- إعادة التعيين المختلطة: التراجع عن عمليات التسجيل والملفات الموضوعة في منطقة الانتظار، مع الاحتفاظ بدليل العمل (الافتراضي)
- إعادة الضبط الكامل: إلغاء جميع التغييرات تمامًا (يُستخدم بحذر)
- «reset» مقابل «revert»: تُستخدم كلمة «reset» للفروع المحلية، بينما تُستخدم كلمة «revert» للفروع التي تم إرسالها
📝 تمارين
-
تمرين أساسي: قم بإنشاء عدة عمليات تسجيل، ثم أعد ضبطها باستخدام كل من أوضاع إعادة الضبط الثلاثة، ولاحظ التغييرات التي تطرأ على منطقة التجهيز ودليل العمل، وافهم الفروق بين الأوضاع الثلاثة.
-
تمرين متقدم: قم بمحاكاة سيناريو إجراء «كوميت» غير صحيح: قم بإنشاء «كوميت» غير صحيح، واستخدم
resetللتراجع عنه، ثم قم بإجراء «كوميت» على الإصدار الصحيح لتجربة التطبيق العملي لـreset. -
التحدي: جرب قوة reflog: قم بتنفيذ عدة عمليات إعادة تعيين، واستخدم reflog لعرض سجل العمليات، واستعادة البيانات بعد فشل عملية إعادة التعيين، وفهم آليات أمان البيانات في Git.