Git: إدارة الإصدارات والعمل الجماعي
خروج

الدرس 1 من 9 · الأساسيات

لماذا نحتاج إلى نظام لإدارة النسخ؟ تثبيت Git وإعداده

35 د Node.js 22 (Debian, git, npm, python3)

الهدف

فهم المشكلة التي يحلّها نظام إدارة النسخ (version control)، وتثبيت Git على جهازك وإعداده بشكل صحيح (الهوية، الفرع الافتراضي، المحرّر) حتى تكون أولى عمليات الـ commit نظيفة منذ البداية.

أهم النقاط

  • يحتفظ نظام إدارة النسخ بتاريخ كل تعديل في المشروع: من، وماذا، ومتى، ولماذا. يمكننا الرجوع إلى الخلف، والمقارنة، والعمل ضمن فريق دون أن يمحو أحدنا عمل الآخر.
  • Git نظام موزَّع: يملك كل مطوّر نسخة كاملة من التاريخ، ويمكنه العمل دون اتصال بالشبكة.
  • قبل أول commit، اضبط على الأقل user.name وuser.email: فهما يُنقشان في كل commit.
  • يقرأ git config الإعدادات ويكتبها على ثلاثة مستويات: --system (الجهاز كله)، و--global (حسابك)، و--local (مستودع واحد). الأقرب هو الذي يُطبَّق.
  • يحوّل git init مجلدًا إلى مستودع: فهو ينشئ مجلدًا فرعيًا مخفيًا .git يحتوي على التاريخ كله.

1. المشكلة: « index-final-v3-OK-vraiment.html »

تخيّل وكالة Atlas Web في الدار البيضاء (حي المعاريف): أربعة مطوّرين يبنون موقعًا لسلسلة محلات حلويات. دون أداة مناسبة، هذا ما يحدث:

  • يرسل يوسف index.html عبر WhatsApp إلى سلمى، فتعدّله بينما يواصل هو العمل على نسخته. في المساء، يجب الدمج يدويًا.
  • يطلب الزبون « أعيدوا الشريط الإعلاني الذي كان قبل أمس ». لم يعد أحد يعرف أي نسخة كانت.
  • يظهر خلل (bug) في بيئة الإنتاج. من غيّر ماذا، ومتى؟ لغز.
  • يحتوي المجلد المشترك على site-final.zip وsite-final-v2.zip وsite-final-corrige-ilyas.zip…

يجيب نظام إدارة النسخ عن كل هذه الأسئلة:

الحاجة ما يفعله Git
الرجوع إلى الخلف يمكن استرجاع كل حالة مسجّلة (commit)
معرفة من غيّر ماذا يحمل كل commit مؤلفًا وتاريخًا ورسالة
العمل ضمن فريق يعمل كل واحد على فرعه (branch)، ثم ندمج (merge)
التجربة دون مخاطرة يُرمى فرع التجربة إن لم تنجح الفكرة
النسخ الاحتياطي تحتوي كل نسخة من المستودع (الجهاز، خادم GitHub أو GitLab) على التاريخ كله

مركزي أم موزَّع

كانت الأدوات القديمة (CVS وSubversion) مركزية: يعيش التاريخ على خادم واحد، ودون شبكة لا يمكن تسجيل أي شيء. أما Git، الذي أنشأه Linus Torvalds سنة 2005 لتطوير نواة Linux، فهو موزَّع: يحتوي حاسوبك على المستودع كاملًا. تُنجز عمليات commit في قطار الدار البيضاء-الرباط دون اتصال، ثم تشاركها لاحقًا.

Git ليس GitHub. Git هو البرنامج، وهو حرّ ومثبّت على جهازك. أما GitHub وGitLab وBitbucket فهي خدمات تستضيف مستودعات Git وتضيف حولها أدوات (مراجعة الشيفرة، التذاكر، CI/CD). ستتعرّف عليها في المستوى 2.

2. تثبيت Git

غالبًا ما يكون Git مثبّتًا مسبقًا. تحقّق أولًا:

git --version
# git version 2.47.2

إذا لم يُعثر على الأمر، ثبّته بواسطة مدير الحزم الخاص بنظامك:

# Debian, Ubuntu
sudo apt update && sudo apt install git

# Rocky Linux, AlmaLinux, RHEL, Fedora
sudo dnf install git

# macOS (أدوات سطر الأوامر من Apple، أو Homebrew)
xcode-select --install
brew install git

على Windows، ثبّت « Git for Windows » من موقع Git الرسمي: فهو يوفّر git وطرفية Git Bash ومديرًا لبيانات الاعتماد. يمكنك أيضًا العمل تحت WSL (نظام Ubuntu داخل Windows) وتثبيت Git بواسطة apt، كما على الخادم.

البحث في التوثيق

git help                 # الأوامر الأكثر استعمالًا
git help config          # الدليل الكامل لأمر ما (يعادل man git-config)
git config -h            # الملخّص القصير للخيارات

التوثيق الرسمي متاح أيضًا على الإنترنت، أمرًا بأمر، في موقع Git.

3. إعداد الهوية

يسجّل كل commit اسمًا وعنوان بريد إلكتروني. من دونهما، يرفض Git تنفيذ الـ commit أو يخترع هوية انطلاقًا من اسم الجهاز، مما يعطي تواريخ غير مقروءة (« root@pc-salle3 »).

git config --global user.name "Salma Bennani"
git config --global user.email "salma@agence-atlas.ma"

استعمل عنوان حسابك على GitHub أو GitLab: فبفضله يربط الموقع عمليات الـ commit بملفك الشخصي.

تحقّق:

git config --global user.name
# Salma Bennani

git config --list --show-origin
# file:/root/.gitconfig   user.name=Salma Bennani
# file:/root/.gitconfig   user.email=salma@agence-atlas.ma

مستويات الإعداد الثلاثة

الخيار الملف النطاق
--system /etc/gitconfig جميع مستخدمي الجهاز
--global ~/.gitconfig (أو ~/.config/git/config) حسابك، وجميع مستودعاتك
--local (افتراضيًا داخل مستودع) .git/config الخاص بالمستودع هذا المستودع فقط

المستوى الأدق هو الذي يُطبَّق. حالة نموذجية: مستقلّ (freelance) يعمل لصالح Atlas Web ولصالح زبائنه الخاصين، يحتفظ بعنوانه الشخصي على المستوى العام، ويضع عنوان الوكالة فقط في مستودعات الوكالة:

cd ~/projets/patisserie-atlas
git config user.email "karim@agence-atlas.ma"       # --local : هذا المستودع فقط
git config --show-origin user.email
# file:.git/config   karim@agence-atlas.ma

الملف ~/.gitconfig ملف نصي بسيط، يمكن قراءته وتعديله:

[user]
	name = Salma Bennani
	email = salma@agence-atlas.ma
[init]
	defaultBranch = main

4. إعدادات مفيدة أخرى

# اسم الفرع الذي ينشئه git init (وإلا « master » في كثير من النسخ)
git config --global init.defaultBranch main

# المحرّر المستعمل لكتابة رسائل الـ commit الطويلة
git config --global core.editor "nano"          # أو "vim"، أو "code --wait" لـ VS Code

# الألوان في الطرفية (مفعّلة افتراضيًا في النسخ الحديثة)
git config --global color.ui auto

# نهايات الأسطر: على Windows، تحويل CRLF/LF تلقائيًا
git config --global core.autocrlf true          # Windows
git config --global core.autocrlf input         # Linux و macOS

# اختصارات شخصية (alias)
git config --global alias.st status
git config --global alias.lg "log --oneline --graph --all"

لقراءة إعداد أو حذفه:

git config --global --get core.editor
git config --global --unset alias.st

نهايات الأسطر. في فريق مختلط Windows/Linux، قد يبدو ملف « معدّلًا بالكامل » لمجرد أن نهايات الأسطر تغيّرت. اضبط core.autocrlf منذ البداية؛ وسترى في المستوى 3 أن ملف .gitattributes يسمح بفرض القاعدة على الفريق كله.

5. إنشاء أول مستودع

mkdir -p ~/projets/vitrine
cd ~/projets/vitrine
git init
# Initialized empty Git repository in /root/projets/vitrine/.git/

ls -a
# .  ..  .git

المجلد .git هو المستودع: التاريخ، والفروع، والإعدادات المحلية. أما باقي المجلد فهو نسخة العمل (working copy) الخاصة بك. لا تعدّل .git يدويًا أبدًا، ولا تحذفه: ستفقد التاريخ كله.

يقبل git init أيضًا مسارًا: git init /srv/projets/vitrine ينشئ المجلد عند الحاجة.

لننشئ أول ملف ونسجّله:

echo '<h1>Pâtisserie Atlas</h1>' > index.html
git status
# On branch main
# No commits yet
# Untracked files:
#   index.html

git add index.html                       # « أريد تسجيل هذا الملف »
git commit -m "Premier commit : page d'accueil"
# [main (root-commit) 3f2a9c1] Premier commit : page d'accueil
#  1 file changed, 1 insertion(+)

git log --oneline
# 3f2a9c1 (HEAD -> main) Premier commit : page d'accueil

لقد أنجزت للتو أول commit لك. يشرح الدرس التالي بالتفصيل مناطق Git الثلاث (نسخة العمل، الفهرس index، المستودع) والأوامر add وcommit وstatus وlog وdiff.

6. المفردات الأساسية

المصطلح المعنى
المستودع (repository) المشروع الذي يتتبّعه Git، مع تاريخه كله (المجلد .git)
commit لقطة مسجّلة للمشروع، مع المؤلف والتاريخ والرسالة
hash (أو SHA) المعرّف الفريد لـ commit، مثلًا 3f2a9c1… (40 حرفًا، غالبًا ما تُختصر إلى 7)
الفرع (branch) خط تطوير؛ main هو الفرع الرئيسي
HEAD « حيث أنت الآن »: الـ commit (والفرع عادةً) المستخرج حاليًا
البعيد (remote) نسخة أخرى من المستودع، غالبًا على GitHub أو GitLab

أخطاء متكررة

  • تنفيذ commit بهوية خاطئة: تحقّق من git config user.email في كل مستودع جديد إذا كانت لديك عدة حسابات. العنوان الذي لا يطابق أي حساب على GitHub يعطي عمليات commit « يتيمة ».
  • git init في المجلد الخطأ (مجلدك الشخصي بأكمله مثلًا): يعرض git status حينها آلاف الملفات. احذف ببساطة الـ .git الذي أُنشئ خطأً بواسطة rm -rf ~/.git، بعد التحقق من المسار.
  • الخلط بين Git وGitHub: يمكن استعمال Git طوال الحياة دون حساب على GitHub؛ فالمستودع المحلي مستودع كامل.
  • نسيان -m: دون رسالة، يفتح git commit المحرّر المضبوط. إذا كان vim وتهت فيه، اضغط Échap، ثم :q! وEntrée للإلغاء.

التطبيق العملي (Lab)

في هذا المختبر (حاوية Debian فيها Git)، تنطلق من جهاز لم يُضبط فيه Git قطّ:

  1. تسجّل هويتك العامة؛
  2. تضبط الفرع الافتراضي على main؛
  3. تنشئ المستودع /root/vitrine بواسطة git init؛
  4. تنجز فيه أول commit مع ملف index.html.

تحقّق من عملك بواسطة git config --list وgit status وgit log --oneline.

اختبار قصير

  1. اذكر مشكلتين ملموستين يحلّهما نظام إدارة النسخ داخل فريق.
  2. ماذا تعني عبارة « Git موزَّع »؟
  3. ما الفرق بين git config --global وgit config --local؟ أيّهما يُطبَّق؟
  4. ماذا يحتوي المجلد .git الذي ينشئه git init؟
  5. لماذا يجب ضبط user.email قبل أول commit؟
الأجوبة
  1. مثلًا: استرجاع نسخة قديمة من ملف، ومعرفة من عدّل ماذا ومتى، والسماح لعدة أشخاص بالعمل في الوقت نفسه دون محو عمل الآخرين.
  2. تحتوي كل نسخة من المستودع على التاريخ كله: يمكن تنفيذ commit، أو الاطلاع على السجلّ، أو إنشاء فروع دون خادم ولا شبكة.
  3. ينطبق --global على جميع مستودعاتك (الملف ~/.gitconfig)؛ و--local على مستودع واحد (.git/config). الإعداد المحلي هو الذي يُطبَّق، لأنه الأدق.
  4. المستودع كله: تاريخ عمليات الـ commit، والفروع، والوسوم (tags)، والإعدادات المحلية. حذفه يعني فقدان التاريخ.
  5. لأن الهوية تُنقش في كل commit وتُستعمل لربط عمليات الـ commit بحسابك على GitHub أو GitLab؛ وتصحيحها لاحقًا يفرض إعادة كتابة التاريخ.

المراجع: التوثيق الرسمي لـ Git (git-scm.com). نص أصلي من MasterLinux.

تمارين تطبيقية

تُنجَز على Node.js 22 (Debian, git, npm, python3)

الطرفية عبر الإنترنت قادمة قريبًا. في انتظار ذلك، أنجِز هذه المهام على جهازك بنظام لينكس أو على آلة افتراضية أو WSL.

  1. سجّل هويتك في Git لحساب root بالكامل: اسم (user.name) وعنوان بريد إلكتروني (user.email) يحتوي على @. مثال: Salma Bennani، salma@agence-atlas.ma.
    عرض تلميحgit config --global user.name "Votre Nom" ثم git config --global user.email vous@exemple.ma
    عرض الحل
    git config --global user.name "Salma Bennani" && git config --global user.email salma@agence-atlas.ma

    التحقق : test -n "$(git config --global user.name)" && git config --global user.email | grep -q @

  2. اضبط Git بحيث يبدأ كل مستودع جديد على فرع اسمه main (الخيار init.defaultBranch).
    عرض تلميحgit config --global init.defaultBranch main
    عرض الحل
    git config --global init.defaultBranch main

    التحقق : test "$(git config --global init.defaultBranch)" = main

  3. أنشئ المجلد /root/vitrine وحوّله إلى مستودع Git.
    عرض تلميحmkdir -p /root/vitrine ثم git init /root/vitrine (أو cd /root/vitrine && git init)
    عرض الحل
    mkdir -p /root/vitrine && git init -q /root/vitrine

    التحقق : test -d /root/vitrine/.git && git -C /root/vitrine rev-parse --is-inside-work-tree >/dev/null 2>&1

  4. داخل /root/vitrine، أنشئ ملف index.html (يكفي سطر واحد) وسجّله في أول commit. يجب أن يكون الـ commit على الفرع main.
    عرض تلميحcd /root/vitrine ; echo '<h1>Atlas Web</h1>' > index.html ; git add index.html ; git commit -m "Premier commit"
    عرض الحل
    cd /root/vitrine && echo "<h1>Atlas Web</h1>" > index.html && git add index.html && git commit -qm "Premier commit : page d accueil"

    التحقق : git -C /root/vitrine log --oneline 2>/dev/null | grep -q . && git -C /root/vitrine ls-files | grep -qx index.html && test "$(git -C /root/vitrine branch --show-current)" = main

المراجع الرسمية المعتمدة: Git — git (page principale du manuel) — https://git-scm.com/docs/git ; Git — git-config — https://git-scm.com/docs/git-config ; Git — git-init — https://git-scm.com/docs/git-init ; Git — gittutorial — https://git-scm.com/docs/gittutorial. نص أصلي من MasterLinux.