سال‌ها پیش، روی یک قالب وردپرسی کار می‌کردم که مشتری خواست «فقط یک تغییر کوچک در فوتر» بدهم. فایل را باز کردم، ویرایش کردم، آپلود کردم و سایت برای دو ساعت از دسترس خارج شد — چون نسخهٔ پشتیبان درستی نداشتم و نمی‌دانستم دقیقاً چه چیزی را عوض کرده‌ام. آن روز دردناک، اولین جرقهٔ این بود که سراغ Git بروم. امروز، برای من Git (که مخفف Global Information Tracker نیست و در واقع یک نام تجاری است) تنها یک ابزار نیست؛ بخشی از روش کار روزمره است. در این آموزش از صفر، همان مسیری را می‌گویم که برای یادگیری Git پیموده‌ام — از ساده‌ترین دستور تا کار تیمی روی شاخه‌ها.

Git دقیقاً چیست؟

Git یک سیستم کنترل نسخهٔ توزیع‌شده (Distributed Version Control System — DVCS) است که در سال ۲۰۰۵ توسط Linus Torvalds برای مدیریت کد هسته لینوکس ساخته شد. دو کلمهٔ کلیدی در این تعریف مهم است: «کنترل نسخه» یعنی Git هر تغییر در فایل‌های شما را در قالب یک تاریخچه ذخیره می‌کند؛ «توزیع‌شده» یعنی هر توسعه‌دهنده یک نسخهٔ کامل از تاریخچه را روی سیستم خودش دارد و برای کار به اینترنت وابسته نیست مگر در لحظهٔ تبادل با مخزن مرکزی. اگر تا به حال با نسخه‌بندی آشنا نبوده‌اید، تصور کنید که هر بار قبل از تغییر، یک کپی از کل پروژه می‌سازید و اسمش را می‌گذارید «نسخهٔ قبل از تغییر — امروز ساعت ۱۴:۳۰». Git همین کار را می‌کند، ولی هزار برابر منظم‌تر و دقیق‌تر. برای درک جایگاه Git در معماری کلان یک پروژه، مطالعهٔ توسعه وردپرس چیست و از کجا باید شروع کنیم می‌تواند چارچوب ذهنی خوبی بدهد.

Git به شما اجازه می‌دهد جسور باشید؛ چون هر تغییر، هر اشتباه و هر بازگشت، در تاریخچه‌ای محفوظ است.

چرا هر توسعه‌دهنده وردپرسی به Git نیاز دارد؟

سه دلیل مشخص که در تجربهٔ کارم روی پروژه‌های وردپرسی زیاد با آن‌ها مواجه شدم:

  • پشتیبان‌گیری معنادار: بکاپ معمولی از فایل‌ها، شما را از خرابی نجات می‌دهد ولی نمی‌گوید کدام تغییر سایت را خراب کرده. Git تاریخچه‌ای خط‌به‌خط از تغییرات می‌دهد. تفاوت بکاپ فایل با بکاپ Git را می‌توان در چگونه از سایت وردپرسی بکاپ بگیریم؟ بررسی کرد.
  • کار تیمی روی قالب و افزونه: اگر تیم چند نفره روی یک چایلد تم کار می‌کنید، بدون Git هر جلسه به دعوا بر سر «فایل نهایی مال کیه» تبدیل می‌شود. مفهوم چایلد تم در قالب وردپرس چایلد چیست و چه زمانی به آن نیاز داریم آمده و Git دقیقاً روی همین لایه بیشترین ارزش را می‌دهد.
  • آزمایش بی‌ترس: وقتی می‌دانید هر چیزی قابل بازگشت است، می‌توانید ایده‌های جدید را روی یک شاخه امتحان کنید بدون اینکه نگران شکستن سایت باشید.

پیشنهاد عملی من: اگر هنوز Git را در پروژه‌های وردپرسی جدی نگرفته‌اید، از همین پروژهٔ بعدی شروع کنید. بهترین زمان برای یادگیری Git دیروز بود؛ دومین زمان، امروز است.

نصب و تنظیمات اولیه

نصب Git روی لینوکس و مک با یک دستور و روی ویندوز با دانلود فایل نصب از سایت رسمی انجام می‌شود. بعد از نصب، دو تنظیم اولیه باید یک‌بار انجام شود تا هر commit به نام شما ثبت شود:

git config --global user.name "Your Name"
git config --global user.email "you@example.com"
git config --global core.editor "code --wait"

سپس برای شروع کار روی یک پروژه، داخل پوشهٔ پروژه دستور git init را می‌زنیم. این دستور پوشه‌ای به نام .git می‌سازد که تمام تاریخچه و تنظیمات در آن زندگی می‌کند. یک نکتهٔ ظریف: خودِ پوشهٔ .git را هرگز به‌صورت دستی دست نزنید؛ این پوشه قلب Git است. اگر می‌خواهید از یک مخزن موجود روی GitHub یا GitLab (که هر دو ابزارهای میزبانی مخزن Git هستند) شروع کنید، از git clone استفاده می‌شود که مفهوم آن در آموزش GitHub توضیح داده شده است.

چرخهٔ روزمره: add، commit، push

چرخهٔ کاری روزانه در Git سه مرحلهٔ اصلی دارد که برای هر تغییر اجرا می‌شود:

  1. add: با git add filename.php یا git add . فایل‌های تغییر‌یافته را به staging area (ناحیهٔ آماده‌سازی) اضافه می‌کنید. تفاوت آن با خودِ ویرایش، این است که شما آگاهانه اعلام می‌کنید «این تغییر را در commit بعدی می‌خواهم».
  2. commit: با git commit -m "پیام تغییر" یک «تصویر» از وضعیت فعلی پروژه ثبت می‌کنید. یک قاعدهٔ طلایی در پیام commit: کوتاه و توضیحی بنویسید. مثلاً «افزودن هوک برای نمایش قیمت در هدر» بهترین پیام است، و «تغییرات» بدترین.
  3. push: با git push origin main تغییرات خود را به مخزن مرکزی می‌فرستید تا سایر اعضای تیم ببینند. اگر روی سیستم خودتان به‌تنهایی کار می‌کنید، این مرحله اختیاری است.
git add .
git commit -m "افزودن قالب نمونه‌کار به بخش خدمات"
git push origin main

یک الگوی حرفه‌ای که در پروژه‌های تیمی اجرا می‌کنم: یک commit برابر با یک «هدف معنادار» است، نه یک «فایل ذخیره‌شده». اگر پنج تغییر بی‌ربط را در یک commit بگذارید، بازگشت به عقب برای عیب‌یابی سخت می‌شود. این عادت کوچک، در پروژه‌های وردپرسی که چند نفر روی افزونه کار می‌کنند، تفاوت میان یک هفته کار و یک روز کار است.

شاخه‌ها: قلب کار تیمی در Git

Branch (شاخه) به شما اجازه می‌دهد موازی با کد اصلی، یک نسخهٔ جدا بسازید و روی آن کار کنید. وقتی کار تمام شد، شاخه را با merge به شاخهٔ اصلی برمی‌گردانید. در پروژه‌های واقعی، سه الگوی نام‌گذاری رایج است:

  • main یا master — شاخهٔ اصلی و پایدار پروژه.
  • develop — شاخهٔ توسعه که ویژگی‌های جدید در آن ادغام می‌شوند قبل از رفتن به main.
  • feature/نام-ویژگی — شاخهٔ موقت برای هر ویژگی یا رفع باگ.
git checkout -b feature/contact-form
git add .
git commit -m "افزودن فرم تماس با اعتبارسنجی سمت کاربر"
git push -u origin feature/contact-form

فلسفهٔ اصلی این الگو، ایزوله بودن است. اگر روی شاخهٔ ویژگی کار می‌کنید و نتیجه رضایت‌بخش نبود، به‌سادگی آن را حذف می‌کنید بدون اینکه به main آسیب رسیده باشد. برای تیم‌های وردپرسی، این الگو به‌خصوص در پروژه‌های افزونه‌ای که چند نفر هم‌زمان روی بخش‌های مختلف کار می‌کنند، ضروری است. مراحل دقیق کار با شاخه‌ها در برنچ در Git به‌تفصیل آمده است.

ادغام و حل تعارض

وقتی دو نفر روی یک فایل کار می‌کنند و هر دو تغییرات خودشان را push می‌کنند، Git ممکن است نتواند به‌طور خودکار ادغام کند و پیام «merge conflict» می‌دهد. این پیام به‌معنای خطر نیست؛ یک درخواست از شماست که تصمیم بگیرید کدام تغییر بماند. Git در همان فایل، سه بخش را با نشانه‌هایی مثل <<<<<<< و ======= و >>>>>>> مشخص می‌کند:

<<<<<<< HEAD
نسخهٔ شما در این شاخه
=======
نسخهٔ نفر دیگر در شاخهٔ دیگر
>>>>>>> feature/other

شما باید یکی از دو نسخه (یا ترکیبی از هر دو) را نگه دارید و خطوط نشانه‌گذاری را حذف کنید. سپس git add و git commit عادی ادامه می‌یابد. یک عادت عملی: قبل از commit نهایی، همیشه یک بار پروژه را در حالت اجرا تست کنید. حل تعارض فقط بخش فنی است؛ تست نکردنِ نتیجه، دام پنهان آن است. روش دقیق‌تر در حل تعارض در Git و مرج در Git آمده است.

جدول دستورات پرکاربرد و کاربردشان

دستورکاربردزمان استفاده
git statusنمایش وضعیت فعلی فایل‌هاقبل از هر commit، برای اطمینان از اینکه چه چیزی اضافه شده
git log --onelineنمایش خلاصهٔ تاریخچهٔ commitهابرای پیدا کردن یک commit خاص یا مرور گذشته
git diffنمایش تغییرات فعلی فایل‌هاقبل از add، برای بازبینی خودتان
git checkout -- file.phpبازگردانی فایل به آخرین commitوقتی آزمایشی کردید و می‌خواهید برگردید
git reset --soft HEAD~1حذف آخرین commit ولی نگه داشتن تغییراتوقتی پیام commit اشتباه بوده یا فایلی اضافه شده
git stashذخیرهٔ موقت تغییرات بدون commitوقتی باید سریع روی موضوع دیگری کار کنید
git remote -vنمایش مخازن متصلهنگام اتصال به GitHub یا GitLab

اشتباهات رایج مبتدی‌ها

  • commit کردن پوشهٔ wp-content/uploads: این پوشه پر از فایل‌های کاربر است و حجم مخزن را چند صد مگابایت می‌کند. با فایل .gitignore آن را نادیده بگیرید.
  • commit کردن رمزهای عبور و کلیدهای API: هرگز. اگر به‌اشتباه این کار را کردید، صرفاً حذف فایل در commit بعدی کافی نیست — تاریخچهٔ Git هم باید پاک شود. یکی از بدترین رخدادهای امنیتی پروژه‌ها از همین‌جا شروع می‌شود.
  • پیام‌های commit مبهم: «update»، «fix»، «test» — سه ماه بعد هیچ‌کدام از این‌ها به شما نمی‌گوید چه چیزی عوض شد.
  • نادیده گرفتن شاخه‌ها: کار مستقیم روی main در تیم، پتانسیل ایجاد فاجعه‌های هم‌زمانی را دارد.
  • ندیدن وضعیت قبل از push: همیشه یک بار git status بزنید تا مطمئن شوید فایلی اشتباهی اضافه نشده.

Git در پروژه‌های وردپرسی

مدیریت Git برای پروژه‌های وردپرسی یک الگوی مشخص دارد که در پروژه‌های خودم استفاده می‌کنم. اول، هستهٔ وردپرس، قالب‌های عمومی و افزونه‌های عمومی از مخزن حذف می‌شوند؛ چون به‌صورت خودکار از مخزن رسمی به‌روزرسانی می‌شوند و نگه‌داشتنشان در Git فقط حجم را زیاد می‌کند. دوم، آنچه در Git می‌ماند: قالب فرزند، افزونه‌های اختصاصی، فایل‌های پیکربندی نمونه (نه فایل‌های واقعی حاوی رمز)، و فایل‌های مستندات. الگوی کامل این ساختار در گیت در وردپرس آمده است. یک نکتهٔ عملی که در تیم‌های وردپرسی زیاد روی آن تأکید می‌کنم: قبل از هر تغییر در functions.php، همیشه یک commit بزنید. اگر بعد از تغییر، سایت به صفحهٔ سفید رفت، با یک git checkout در چند ثانیه برمی‌گردید. علت رایج این خطا را در رفع خطای Parse error در functions.php بررسی کرده‌ام و Git در این سناریو، ابزار نجات است.

آن‌سوی دستورها: مدل ذهنی داخلی Git

برای توسعه‌دهنده‌های ارشد، Git یک ساختار داده است که سه سطح اصلی دارد: working directory (فایل‌های شما روی دیسک)، staging area (ناحیهٔ آماده‌سازی)، و repository (تاریخچهٔ ذخیره‌شده). هر دستور Git در واقع انتقال داده بین این سه سطح است. add داده را از working به staging منتقل می‌کند؛ commit از staging به repository؛ و checkout داده را از repository به working برمی‌گرداند. وقتی این مدل ذهنی را بفهمید، دستورهای پیچیده‌تر مثل reset (سه حالت soft، mixed و hard)، rebase و cherry-pick دیگر جادو به نظر نمی‌رسند؛ هر کدام فقط یک عملیات مشخص روی همین سه سطح هستند.

نکتهٔ مهم‌تر، مدل ذخیره‌سازی درون Git است. هر commit در واقع یک «snapshot» از کل پروژه است که با یک هش SHA-1 یکتا شناسایی می‌شود. این یعنی commit بعدی همیشه به commit قبلی اشاره دارد و یک گراف جهت‌دار بدون دور می‌سازد. این ساختار، دلیل شگفت‌آور کارآمدی Git را توضیح می‌دهد: حتی وقتی هزاران شاخه و ادغام دارید، پیدا کردن تفاوت‌ها در زمان O(log n) انجام می‌شود. برای توسعه‌دهندگان وردپرس، این درک به‌خصوص در پروژه‌هایی که تاریخچهٔ طولانی دارند، حیاتی است. به‌عنوان یک قاعدهٔ شخصی، هر سه ماه یک بار git log --graph --oneline --all می‌زنم و ساختار کلی پروژه‌های فعال را مرور می‌کنم؛ این کار به من اجازه می‌دهد قبل از اینکه شاخه‌های رهاشده به بدهی فنی تبدیل شوند، آن‌ها را پاک‌سازی کنم. در پروژه‌ای که سه سال با یک تیم چهار نفره روی یک افزونهٔ وردپرسی کار می‌کردیم، همین عادت سه‌ماهه باعث شد هیچ‌وقت بیش از دو شاخهٔ فعال نداشته باشیم، در حالی که تیم‌های مشابه در همان دوره با ده‌ها شاخهٔ رهاشده دست‌وپنجه نرم می‌کردند. قاعده‌ای که به‌عنوان جمع‌بندی این بخش توصیه می‌کنم: در Git، انضباط مهم‌تر از دانش دستورهاست؛ شما می‌توانید فقط ده دستور بلد باشید ولی اگر منظم باشید، پروژه‌تان سالم می‌ماند.

اگر Git را تازه شروع کرده‌اید و به یک موقعیت خاص برخوردید — مثلاً برگرداندن یک commit که اشتباهاً push شده، یا کار هم‌زمان چند نفر روی یک قالب وردپرسی — سناریو را در دیدگاه بنویسید. جزئیات همان تجربه‌ها، برای من و بقیهٔ خواننده‌ها از هر مستند رسمی زنده‌تر است. 🌱