تدفع عملك بثقة فيصدّك Git:
! [rejected] main -> main (non-fast-forward)
error: failed to push some refs to 'github.com:user/repo.git'
hint: Updates were rejected because the remote contains work that you
hint: do not have locally.
الرسالة مخيفة الشكل، لكن معناها جملة واحدة: الفرع على الريموت تقدّم خطوة ليست عندك — والرفض حمايةٌ لتلك الخطوة من الضياع، لا عقوبة لك.
ماذا حدث بالضبط؟
تاريخ الفرع سلسلة commits. عندما تدفع، يشترط Git أن يكون تاريخك امتدادًا مباشرًا لتاريخ الريموت (fast-forward). اللحظة التي يحتوي فيها الريموت commit ليس في سلسلتك — زميل دفع قبلك، أو تعديل من واجهة GitHub — يصبح دفعك «تفرعًا موازيًا» يرفضه Git حتى تدمج.
| السيناريو | العلامة | الحل |
|---|---|---|
| زميل دفع قبلك | عمل جماعي على نفس الفرع | git pull ثم push |
| أنشأت الريبو بـ README من GitHub | أول push بالمشروع | git pull --rebase origin main |
| عدّلت ملفًا من موقع GitHub | تذكر تعديلًا سريعًا بالمتصفح | git pull ثم push |
| عملت rebase/amend لفرع مدفوع | غيّرت تاريخًا منشورًا | --force-with-lease (فرعك فقط!) |
الحل الآمن — يصلح في 95% من الحالات
git pull # ينزّل عمل الريموت ويدمجه مع عملك
# إن ظهرت تعارضات: حلّها ثم git add و git commit
git push # ✅ الآن تاريخك امتداد للريموت
تفضّل تاريخًا مستقيمًا بلا commit دمج إضافي؟
git pull --rebase # يعيد وضع عملك «فوق» عمل الريموت
git push
💡 التعارضات إن ظهرت أثناء الدمج ليست كارثة — دليلنا الكامل: حل Merge Conflict خطوة بخطوة.
حالة «أول دفع» الشهيرة
أنشأت المستودع على GitHub مع README، وبدأت محليًا بـ git init؟
التاريخان منفصلان تمامًا ولا يعرفان بعضهما، فيرفض Git ربطهما:
git pull origin main --allow-unrelated-histories
git push -u origin main
(والوقاية بسيطة: عند ربط مشروع محلي موجود، أنشئ الريبو على GitHub فارغًا بلا README ولا رخصة.)
القوة — متى ولماذا وبأي صيغة
أحيانًا التاريخ المحلي هو الصحيح فعلًا — بعد rebase أو commit --amend
لفرعك الشخصي المدفوع سابقًا. هنا فقط:
# ✅ الصيغة الآمنة: تفشل لو دفع أحد شيئًا لم تره
git push --force-with-lease
# ❌ تجنّبها: تمحو أي شيء على الريموت بشكل أعمى
git push --force
القاعدة الحمراء: لا قوة على فرع يعمل عليه غيرك أبدًا — ستمحو عملهم وتكسب عداوتهم في نفس الأمر 😅. القوة لفروعك الشخصية حصرًا.
قائمة تحقّق سريعة
git pullثمpush— الحل الافتراضي دائمًا.- تاريخ أنظف؟
git pull --rebase. - أول دفع لريبو أُنشئ بـ README؟ →
--allow-unrelated-histories. - بعد rebase لفرعك الشخصي فقط:
--force-with-leaseوليس--force. - فرع مشترك = ممنوع القوة، مهما كانت الظروف.
الخلاصة
failed to push some refs ليس عطلًا بل بوابة أمان: الريموت يحمل عملًا
ليس عندك، وGit يطلب أن تدمجه محليًا قبل النشر. pull ثم push يحلها
دائمًا تقريبًا — والقوة استثناء ضيق لفرعك وحدك بصيغة --force-with-lease.
أتقن الفروع والريموت في مسار Git بالعربي، وأكمل السلسلة مع حل خطأ fatal: not a git repository و حل Merge Conflict.