
Git Stash والعلامات: إدارة العمل المؤقت والإصدارات
تحل أوامر Git stash والعلامات في Git مشكلتين مختلفتين تمامًا.
الـ stash مؤقت. فهو يساعدك على وضع التغييرات المحلية غير المكتملة جانبًا، والعودة إلى حالة عمل أنظف، ثم استعادة العمل لاحقًا. أما العلامة فهي ثابتة. تمنح اسمًا مستقرًا لكائن مهم في Git—غالبًا التزامًا—بحيث يستطيع الفريق تحديد إصدار أو عملية نشر أو محطة مهمة أو نقطة تاريخية محددة.
غالبًا ما تُقدَّم هذه الأوامر معًا لأن كليهما يحتفظ بمرجع إلى حالة من حالات المشروع، لكن لا ينبغي الخلط بينهما. الـ stashes أدوات عمل شخصية تبقى عادة داخل مستودع محلي واحد. أما العلامات فهي مراجع داخل المستودع غالبًا ما تُشارك مع الفريق وتُستخدم في مسارات عمل الإصدارات.
يشرح هذا الدليل الميزتين بعمق. ستتدرب على إنشاء stashes وفحصها وتطبيقها وحذفها واستعادتها؛ وستفهم سلوك الملفات tracked وuntracked وstaged وignored؛ وتحل تعارضات stash؛ وتنشئ علامات lightweight وannotated وsigned؛ وتضع علامات على التزامات تاريخية؛ وتفحص العلامات وتتحقق منها؛ وتنشرها بأمان؛ وتتجنب أخطاء إعادة التوسيم الخطرة.
ما الذي ستتعلمه؟
ما الذي يسجله Git stash ومتى يكون استخدامه مناسبًا.
الفرق بين
stash pushوapplyوpop.كيف تؤثر الملفات staged وunstaged وuntracked وignored في stash.
كيفية حفظ مسارات أو أجزاء محددة داخل stash.
كيفية الحفاظ على index باستخدام
--keep-index.كيفية حفظ التغييرات staged فقط.
كيفية فحص stashes والتعامل مع تسمياتها مفاهيميًا وإنشاء فرع منها وحذفها وتنظيفها.
كيف تحدث تعارضات stash وكيفية حلها.
ما الذي تمثله العلامات lightweight وannotated وsigned.
كيف تختلف العلامات عن الفروع.
كيفية وضع علامة على التزام أقدم.
كيفية عرض العلامات وتصفيتها وترتيبها وفحصها وحذفها واستبدالها.
كيفية دفع علامات منفردة وعلامات إصدار محددة.
لماذا يُعد تغيير علامة منشورة أمرًا خطيرًا.
كيف تدعم العلامات مسارات عمل الإصدارات وعمليات النشر.
القسم الأول: فهم Git Stash
يسجل Git stash الحالة الحالية للتغييرات المحددة في working tree وindex، ثم يعيد هذه المناطق عادة باتجاه الحالة التي يمثلها HEAD.
يبدو السيناريو الشائع كما يلي:
أنت في منتصف تطوير ميزة.
يتطلب إصلاح عاجل الانتقال إلى فرع آخر.
التغييرات الحالية ليست جاهزة بعد لالتزام ذي معنى.
لا يمكن الانتقال إلى الفرع الهدف بأمان مع حالة working tree الحالية.
تضع العمل غير المكتمل داخل stash، وتنجز المهمة العاجلة، ثم تستعيد العمل لاحقًا.
أبسط أمر هو:
git stash push
أما الصيغة التاريخية الأقصر فهي:
git stash
في مسارات العمل الحديثة والواضحة، يكون git stash push أكثر وضوحًا لأنه يقبل الرسائل وpathspecs وخيارات الاختيار.
الـ Stash ليس فرعًا أو التزامًا عاديًا
يُمثَّل stash داخليًا بواسطة كائنات Git وبنى شبيهة بالالتزامات، لكنه يُدار من خلال مرجع خاص وreflog بدل التعامل معه كفرع تطوير عادي.
تظهر stashes عادة في قائمة شبيهة بالمكدس:
stash@{0}
stash@{1}
stash@{2}
يكون stash@{0} عادة أحدث stash.
لا ينبغي أن يتحول stash إلى نظام تخزين دائم للعمل المهم. فالتطوير طويل الأمد وذو المعنى يكون عادة أكثر أمانًا على فرع ذي التزامات واضحة.
متى ينبغي استخدام Git Stash؟
يفيد stash عندما:
تحتاج إلى الانتقال مؤقتًا إلى فرع آخر.
تحتاج إلى working tree نظيف قبل pull أو rebase أو الاختبار.
تريد مقارنة العمل الحالي بحالة مشروع نظيفة.
لديك تعديلات محلية غير مرتبطة لا ينبغي أن تدخل الالتزام التالي.
أنت على وشك تنفيذ عملية خطرة وتريد نقطة حفظ محلية قصيرة العمر.
تريد نقل تغييرات غير مكتملة إلى فرع جديد.
ويكون stash أقل ملاءمة عندما:
يكون العمل بالفعل نقطة واضحة يمكن تسجيلها في التزام.
يجب مشاركة العمل مع مطور آخر.
تحتاج التغييرات إلى حفظ موثوق طويل الأمد.
لديك عدد كبير من stashes القديمة ذات رسائل غير واضحة.
تستخدم stash للتهرب من تنظيم الالتزامات والفروع.
إنشاء مستودع للتدرب
تستخدم الأمثلة مشروعًا صغيرًا باسم Task Notes.
على macOS أو Linux أو Git Bash
mkdir git-stash-tags-demo
cd git-stash-tags-demo
git init -b main
cat > app.txt <<'EOF'
Task Notes
التخزين: محلي
البحث: معطل
EOF
cat > README.md <<'EOF'
# Task Notes
مشروع صغير للتدرب على Git stash والعلامات.
EOF
git add app.txt README.md
git commit -m "إنشاء مشروع ملاحظات المهام"
على PowerShell
New-Item -ItemType Directory git-stash-tags-demo
Set-Location git-stash-tags-demo
git init -b main
@"
Task Notes
التخزين: محلي
البحث: معطل
"@ | Set-Content app.txt
@"
# Task Notes
مشروع صغير للتدرب على Git stash والعلامات.
"@ | Set-Content README.md
git add app.txt, README.md
git commit -m "إنشاء مشروع ملاحظات المهام"
تحقق من نقطة البداية:
git status
git log --oneline
إنشاء أول Stash
عدّل app.txt:
Task Notes
التخزين: محلي
البحث: كلمة مفتاحية
تحقق من المستودع:
git status
git diff
أنشئ stash برسالة مفيدة:
git stash push -m "WIP: إضافة البحث بالكلمة المفتاحية"
افحص الحالة:
git status
يجب عادة إزالة التعديل tracked من working tree وإعادته إلى حالة الالتزام الحالي.
اعرض stashes:
git stash list
مثال:
stash@{0}: On main: WIP: إضافة البحث بالكلمة المفتاحية
قد تتضمن النتيجة الدقيقة سياق الفرع والالتزام.
أضف دائمًا رسالة إلى Stash
من دون رسالة مخصصة، قد يصبح التمييز بين عدة stashes أمرًا صعبًا:
stash@{0}: WIP on main: ...
stash@{1}: WIP on main: ...
stash@{2}: WIP on main: ...
تصف الرسالة المفيدة المهمة غير المكتملة:
git stash push -m "WIP: التحقق من تواريخ المهام المستوردة"
git stash push -m "Debug: فحص استعلام التقرير البطيء"
git stash push -m "Experiment: تخطيط جديد لنتائج البحث"
البادئة اختيارية. المهم أن تساعدك الرسالة على التعرف إلى العمل لاحقًا.
فحص Stash
اعرض ملخص أحدث stash:
git stash show
اعرض patch كاملًا:
git stash show -p
افحص stash محددًا:
git stash show -p stash@{1}
استخدم ملخص الإحصاءات:
git stash show --stat stash@{0}
قبل تطبيق stash قديم، افحص محتواه. فقد لا تكشف الرسالة وحدها عن جميع الملفات الموجودة فيه.
الفرق بين Apply وPop
استعد أحدث stash مع الاحتفاظ به في القائمة:
git stash apply
استعد stash محددًا:
git stash apply stash@{1}
استعد أحدث stash واحذفه من القائمة بعد تطبيق ناجح:
git stash pop
نفّذ pop على stash محدد:
git stash pop stash@{1}
| الأمر | يستعيد التغييرات | يحذف Stash تلقائيًا |
|---|---|---|
git stash apply | نعم | لا |
git stash pop | نعم | بعد تطبيق ناجح |
استخدم apply عندما تريد خطوة مراجعة أكثر أمانًا أو تحتاج إلى تطبيق stash نفسه في أكثر من مكان. واستخدم pop عندما تكون واثقًا من أن stash يجب استعادته وحذفه.
عندما تمنع التعارضات تنفيذ pop بصورة نظيفة، يحتفظ Git عادة بالـ stash كي لا يضيع تلقائيًا.
هل يتضمن Stash الملفات Untracked؟
يحفظ git stash push افتراضيًا التعديلات tracked والتغييرات staged أساسًا. ولا تُضمَّن الملفات untracked العادية تلقائيًا.
أنشئ ملفًا untracked:
echo "ملاحظات بحث مؤقتة" > search-notes.txt
تحقق:
git status --short
احفظ التغييرات tracked وuntracked داخل stash:
git stash push -u -m "WIP: تنفيذ البحث والملاحظات"
الخيار الطويل هو:
git stash push --include-untracked
بعد ذلك، يجب عادة إزالة الملف untracked من working tree وتخزينه داخل stash.
حفظ الملفات Ignored داخل Stash
لا تُضمَّن الملفات ignored عند استخدام -u.
لتضمين الملفات ignored أيضًا:
git stash push -a -m "WIP: تضمين الملفات المحلية المولدة"
الخيار الطويل هو:
git stash push --all
استخدم --all بحذر. فقد تحتوي المجلدات ignored على:
مجلدات dependencies كبيرة.
مخرجات build.
السجلات.
ذاكرات cache محلية.
Assets مولدة.
ملفات خاصة بالبيئة.
قد يكون حفظ جميع الملفات ignored بطيئًا ويستهلك مساحة كبيرة داخل المستودع.
التغييرات Staged وUnstaged داخل Stash
يمكن أن يحتوي الملف نفسه على تغييرات staged وunstaged في الوقت ذاته.
مثال:
عدّل
README.md.نفّذ
git add README.md.عدّل
README.mdمرة أخرى.نفّذ
git status --short.
قد ترى:
MM README.md
يمكن للـ stash العادي الحفاظ على حالة index وحالة working tree معًا. لكن طريقة استعادتهما تعتمد على خيارات apply.
لمحاولة استعادة حالة staged أيضًا:
git stash apply --index
أو:
git stash pop --index
من دون --index قد يُستعاد المحتوى من دون إعادة إنشاء ترتيب staged نفسه.
قد تفشل استعادة index عندما لا تسمح حالة المستودع الحالية بإعادة بناء بنية staging الأصلية بصورة نظيفة.
الإبقاء على التغييرات Staged في مكانها
قد يكون لديك إصلاح مكتمل موجود في staging، إضافة إلى تغييرات أخرى غير مكتملة داخل working tree. في هذه الحالة قد ترغب في حفظ الجزء غير المكتمل فقط داخل stash والإبقاء على index جاهزًا للالتزام.
استخدم:
git stash push --keep-index -m "WIP: تعديلات توثيق غير مكتملة"
تبقى التغييرات staged متاحة، بينما تُحفظ التغييرات المناسبة الأخرى داخل stash.
مسار عمل عملي:
git add fix.php
git stash push --keep-index -m "WIP: تجارب غير مرتبطة"
git diff --staged
git commit -m "إصلاح تقريب الفاتورة"
git stash pop
افحص الحالة دائمًا بعد إنشاء stash. فالخيارات تؤثر في طبقات مختلفة من المستودع، والجمع بين إصدارات staged وunstaged يحتاج إلى مراجعة دقيقة.
حفظ التغييرات Staged فقط
عندما تريد حفظ محتوى index داخل stash وترك تغييرات working tree الأخرى ظاهرة:
git stash push --staged -m "WIP: تنفيذ البحث الموجود في staging"
يفيد ذلك عندما تشكل التغييرات staged مجموعة مستقلة ينبغي وضعها جانبًا مع إبقاء العمل unstaged ظاهرًا.
راجع الحالة قبل العملية وبعدها:
git status
git diff
git diff --staged
git stash push --staged -m "WIP: تنفيذ البحث الموجود في staging"
git status
إذا تداخلت التغييرات staged وunstaged بطريقة لا يستطيع Git فصلها بأمان، فقد تتوقف العملية أو تحتاج إلى إعادة تنظيم التغييرات أولًا.
حفظ ملفات محددة داخل Stash
لا تحتاج إلى حفظ working tree كاملًا.
احفظ ملفًا واحدًا:
git stash push -m "WIP: إعادة كتابة README" -- README.md
احفظ عدة مسارات:
git stash push -m "WIP: ملفات البحث" -- app.txt search-notes.txt
احفظ مجلدًا:
git stash push -m "WIP: وحدة التقارير" -- src/Report/
تفصل -- خيارات الأمر عن pathspecs.
يفيد stash المحدود بمسارات عندما تختلط عدة مهام مستقلة داخل working tree واحدة، رغم أن فصل العمل مبكرًا باستخدام الفروع والالتزامات يكون أنظف غالبًا.
الحفظ التفاعلي باستخدام --patch
احفظ أجزاء محددة بصورة تفاعلية:
git stash push -p -m "WIP: تغييرات البحث المحددة"
الخيار الطويل هو:
git stash push --patch
يعرض Git الأجزاء ويسألك إن كان يجب تضمين كل منها.
تشمل الإجابات الشائعة:
y: تضمين هذا الجزء.n: ترك هذا الجزء داخل working tree.s: تقسيم الجزء عندما يكون ذلك ممكنًا.e: تعديل patch يدويًا.q: إيقاف الاختيار.?: عرض المساعدة.
بعد ذلك نفّذ:
git status
git stash show -p stash@{0}
تأكد من أن الأجزاء المطلوبة دخلت stash وأن التعديلات المتبقية بقيت داخل working tree.
هل يمكن إنشاء Stash من Working Tree نظيف؟
إذا لم توجد تغييرات محلية مناسبة، يبلّغ Git عادة أنه لا يوجد شيء لحفظه.
لا يُعد stash بديلًا عن إنشاء نقطة مسماة لحالة مسجلة أصلًا. استخدم فرعًا أو علامة لهذا الغرض.
تطبيق Stash على فرع آخر
لا يرتبط stash بصورة دائمة بالفرع الذي أُنشئ عليه.
يمكنك الانتقال إلى فرع آخر وتطبيقه:
git switch feature/search
git stash apply stash@{0}
يفيد ذلك عندما بدأت التغييرات على الفرع الخطأ.
لكن تطبيق stash على حالة مختلفة من الشيفرة يزيد احتمال التعارضات. افحص اختلاف الفرع وpatch الخاص بالـ stash أولًا.
إنشاء فرع من Stash
عندما يتغير الفرع الحالي كثيرًا منذ إنشاء stash، قد يؤدي تطبيقه مباشرة إلى تعارضات.
استخدم:
git stash branch feature/search-recovery stash@{0}
ينشئ هذا الأمر فرعًا جديدًا من الالتزام الذي أُنشئ عنده stash أصلًا، وينتقل إليه، ويطبق stash هناك، ثم يحذفه إذا نجح التطبيق.
تُعد هذه من أكثر الطرق أمانًا لتحويل stash قديم إلى عمل عادي مبني على فرع.
تعارضات Stash
قد يحدث تعارض عند تطبيق stash إذا تغيرت الملفات الحالية بطرق غير متوافقة مع التغييرات المحفوظة.
مثال:
احفظ تغييرًا في سطر
التخزينداخل stash.سجل تغييرًا مختلفًا في السطر نفسه.
طبّق stash القديم.
قد يضيف Git علامات تعارض:
<<<<<<< Updated upstream
التخزين: محلي مشفر
=======
التخزين: سحابي
>>>>>>> Stashed changes
حل التعارض كما تحل merge conflict:
نفّذ
git status.افتح كل ملف متعارض.
افهم نية التغييرات الحالية والتغييرات المحفوظة.
حرر النتيجة المجمعة الصحيحة.
أزل علامات التعارض.
ضع الملفات المحلولة في staging باستخدام
git add.شغّل الاختبارات.
أنشئ التزامًا عندما يصل العمل المستعاد إلى حالة ذات معنى.
بخلاف عملية merge نشطة، لا يوفر تطبيق stash مسار git merge --abort نفسه. إذا أصبحت عملية الاستعادة غير واضحة، فاحمِ العمل الحالي قبل تنفيذ reset أو restore على الملفات.
حذف Stash واحد
احذف stash محددًا:
git stash drop stash@{1}
احذف أحدث stash:
git stash drop
افحص stash قبل حذفه:
git stash show -p stash@{1}
بعد الحذف قد تتغير أرقام stashes لأن القائمة مبنية على reflog. نفّذ git stash list مرة أخرى قبل الإشارة إلى موضع آخر.
حذف جميع Stashes
git stash clear
يزيل هذا الأمر كل إدخالات stash من مرجعه.
لا يوجد تأكيد تفاعلي افتراضيًا. قبل التنظيف:
git stash list
git stash show -p stash@{0}
git stash show -p stash@{1}
ينبغي تحويل العمل المهم إلى فروع أو التزامات بدل تركه في قائمة stash.
استعادة Stash محذوف
قد يبقى stash حُذف مؤخرًا على شكل كائنات Git غير قابلة للوصول لمدة محدودة، لكن الاستعادة غير مضمونة.
تشمل أدوات الفحص المحتملة:
git fsck --unreachable
git fsck --no-reflogs
يمكنك العثور على كائنات شبيهة بالالتزامات dangling أو unreachable وفحص المرشحين باستخدام:
git show <object-id>
إذا وجدت الكائن الصحيح، فاحفظه فورًا:
git branch stash-recovery <object-id>
تعتمد الاستعادة على garbage collection وصيانة المستودع وإمكانية الوصول إلى الكائنات. تعامل مع stashes المحذوفة أو المنظفة على أنها قد تكون فُقدت.
أوامر متقدمة لإنشاء Stash
ينبغي لمعظم المطورين استخدام git stash push. لكن Git يوفر عمليات stash منخفضة المستوى أيضًا.
الإنشاء من دون التخزين في قائمة Stash
git stash create "كائن stash مؤقت"
ينشئ هذا الأمر كائنًا شبيهًا بالـ stash ويطبع معرّفه من دون تحديث مرجع stash العادي.
تخزين كائن Stash موجود
git stash store -m "عمل مؤقت مستعاد" <object-id>
تفيد هذه الأوامر في السكربتات ومسارات الاستعادة، لكنها أسهل في سوء الاستخدام من push.
أفضل الممارسات عند استخدام Stash
استخدم رسائل واضحة.
افحص working tree قبل إنشاء stash.
استخدم
-uفقط عندما تكون الملفات untracked مطلوبة.تجنب
-aما لم تكن الملفات ignored بحاجة فعلية إلى الحفظ.افحص stash قبل تطبيقه أو حذفه.
فضّل
applyعلىpopعندما تكون الحالة خطرة.استخدم
--indexفقط عندما تكون استعادة ترتيب staged مهمة.حوّل stashes طويلة العمر إلى فروع.
لا تستخدم stash بديلًا عن الالتزامات ذات المعنى.
نظّف stashes القديمة بعد التأكد من عدم الحاجة إليها.
القسم الثاني: فهم علامات Git
تمنح علامة Git اسمًا سهل القراءة لكائن محدد، وغالبًا ما يكون التزامًا.
تُستخدم العلامات عادة في:
إصدارات البرمجيات.
عمليات النشر إلى الإنتاج.
المحطات العامة المهمة.
خطوط الأساس الخاصة بالتوافق.
نقاط تاريخية مهمة.
مراجع الإصدارات الموقعة.
على خلاف الفرع، لا تتحرك العلامة تلقائيًا عند إنشاء التزامات جديدة.
الفرق بين Tag وBranch
افترض أن فرعًا وعلامة يشيران معًا إلى الالتزام C:
A---B---C
^ main
^ v1.0.0
أنشئ التزامًا جديدًا على main:
A---B---C---D
^ ^
v1.0.0 main
يتحرك الفرع إلى D، بينما تبقى العلامة عند C.
| الفرع | العلامة |
|---|---|
| يتحرك عند إنشاء التزامات جديدة | تبقى ثابتة عادة |
| يمثل مسار تطوير نشطًا | تحدد كائنًا أو محطة مهمة بعينها |
| يُستخدم عادة للعمل المستمر | تُفحص عادة أو تُستخدم مرجعًا لإصدار |
| يُخزن ضمن مراجع الفروع | تُخزن ضمن مراجع العلامات |
عرض العلامات
اعرض جميع العلامات:
git tag
الصيغة المكافئة:
git tag --list
صفِّ النتائج باستخدام pattern شبيه بصيغة shell:
git tag --list "v1.*"
اعرض العلامات مع معلومات annotation عندما تكون متاحة:
git tag -n
اعرض عددًا أكبر من أسطر الرسالة:
git tag -n3
العلامات Lightweight
العلامة lightweight اسم يشير مباشرة إلى كائن، وغالبًا إلى التزام.
أنشئ واحدة عند الالتزام الحالي:
git tag v0.1.0
افحصها:
git show v0.1.0
لا تنشئ العلامة lightweight كائن tag منفصلًا يحتوي على tagger وتاريخ ورسالة.
قد تفيد العلامات lightweight في:
التسميات المحلية المؤقتة.
الإشارات المرجعية الشخصية.
علامات الاختبار قصيرة العمر.
نقاط الحفظ الداخلية البسيطة.
في الإصدارات الرسمية، تكون العلامات annotated أكثر فائدة عادة.
العلامات Annotated
أنشئ علامة annotated:
git tag -a v1.0.0 -m "إصدار النسخة 1.0.0"
تنشئ العلامة annotated كائن tag يحتوي على بيانات وصفية مثل:
مرجع الكائن المُعلَّم.
اسم العلامة.
اسم tagger وبريده الإلكتروني.
تاريخ الإنشاء.
رسالة annotation.
توقيع تشفيري اختياري عند استخدام signing.
افحصها:
git show v1.0.0
تتضمن المخرجات عادة رسالة العلامة ومعلومات عن الالتزام المشار إليه.
الفرق بين Lightweight وAnnotated Tags
| الميزة | Lightweight Tag | Annotated Tag |
|---|---|---|
| كائن tag منفصل | لا | نعم |
| هوية Tagger | لا توجد بيانات مخصصة | نعم |
| رسالة Tag | لا | نعم |
| تاريخ الإنشاء داخل كائن Tag | لا | نعم |
| إمكانية حمل توقيع | لا | نعم |
| الاستخدام المعتاد | تسميات مؤقتة أو شخصية | الإصدارات والمحطات المهمة |
تفضل بعض أوامر Git العلامات annotated افتراضيًا لأنها تمثل كائنات tags واضحة مخصصة للإصدارات.
وضع علامة على التزام تاريخي
لست مضطرًا إلى وضع علامة على الالتزام الحالي فقط.
اعثر على الهدف:
git log --oneline
أنشئ علامة annotated على التزام أقدم:
git tag -a v0.9.0 7a93c2e -m "خط أساس لإصدار مرشح"
أنشئ علامة lightweight تاريخية:
git tag test-baseline 7a93c2e
تحقق من الهدف قبل وضع العلامة:
git show --no-patch --format=fuller 7a93c2e
قد يؤدي وضع العلامة على الالتزام الخطأ إلى ارتباك في النشر والإصدارات، خصوصًا بعد نشرها.
فحص مراجع العلامات بدقة
اعرض الكائن الذي يشير إليه اسم العلامة:
git rev-parse v1.0.0
في العلامة annotated، يحدد هذا عادة كائن tag نفسه.
قم بفك العلامة للوصول إلى الالتزام الذي تشير إليه في النهاية:
git rev-parse v1.0.0^{}
اشترط أن يكون الكائن المشار إليه التزامًا:
git rev-parse v1.0.0^{commit}
اعرض نوع المرجع:
git cat-file -t v1.0.0
النتائج المعتادة:
tagلكائن علامة annotated.commitلعلامة lightweight تشير مباشرة إلى التزام.
عرض العلامات التي تشير إلى التزام
اعرض العلامات التي تشير مباشرة إلى HEAD:
git tag --points-at HEAD
تحقق من revision آخر:
git tag --points-at 7a93c2e
يساعد ذلك على التحقق مما إذا كانت علامة إصدار موجودة بالفعل عند الالتزام المحدد.
عرض العلامات التي تحتوي على التزام
اعرض العلامات التي تحتوي التزاماتها المرجعية على التزام معين ضمن سجلها:
git tag --contains <commit>
اعرض العلامات التي لا تحتوي عليه:
git tag --no-contains <commit>
يساعد ذلك على الإجابة عن أسئلة مثل:
ما الإصدارات التي تتضمن إصلاحًا أمنيًا؟
هل أُدخل الخطأ قبل الإصدار أم بعده؟
ما خطوط الإصدارات التي تحتوي على التزام معين؟
يعتمد الاحتواء على تسلسل أصل الالتزامات، لا على وجود شيفرة متطابقة أُدخلت بصورة مستقلة في مكان آخر.
ترتيب العلامات
قد ينتج الترتيب المعجمي نتائج مفاجئة:
v1.10.0
v1.2.0
v1.9.0
استخدم ترتيبًا مدركًا للإصدارات:
git tag --sort=version:refname
اعكس الترتيب:
git tag --sort=-version:refname
رتّب العلامات annotated بحسب تاريخ tagger:
git tag --sort=-taggerdate
لا تملك العلامات lightweight تاريخ tagger مخصصًا، لذلك قد تحتاج العروض المعتمدة على التاريخ إلى حقول مختلفة بحسب نوع العلامة.
نسّق قائمة علامات مخصصة:
git for-each-ref \
--sort=-version:refname \
--format="%(refname:short) %(objecttype) %(subject)" \
refs/tags
البحث في أسماء العلامات
اعرض علامات الإصدار الأول المستقرة:
git tag -l "v1.*"
اعرض release candidates:
git tag -l "*-rc.*"
ضع patterns التي تحتوي wildcards بين علامتي اقتباس حتى لا يوسعها shell وفق أسماء الملفات قبل وصولها إلى Git.
حذف علامة محلية
git tag -d v0.1.0
يزيل هذا مرجع العلامة المحلي.
ولا يحذف تلقائيًا علامة نُشرت مسبقًا إلى مستودع remote.
قبل الحذف:
git show v0.1.0
git rev-parse v0.1.0^{}
تأكد من أنك تحذف المرجع المقصود.
استبدال علامة محلية أو نقلها
يُفترض أن تبقى العلامات ثابتة، لكن قد تحتاج أثناء التحضير المحلي الخاص إلى تصحيح علامة.
احذفها وأعد إنشاءها:
git tag -d v1.0.0
git tag -a v1.0.0 <correct-commit> -m "إصدار النسخة 1.0.0"
أو استبدلها محليًا بالقوة:
git tag -f -a v1.0.0 <correct-commit> -m "إصدار النسخة 1.0.0"
يغير الاستبدال الإجباري الكائن الذي يحدده الاسم. لا تفعل ذلك بلا مبالاة بعد مشاركة العلامة.
لماذا يجب التعامل مع العلامات المنشورة بوصفها ثابتة؟
افترض أن فريقًا نشر v1.0.0 وهي تشير إلى الالتزام A. قد يكون المستخدمون وأنظمة CI وأدوات النشر وأدوات بناء الحزم قد حمّلوا العلامة أو خزنوها مؤقتًا.
إذا نُقلت العلامة لاحقًا إلى الالتزام B، فقد يصبح للاسم نفسه معانٍ مختلفة لدى أنظمة وأشخاص مختلفين:
المطور 1: v1.0.0 -> A
المطور 2: v1.0.0 -> B
ذاكرة Build المؤقتة: v1.0.0 -> A
نظام النشر: v1.0.0 -> B
يضر ذلك بقابلية إعادة الإنتاج والثقة.
عندما يكون الإصدار المنشور خاطئًا، يكون الأسلوب الأكثر أمانًا عادة إنشاء إصدار جديد:
v1.0.1
v1.0.0-hotfix.1
v1.0.1-rc.1
استخدم قاعدة versioning المعتمدة في المشروع.
العلامات Signed
يمكن توقيع علامة annotated تشفيريًا عندما تكون مفاتيح التوقيع وإعدادات Git جاهزة.
أنشئ علامة موقعة:
git tag -s v1.0.0 -m "إصدار النسخة 1.0.0"
بحسب صيغة التوقيع المضبوطة وإعداد المفتاح، ينشئ Git توقيعًا داخل كائن tag.
تحقق من توقيع العلامة:
git tag -v v1.0.0
أو:
git verify-tag v1.0.0
يتطلب التحقق الوصول إلى المفتاح العام المناسب أو إعدادات الثقة.
يثبت التوقيع التشفيري الصحيح أن كائن tag وُقع بواسطة حامل المفتاح الخاص المقابل، لكنه لا يثبت تلقائيًا أن البرنامج آمن أو خالٍ من الأخطاء أو معتمد من مؤسستك.
الفرق بين Signed Tag وSigned Commit
يوقّع signed tag كائن العلامة، بينما يوقّع signed commit كائن التزام منفردًا.
يمكن استخدامهما بصورة مستقلة:
قد تشير علامة إصدار موقعة إلى التزامات غير موقعة.
قد يملك التزام موقع علامة غير موقعة.
قد يشترط المشروع استخدام الاثنين.
قد يعتمد المشروع على attestations خاصة بمنصة الاستضافة أو نظام تحقق آخر.
اتبع سياسة الثقة الخاصة بالإصدارات في المشروع بدل افتراض أن توقيعًا واحدًا يغطي جميع الملفات والعمليات.
إنشاء علامة إصدار عملية
قبل وضع علامة على إصدار:
تأكد من الفرع الصحيح.
تأكد من أن working tree نظيف.
نفّذ fetch أو زامن حالة remote وفق سياسة الفريق.
شغّل الاختبارات وفحوص build.
راجع الالتزام الذي ستوضع عليه العلامة.
تحقق من رقم الإصدار.
أنشئ علامة annotated أو signed.
افحص العلامة قبل نشرها.
مثال:
git switch main
git status
git log -1 --format=fuller
git diff HEAD^ HEAD
git tag -a v1.0.0 -m "إصدار Task Notes 1.0.0"
git show v1.0.0
ينبغي أن تحدد العلامة التزامًا دقيقًا جرى اختباره، لا working directory يحتوي على تغييرات غير مسجلة.
دفع علامة واحدة إلى Remote
لا تنشر عمليات push العادية للفروع جميع العلامات المحلية بالضرورة.
ادفع علامة واحدة صراحة:
git push origin v1.0.0
يُعد هذا أكثر سلوك شائع أمانًا للإصدارات لأنه ينشر العلامة المقصودة بالضبط.
دفع جميع العلامات المحلية
git push origin --tags
يدفع هذا الأمر كل العلامات المحلية غير الموجودة في remote.
استخدمه بحذر. فقد تكون لدى المطور علامات محلية مؤقتة أو شخصية أو تجريبية أو قديمة لا ينبغي نشرها.
قبل تشغيله:
git tag --list
git for-each-ref --format="%(refname:short) %(objecttype) %(subject)" refs/tags
دفع العلامات Annotated القابلة للوصول باستخدام --follow-tags
عند دفع الفروع، استخدم:
git push --follow-tags
قد يدفع هذا الخيار العلامات annotated غير الموجودة في remote والتي يمكن الوصول إليها من الالتزامات التي يجري دفعها.
لا يتصرف بالطريقة نفسها تمامًا مثل --tags، ولا ينشر كل العلامات lightweight المحلية.
وهذا يجعله مفيدًا لمسارات الإصدارات التي تستخدم العلامات annotated وتريد تجنب نشر علامات محلية غير مرتبطة.
حذف علامة من Remote
احذفها من خلال عملية مرجع remote صريحة:
git push origin --delete v1.0.0
صيغة صريحة أخرى:
git push origin :refs/tags/v1.0.0
لا يؤدي حذف علامة من remote إلى حذف النسخ التي جلبها مستخدمون آخرون تلقائيًا.
إذا كان لا بد من استبدال علامة منشورة، فتواصل بوضوح، واستخدم refspecs صريحة، وافهم أن العملاء قد يحتفظون بالعلامة القديمة إلى أن يحدثوها أو يحذفوها عمدًا.
جلب العلامات
غالبًا ما تحصل عمليات fetch العادية على العلامات التي تشير إلى السجل الذي جرى جلبه وفق سلوك Git الخاص بتتبع العلامات.
اجلب العلامات صراحة:
git fetch --tags
اجلب علامة واحدة باستخدام refspec صريح:
git fetch origin tag v1.0.0
افحص بعد الجلب:
git tag --list
git show v1.0.0
لا تفترض أن العلامة موثوقة لمجرد وجودها على remote. تحقق من هدفها وبياناتها الوصفية وتوقيعها وفق نموذج الأمان الخاص بالمشروع.
Checkout لإحدى العلامات
افحص إصدارًا ذا علامة في وضع detached-HEAD:
git switch --detach v1.0.0
يفيد ذلك في:
بناء إصدار قديم.
تشغيل اختبارات تاريخية.
فحص إصدار موجود في الإنتاج.
مقارنة السلوك بين الإصدارات.
لا تنشئ عملًا مستمرًا في وضع detached ما لم تكن تنوي حفظه.
أنشئ فرع صيانة من العلامة:
git switch -c support/1.0 v1.0.0
الآن تحرك الالتزامات الجديدة فرع الصيانة بينما تبقى العلامة ثابتة.
مقارنة الإصدارات
اعرض الالتزامات التي أُضيفت بين إصدارين:
git log --oneline v1.0.0..v1.1.0
قارن المحتوى:
git diff v1.0.0 v1.1.0
اعرض ملخص الإحصاءات:
git diff --stat v1.0.0 v1.1.0
اعرض المسارات المتغيرة:
git diff --name-status v1.0.0 v1.1.0
تفيد هذه الأوامر في ملاحظات الإصدار والتحقيق في regressions ومراجعة عمليات النشر.
وصف التزام نسبة إلى العلامات
ينشئ git describe اسمًا سهل القراءة اعتمادًا على علامة قريبة يمكن الوصول إليها:
git describe
مثال:
v1.0.0-5-g7a93c2e
يعني هذا عادة:
أقرب علامة مأخوذة في الاعتبار هي
v1.0.0.الالتزام يأتي بعد تلك العلامة بخمسة التزامات.
يبدأ المعرّف المختصر للكائن بـ
7a93c2e.
ضمّن العلامات lightweight:
git describe --tags
اعرض معرّف كائن احتياطيًا حتى عند عدم العثور على علامة مناسبة:
git describe --tags --always
قد يفيد ذلك في معرّفات builds الخاصة بالتطوير.
قواعد تسمية العلامات
تشمل أسماء الإصدارات الشائعة:
v1.0.0
v1.2.3
v2.0.0-rc.1
release-2026.07
production-2026-07-10
ينبغي أن تكون القاعدة المفيدة:
متسقة.
موثقة.
قابلة للترتيب أو التحليل بواسطة أدوات الإصدارات.
متوافقة مع أنظمة الحزم والنشر.
ثابتة بعد النشر.
لا تخلط بين عدة مخططات غير مرتبطة من دون سبب واضح.
نظرة عامة على Semantic Versioning
تستخدم مشاريع كثيرة بنية إصدار مثل:
MAJOR.MINOR.PATCH
على سبيل المثال:
2.4.1
التفسير المعتاد:
MAJOR: تغييرات عامة غير متوافقة مع الإصدارات السابقة.
MINOR: وظائف جديدة متوافقة مع الإصدارات السابقة.
PATCH: إصلاحات متوافقة مع الإصدارات السابقة.
قد تمثل معرّفات prerelease إصدارات مرشحة:
2.5.0-alpha.1
2.5.0-beta.1
2.5.0-rc.1
لا يفرض Git نظام Semantic Versioning. اسم العلامة مجرد اسم مرجع، ويجب أن يحدد المشروع وسياسة إصداراته معنى أرقام النسخ.
يمكن لكائنات Tag الإشارة إلى أكثر من Commit
يمكن لمرجع tag في Git تحديد كائن من نوع آخر، رغم أن علامات الإصدارات تشير عادة إلى التزامات.
يمكن لكائنات العلامات annotated الإشارة إلى commits أو trees أو blobs أو كائنات tags أخرى.
ينبغي لمعظم مسارات عمل المطورين وضع العلامات على الالتزامات، لأن الالتزام يحدد لقطة كاملة من المشروع مع سياق السجل.
علامات الإصدارات وإصدارات منصات الاستضافة
ترتبط علامة Git بإصدار منصة الاستضافة، لكنهما ليسا الشيء نفسه.
علامة Git مرجع داخل المستودع. أما إصدار المنصة فقد يضيف:
ملاحظات الإصدار.
أرشيفات قابلة للتنزيل.
ملفات binary مبنية.
Assets.
مسارات موافقة.
تكاملًا مع عمليات النشر.
معلومات provenance أو attestation.
تستخدم واجهة الإصدار عادة علامة Git بوصفها نسخة المصدر، لكن البيانات الوصفية المحيطة بها تنتمي إلى منصة الاستضافة.
مسار عملي: إيقاف ميزة مؤقتًا لإصلاح عاجل
1. فحص العمل غير المكتمل
git status
git diff
git diff --staged
2. حفظه مع الملفات Untracked
git stash push -u -m "WIP: تصفية البحث في المهام"
3. التحقق من الحالة النظيفة
git status
git stash list
4. الانتقال إلى فرع الإصلاح
git switch main
git switch -c hotfix/task-import
5. تنفيذ الإصلاح وتسجيله
git add -p
git commit -m "رفض تواريخ المهام المستوردة غير الصالحة"
6. العودة إلى الميزة
git switch feature/search
7. فحص Stash وتطبيقه
git stash show -p stash@{0}
git stash apply stash@{0}
8. التحقق قبل الحذف
git status
# شغّل الاختبارات وافحص الملفات
git stash drop stash@{0}
يوفر استخدام apply متبوعًا بحذف مقصود خطوة للتحقق.
مسار عملي: تحويل عمل قديم في Stash إلى فرع
افحص stash:
git stash list
git stash show -p stash@{2}
أنشئ فرعًا من base الأصلية:
git stash branch feature/recovered-search stash@{2}
ثم:
git status
git diff
git diff --staged
نظم التغييرات المستعادة في التزامات ذات معنى.
مسار عملي: إنشاء علامة إصدار ونشرها
1. التحقق من التزام الإصدار
git switch main
git status
git log -1 --format=fuller
git show --stat HEAD
2. تشغيل فحوص الإصدار
# أمثلة فقط؛ استخدم أوامر المشروع الحقيقية
php vendor/bin/phpunit
npm run build
3. إنشاء علامة Annotated
git tag -a v1.0.0 -m "إصدار Task Notes 1.0.0"
4. فحص العلامة
git show v1.0.0
git rev-parse v1.0.0^{commit}
5. نشر العلامة المقصودة فقط
git push origin v1.0.0
6. التحقق من أتمتة الإصدار البعيد
تأكد من نجاح CI وإنشاء الحزم والنشر ومسارات إنشاء ملاحظات الإصدار.
أخطاء شائعة عند استخدام Stash
افتراض تضمين الملفات Untracked تلقائيًا
استخدم -u عندما يجب أن تكون الملفات untracked جزءًا من stash.
استخدام --all من دون فحص المحتوى Ignored
قد تجعل مجلدات dependencies وbuild التي يجري تجاهلها حجم stash أكبر من المتوقع.
استخدام Pop قبل فحص Stash قديم
استخدم stash show وفكر في استخدام apply أولًا.
ترك عمل مهم داخل Stash لأشهر
حوّل العمل المهم إلى فرع يحتوي على التزامات.
حذف رقم Stash الخطأ
قد تتغير مواضع stashes بعد الحذف. نفّذ git stash list مباشرة قبل الحذف.
توقع أن يعيد --index كل شيء بصورة مثالية دائمًا
قد تمنع حالة المستودع الحالية تطبيق ترتيب index القديم بصورة نظيفة.
افتراض مشاركة Stash مع Remote
تبقى stashes محلية عادة، ولا تُنشر من خلال عمليات push العادية للفروع.
استخدام Stash لإخفاء Working Tree غير منظم
إن تكرار إنشاء stashes من دون رسائل أو تنظيف ينشئ backlog ثانيًا يصعب فهمه.
أخطاء شائعة عند استخدام العلامات
الخلط بين Tag وBranch
تبقى العلامة ثابتة عادة، بينما يتحرك الفرع مع التطوير.
وضع العلامة على الالتزام الخطأ
افحص الالتزام ونتيجة الاختبارات قبل إنشاء علامة الإصدار.
استخدام Lightweight Tag لإصدار رسمي من دون قصد
تحفظ العلامات annotated بيانات ورسائل خاصة بالإصدار.
دفع جميع العلامات بلا مراجعة
قد ينشر git push --tags علامات محلية شخصية أو تجريبية.
نقل علامة إصدار منشورة
قد يحتفظ مستخدمون وأنظمة build مختلفة بأهداف مختلفة للاسم نفسه.
افتراض أن Signed Tag يثبت أمان البرنامج
يتحقق التوقيع من كائن tag وعلاقته بالمفتاح، لا من صحة البرنامج أو أمانه.
حذف علامة Remote وافتراض اختفائها من كل مكان
قد تحتفظ clone أخرى بالعلامة المحلية القديمة إلى أن تحذفها أو تستبدلها عمدًا.
إنشاء إصدار من Working Tree غير نظيف
تحدد العلامة كائنًا مسجلًا. ولا تدخل الملفات المحلية غير المسجلة ضمن مرجع الإصدار.
مرجع أوامر Stash
| الأمر | الغرض |
|---|---|
git stash push -m "message" | حفظ تغييرات working tree وindex المتتبعة مع رسالة |
git stash push -u | تضمين الملفات untracked |
git stash push -a | تضمين الملفات untracked وignored |
git stash push --keep-index | الإبقاء على التغييرات staged داخل index |
git stash push --staged | حفظ التغييرات staged |
git stash push -p | اختيار الأجزاء بصورة تفاعلية |
git stash push -- path | حفظ مسارات محددة |
git stash list | عرض إدخالات stash |
git stash show -p | فحص patch الخاص بأحدث stash |
git stash apply | استعادة التغييرات مع الاحتفاظ بالـ stash |
git stash apply --index | محاولة استعادة التغييرات وحالة staged |
git stash pop | استعادة التغييرات وحذف stash بعد النجاح |
git stash branch name stash@{n} | إنشاء فرع من base الأصلية للـ stash وتطبيقه |
git stash drop stash@{n} | إزالة إدخال stash واحد |
git stash clear | إزالة جميع إدخالات stash |
مرجع أوامر العلامات
| الأمر | الغرض |
|---|---|
git tag | عرض العلامات المحلية |
git tag v1.0.0 | إنشاء علامة lightweight |
git tag -a v1.0.0 -m "message" | إنشاء علامة annotated |
git tag -s v1.0.0 -m "message" | إنشاء علامة annotated موقعة |
git tag -a v1.0.0 commit | وضع علامة على التزام تاريخي محدد |
git show v1.0.0 | فحص علامة والكائن المشار إليه |
git tag --points-at HEAD | عرض العلامات التي تشير إلى revision |
git tag --contains commit | عرض العلامات التي تحتوي سجلاتها على التزام |
git tag --sort=version:refname | ترتيب الأسماء بترتيب مدرك للإصدارات |
git tag -d v1.0.0 | حذف علامة محلية |
git tag -v v1.0.0 | التحقق من علامة موقعة |
git push origin v1.0.0 | نشر علامة واحدة |
git push origin --tags | نشر جميع العلامات المحلية |
git push --follow-tags | دفع العلامات annotated المناسبة والقابلة للوصول مع تحديثات الفروع |
git push origin --delete v1.0.0 | حذف علامة من remote |
git switch --detach v1.0.0 | فحص إصدار ذي علامة |
git switch -c support/1.0 v1.0.0 | إنشاء فرع من علامة |
قائمة التحقق الخاصة بـ Stash
قبل إنشاء stash:
نفّذ
git status.قرر ما إذا كانت الملفات untracked أوignored مطلوبة.
راجع التغييرات staged وunstaged.
استخدم رسالة واضحة.
فكر فيما إذا كان إنشاء فرع والتزام أكثر أمانًا.
قبل تطبيق stash أو حذفه:
نفّذ
git stash list.افحص patch المحدد.
تحقق من الفرع الحالي وworking tree.
فضّل
applyعندما تحتاج إلى التحقق.شغّل الاختبارات بعد الاستعادة.
احذف stash فقط بعد التأكد من حفظ العمل في مكان آخر.
قائمة التحقق الخاصة بعلامة الإصدار
جرى فحص التزام الإصدار المقصود واختباره.
Working tree نظيف.
يتبع اسم الإصدار قواعد المشروع.
نوع العلامة مناسب لسياسة الإصدار.
توضح annotation محتوى الإصدار.
تشير العلامة إلى الالتزام الصحيح.
اكتملت خطوات التوقيع والتحقق المطلوبة.
تُنشر العلامة المقصودة فقط.
تُبنى ملفات الإصدار من الالتزام ذي العلامة.
لن تُنقل العلامة المنشورة بلا مبالاة.
الأسئلة الشائعة
هل يحفظ Git Stash الملفات Untracked؟
ليس افتراضيًا. استخدم git stash push -u لتضمين الملفات untracked.
هل يتضمن -u الملفات Ignored؟
لا. استخدم -a أو --all عندما يجب تضمين الملفات ignored أيضًا.
ما الفرق بين Apply وPop؟
كلاهما يستعيد التغييرات المحفوظة. يحتفظ apply بإدخال stash، بينما يحذفه pop بعد تطبيق ناجح.
هل يمكن تطبيق Stash على فرع مختلف؟
نعم، لكن تزداد احتمالية التعارضات عندما يختلف الفرع الهدف كثيرًا عن base الأصلية للـ stash.
هل يمكن مشاركة Stash؟
إدخالات stash العادية محلية. للتعاون، أنشئ فرعًا وسجل العمل في التزامات، أو استخدم مسار نقل متقدمًا ومقصودًا.
هل Stash آمن للعمل طويل الأمد؟
صُمم أساسًا للعمل المحلي المؤقت. ينبغي حفظ التغييرات المهمة طويلة الأمد باستخدام الفروع والالتزامات والنسخ البعيدة.
ما الفرق بين Lightweight وAnnotated Tag؟
العلامة lightweight مرجع مباشر، بينما تنشئ العلامة annotated كائن tag يحتوي على بيانات tagger وتاريخ ورسالة وتوقيع اختياري.
هل ينبغي استخدام Annotated Tags للإصدارات؟
تكون العلامات annotated أوsigned أكثر ملاءمة عمومًا للإصدارات الرسمية لأنها تخزن بيانات إصدار صريحة.
هل ينشر git push العلامات تلقائيًا؟
لا تُدفع كل علامة محلية بالضرورة مع push عادي للفرع. انشر العلامة المقصودة صراحة أو استخدم خيار دفع علامات مختارًا بعناية.
هل يمكن تغيير علامة؟
يمكن استبدال علامة محلية، لكن تغيير علامة منشورة قد ينشئ هويات إصدار غير متسقة بين clone والأنظمة.
هل يمكن أن تشير العلامة إلى فرع؟
تُحل العلامة إلى كائن، لا إلى الحركة المستقبلية للفرع. وعند إنشاء علامة باستخدام اسم فرع، تُوضع العلامة على الكائن الذي يشير إليه الفرع في تلك اللحظة.
هل يمكن إنشاء التزامات أثناء Checkout عند علامة؟
يمكن إنشاء التزامات في وضع detached-HEAD، لكن لا يتحرك أي فرع تلقائيًا. أنشئ فرعًا أولًا عندما يجب حفظ العمل بصورة واضحة.
هل تعني Signed Tag أن ملف الإصدار Binary موقّع؟
لا. فهي توقّع كائن Git tag. وقد تحتاج ملفات binary والحاويات والحزم وattestations الخاصة بالإصدار إلى توقيع وتحقق منفصلين.
الخلاصة
يعمل Git stash والعلامات عند طرفين مختلفين من مسار التطوير.
يدير stash العمل المحلي غير المكتمل. فهو يتيح تنظيف working tree مؤقتًا، وحفظ تغييرات tracked أوuntracked محددة، ونقل العمل إلى فرع آخر، والعودة إليه لاحقًا. وتأتي هذه القوة مع مسؤولية: افحص ما يجري حفظه، واستخدم رسائل واضحة، واستعد العمل بحذر، وحوّل العمل المهم طويل العمر إلى التزامات عادية.
تحدد العلامات نقاطًا تاريخية مستقرة. توفر العلامات lightweight تسميات بسيطة، بينما تحمل العلامات annotated وsigned بيانات إصدار أقوى. وتشير العلامة المُدارة جيدًا إلى التزام جرى اختباره، وتتبع نظام إصدار متسقًا، وتبقى ثابتة بعد نشرها.
الفرق الأهم هو الاستمرارية والقصد. الـ stash حاوية عمل مؤقتة وشخصية. أما علامة الإصدار فهي وعد مشترك بأن اسمًا معينًا يحدد حالة معينة من المشروع.
ستتناول المقالة التالية مسارات عمل Git، بما يشمل feature branches وGitHub Flow وGit Flow وtrunk-based development وفروع الإصدارات واستراتيجيات hotfix وكيفية اختيار مسار يناسب حجم الفريق ونموذج التسليم.
المراجع الرسمية ومواد إضافية للقراءة

