۱. چرا Save کردن برای تغییرات هوش مصنوعی کافی نیست؟
فرض کن یک اپ ثبت گزارش داری و از ایجنت میخواهی صفی برای گزارشهای صوتی بسازد. قبل از درخواست، فرم ثبت گزارش درست کار میکند؛ بعد از آن شاید چند فایل تازه ساخته شود و رفتار فرم هم عوض شود. اگر فقط فایلها را Save کرده باشی، تغییرات روی دیسک هستند، اما هنوز نقطهٔ مشخصی در تاریخچه نداری که بگویی «این نسخهٔ سالمِ قبل از صف بود».
کپیگرفتن از کل پوشه هم برای چند آزمایش پشتسرهم گیجکننده میشود: کدام پوشه سالم بود و دقیقاً چه چیزی بین دو پوشه عوض شد؟ Git تاریخچهای از نسخههای انتخابشده به تو میدهد و تفاوت آنها را نشان میدهد. البته Git جای همهٔ روشهای پشتیبانگیری را نمیگیرد؛ اگر تنها نسخهٔ مخزن روی همان کامپیوتر باشد و دیسک از بین برود، تاریخچهٔ محلی هم در خطر است.
۲. Save، staging و commit سه اتفاق جدا هستند
Save یعنی محتوای فعلی فایل در پوشهٔ پروژه ذخیره شده است. Git میتواند این محتوا را با آخرین نسخهٔ ثبتشده مقایسه کند. Staging، یا «آمادهکردن برای کامیت»، مرحلهای است که در آن انتخاب میکنی چه محتوایی وارد کامیت بعدی شود. Commit همان نقطهٔ ثبتشده در تاریخچهٔ محلی است؛ همراه پیامی که توضیح میدهد چرا این تغییر را نگه داشتهای.
یک ظرافت مهم: اگر فایلی را stage کنی و بعد دوباره ویرایشش کنی، ویرایش تازه خودبهخود وارد staging نمیشود. ممکن است یک فایل همزمان تغییرِ آمادهشده و تغییرِ آمادهنشده داشته باشد. بنابراین پیش از commit فقط به این نگاه نکن که نام فایل زیر چه عنوانی آمده؛ تفاوتِ محتوای آمادهشده را هم بخوان.
گاهی commit را «بکاپ» صدا میزنیم، اما توصیف دقیقترش یک snapshot یا تصویر از وضعیت فایلهای ردیابیشده در آن نقطه است. Git لزوماً برای هر commit یک کپی کامل و مستقل از همهٔ فایلها نمیسازد؛ محتوای یکسان را بازاستفاده میکند و برای انتقال داده هم ممکن است آن را بهینهسازی کند. از آن طرف، اینطور هم نیست که تاریخچه صرفاً فهرستی از چند خطِ تغییرکرده باشد. درک همین تفاوت کمک میکند بدانی commit چه چیزی را حفظ میکند و چرا دیدن diff با ماهیت ذخیرهسازی Git یکی نیست.
۳. مخزن را آماده کن و چیزهای حساس را کنار بگذار
برای تمرین، Git را نصب کن، در VS Code پوشهٔ اصلی یک پروژهٔ آزمایشی را باز کن و ترمینال همان پوشه را اجرا کن. دستورهای این مقاله برای ترمینالی نوشته شدهاند که Git در آن در دسترس است. ابتدا وضعیت را ببین؛ اگر پروژه از قبل مخزن Git دارد، git init را تکرار نکن.
git --version
git status
اگر git status گفت این پوشه مخزن Git نیست، در همان پوشهٔ اصلی این دستور را بزن:
git init
نتیجهٔ مورد انتظار این است که git status دیگر خطای «not a git repository» ندهد. Git اطلاعات مخزن محلی را در پوشهٔ پنهان .git نگه میدارد؛ لازم نیست فایلهای داخل آن را دستی تغییر بدهی.
قبل از اولین git add، فایل .gitignore را در ریشهٔ پروژه بررسی کن؛ اگر وجود ندارد، آن را بساز. فایلهای موقت، خروجی ساخت و فایلهای حاوی کلید معمولاً نباید وارد مخزن شوند. برای نمونه، اگر پروژهات از فایلهای محیطی با این نامها استفاده میکند، میتوانی الگوی زیر را به .gitignore اضافه کنی:
.env
.env.*
!.env.example
این الگو فقط برای فایلهایی اثر دارد که هنوز ردیابی نشدهاند؛ چیزی را که قبلاً commit شده از تاریخچه پاک نمیکند. اگر کلیدی را اشتباهی به GitHub فرستادهای، حذف آن در commit بعدی کافی نیست: کلید را در سرویس مربوط باطل یا تعویض کن و بعد وضعیت مخزن را اصلاح کن. حتی مخزن خصوصی هم دلیل خوبی برای ثبتکردن کلید نیست. اگر .env.example را در مخزن میگذاری، فقط نام متغیرها و مقدارهای نمونهٔ غیرواقعی را در آن بنویس.
پیش از سپردن تغییر بعدی به ایجنت، یک نقطهٔ شروع سالم ثبت کن. اگر پروژه هنوز commit ندارد، در Source Control فقط فایلهای لازم و بررسیشدهٔ نسخهای را که درست کار میکند stage کن؛ با git status و git diff --staged انتخابت را بازبینی کن و سپس، مثلاً با git commit -m "Record working baseline"، آن را ثبت کن. اگر از قبل commit سالمی داری، لازم نیست همان وضعیتِ بدون تغییر را دوباره commit کنی.
۴. پیش از درخواست بعدی، تفاوتها را بخوان
حالا فرض کن ایجنت چند فایل فرم را تغییر داده است. در VS Code بخش Source Control نام فایلهای تغییرکرده و تازه را نشان میدهد؛ با بازکردن هر فایل میتوانی خطوط حذفشده و افزودهشده را کنار هم ببینی. رنگها کمک بصریاند، نه حکم دربارهٔ درستبودن تغییر. همان بررسی را در ترمینال با این دستورها انجام بده:
git status --short
git diff
git diff --check
git status --short خلاصهٔ وضعیت فایلها را میدهد. git diff تغییراتِ هنوز آمادهنشده را نسبت به محتوای staging نشان میدهد؛ اگر چیزی stage نکرده باشی، این مقایسه عملاً با آخرین نسخهٔ ثبتشده است. git diff --check بعضی ایرادهای فاصلهگذاریِ همین تغییراتِ آمادهنشده را گزارش میکند. اگر git diff خالی بود، نتیجه نگیر که هیچ تغییری وجود ندارد: شاید تغییرات را stage کردهای یا فایل تازهای هنوز به Git معرفی نشده است. وضعیت را با git status بررسی کن.
اینجا سؤال اصلی تو این نیست که «ایجنت چند فایل دست زده؟»؛ باید بفهمی آیا تغییراتش به همان درخواست مربوطاند. اگر قرار بوده فقط صف گزارش صوتی اضافه شود، تغییر بیدلیل در تنظیمات ورود کاربران ارزش مکث و بررسی دارد. فایل ناشناس را صرفاً برای تمیزشدن فهرست تغییرات وارد commit نکن.
۵. فقط نسخهٔ قابلدفاع را stage و commit کن
در بخش Source Control میتوانی کنار فایلهای موردنظر علامت + را بزنی. معادل آن در ترمینال، git add با مسیر مشخص است. دستورهای زیر مثال تکمیلی آموزشی هستند، نه دستورهایی که عیناً برای پروژهٔ ضبطشده اجرا شده باشند. فرض کن در پروژهٔ تمرینیات دو فایل src/form.js و src/queue.js وجود دارند و تغییرشان را بررسی کردهای:
git add src/form.js src/queue.js
git diff --staged
git status
git commit -m "Add draft report queue"
اگر نام فایلهای تو فرق دارد، مسیرها را با مسیر واقعی جایگزین کن. git diff --staged تفاوتِ محتوای آمادهشده را با آخرین commit نشان میدهد؛ برای دیدن فهرست فایلهای آمادهشده، git status را هم بررسی کن. پس از git commit، انتظار داری یک commit تازه در تاریخچه ببینی؛ اگر فایل دیگری را عمداً stage نکرده باشی، در آن commit جایی ندارد. میتوانی با git log --oneline -5 پنج commit آخر را ببینی.
پیام commit بهتر است به تو کمک کند چند هفته بعد بفهمی چه تغییری ثبت شده؛ «نسخهٔ جدید» معمولاً کمتر از «افزودن صف گزارش» اطلاعات میدهد. نقطهٔ مناسب برای commit هم وقتی است که یک بخش کوچک را بررسی و تا حد ممکن آزمایش کردهای، نه بعد از هر فشار کلید و نه پس از انباشتهشدن چند تغییر نامرتبط. در تجربهٔ پروژهٔ گزارش صوتی، پس از اینکه صف در حالت محلی قابلآزمایش شد، ثبت آن پیش از سپردن انتشار به ایجنت یک نقطهٔ بازگشت معقول بود.
۶. Git محلی است؛ GitHub نسخهٔ راهدور را نگه میدارد
تا اینجا همهٔ commitها میتوانند فقط روی کامپیوتر تو باشند. Git نرمافزار کنترل نسخه است؛ GitHub سرویسی برای میزبانی مخزن راهدور، اشتراکگذاری و همکاری است. «remote» نام ارتباط مخزن محلی با یک مخزن دیگر است و معمولاً نام origin را برای آن انتخاب میکنند. نامگذاری قرارداد است، نه ویژگی جادوییِ GitHub.
پیش از انتشار، بررسی کن فایلها و تاریخچهات مناسب فرستادن به GitHub هستند. برای شروع، یکی از دو مسیر را انتخاب کن: اگر هنوز مخزن راهدور نساختهای، از گزینهٔ انتشار در VS Code، مانند Publish Branch یا Publish to GitHub، استفاده کن؛ در صورت ارائهٔ این قابلیت، وارد حساب شو و هنگام ساخت مخزن، عمومی یا خصوصیبودن آن را آگاهانه انتخاب کن. اگر مخزن را از قبل در GitHub ساختهای، بهتر است برای این تمرین خالی و بدون README اولیه باشد. ابتدا با git remote -v مطمئن شو origin دیگری نداری؛ سپس نشانی همان مخزن را از GitHub بردار، در دستور git remote add origin URL بهجای URL بگذار و با git push -u origin HEAD شاخهٔ فعلی را بفرست. بعد از انتشار، صفحهٔ GitHub را باز کن: باید فایلهای commitشده و پیام commit را ببینی، نه الزاماً هر فایل موجود روی کامپیوترت.
برای بررسی اتصال، این دستور کافی است:
git remote -v
اگر هنوز remote تعریف نشده باشد، خروجی مرتبطی نمیبینی. اگر تعریف شده باشد، نشانی مقصد نمایش داده میشود؛ قبل از push مطمئن شو مقصد همان مخزنی است که میخواستی. راهنمای رسمی Git برای جزئیات بیشترِ مخزن محلی و راهدور مرجع مناسبی است.
۷. Push و pull را با commit اشتباه نگیر
Commit روی مخزن محلی ثبت میشود. Push، commitهای محلی را به مخزن راهدور میفرستد؛ pull تغییرات راهدور را میگیرد و با شاخهٔ فعلی محلی ادغام میکند. بنابراین پس از یک commit، دیدن پیام تازه در VS Code بهمعنای دیدهشدن آن در GitHub نیست. برعکس، اگر کسی در GitHub فایلی را ویرایش و همانجا commit کند، نسخهٔ محلی تو خودبهخود بهروز نمیشود.
اگر شاخهٔ فعلیات شاخهٔ بالادستی دارد، پیش از کار مشترک git status را ببین. اگر تغییرات ثبتنشده داری، پیش از pull تکلیفشان را روشن و کار مفید را حفظ کن؛ سپس تغییرات راهدور را دریافت کن. اگر شاخهٔ بالادستی هنوز تنظیم نشده، ابتدا شاخه و اتصال راهدور را بررسی کن؛ git pull --ff-only بدون این تنظیم ممکن است خطا بدهد:
git status
git pull --ff-only
گزینهٔ --ff-only فقط وقتی پیش میرود که تاریخچهٔ محلی بدون ساختن commit ادغام جلو برود. اگر تاریخچهها از هم جدا شده باشند، دستور متوقف میشود؛ این توقف بهتر از آن است که بیخبر راهحلِ ادغام انتخاب شود. در چنین وضعی ابتدا git status و تاریخچه را بررسی کن و دربارهٔ ادغام یا بازچینی commitها تصمیم بگیر. وقتی تغییرات خودت را commit کردی و remote آماده بود، از Push در VS Code استفاده کن. در ترمینال نیز اگر شاخهٔ فعلی هنوز شاخهٔ بالادستی ندارد، git push -u origin HEAD همان شاخهٔ فعلی را به origin میفرستد. پس از آن، git push معمولاً برای ارسال commitهای بعدی کافی است. اگر خطای احراز هویت یا ردشدن push دیدی، رمز عبور حساب را در فایل پروژه نگذار؛ مسیر ورودِ ابزار و وضعیت شاخهٔ راهدور را بررسی کن.
۸. تغییر خرابِ هنوز commitنشده را با احتیاط کنار بگذار
اینجاست که Git در وایب کدینگ واقعاً به کارت میآید. فرض کن ایجنت فقط متن یک فایل را تغییر داده و تو پس از دیدن diff فهمیدهای تغییر اشتباه است. اگر فایل هنوز stage نشده، میتوانی در VS Code گزینهٔ کنارگذاشتن تغییر همان فایل را انتخاب کنی. این کار محتوای ذخیرهشدهٔ فعلی آن فایل را از دست میدهد؛ پس قبلش مطمئن شو بخش مفیدی داخلش نیست.
اگر فایل stage شده، اول با git diff --staged ببین چه چیزی آماده است. برای خارجکردن آن از staging، بدون حذف ویرایش فایل، میتوانی این دستور را بزنی:
git restore --staged path/to/file
مسیر نمونه را با مسیر واقعی عوض کن. نتیجهٔ مورد انتظار: فایل هنوز در پروژه تغییرکرده است، اما دیگر جزو commit بعدی نیست. اگر از تصمیم خودت مطمئن نیستی، همینجا توقف کن و نسخهای از محتوای مفید را جداگانه نگه دار. خارجکردن از staging با برگرداندن محتوای فایل دو کار متفاوت است؛ قاطیکردنشان میتواند زحمتی را که هنوز commit نکردهای از بین ببرد.
۹. وقتی تغییر خراب commit شده، نسخهٔ سالم را امن پیدا کن
اگر تغییر بد را commit کردهای، اولین واکنش نباید پاککردن تاریخچه باشد. با git log --oneline -5 commitهای اخیر را پیدا کن و با git show HASH --stat ببین commit موردنظر چه فایلهایی را درگیر کرده است؛ HASH را با شناسهٔ واقعی commit جایگزین کن. اگر فقط میخواهی محتوای قدیمی یک فایل متنی را بدون دستزدن به فایل فعلی بررسی کنی، دستور زیر را در ترمینالی اجرا کن که تغییرمسیر خروجی (>) را پشتیبانی میکند. فرض این مثال آن است که recovered-copy.md هنوز وجود ندارد:
git show HASH:path/to/file.md > recovered-copy.md
این هم مثال تکمیلی آموزشی است. مسیر سمت چپ باید مسیر فایل در همان commit باشد. نتیجه، یک فایل تازه برای مقایسه است؛ پس از بررسی، تصمیم میگیری کدام بخش را به فایل اصلی برگردانی و آیا فایل کمکی را نگه داری یا پاک کنی. اگر کل یک commit اشتباه بوده، مخصوصاً وقتی آن را push کردهای، git revert HASH معمولاً راه امنتری است: commit تازهای میسازد که اثر commit انتخابی را برمیگرداند و تاریخچهٔ قبلی را حفظ میکند. پیش از اجرای آن git status را بررسی کن؛ در پروژهٔ دارای تغییرات ذخیرهنشده یا وابستگی میان چند commit، اول وضعیت را روشن کن، چون revert هم ممکن است به تعارض برسد.
برای یک مبتدی، reset --hard انتخاب مناسبی برای «فقط میخواهم برگردم» نیست: میتواند تغییرات ثبتنشده را حذف کند و با جابهجایی تاریخچه، تشخیص اتفاقی را که افتاده دشوارتر کند. حتی اگر از ایجنت کمک میگیری، به او اجازهٔ اجرای کورکورانهٔ دستور بازگشت نده. اول بخواه وضعیت و دستور پیشنهادی را توضیح بدهد، بعد خودت اثر آن را تأیید کن.
۱۰. چرخهای که برای پروژهٔ بعدی نگه میداری
تمرین را با یک تغییر کمخطر تمام کن. روی یک پروژهٔ آزمایشی، نسخهای را که فعلاً درست کار میکند commit کن؛ از ایجنت بخواه فقط متن یک دکمه را تغییر بدهد؛ فایل را Save کن و پیش از هر commit، diff را بخوان. سپس همان تغییر را stage کن، git diff --staged را ببین و با پیامی مشخص commit بزن. اگر remote آزمایشی داری، push کن و وجود پیام را در GitHub بررسی کن. برای تمرین دریافت تغییر نیز یک فایل غیرحساس را در GitHub ویرایش و commit کن، بعد آن را روی کامپیوترت pull کن.
خروجی واقعی این تمرین فقط چند دستور حفظشده نیست: یک پروژه با دو یا چند نقطهٔ ثبتشده، پیامهای قابلفهم، یک تغییر قابلمشاهده در diff و توانایی تشخیص این است که نسخهٔ فعلی محلی با نسخهٔ GitHub یکسان هست یا نه. دفعهٔ بعد که ایجنت چند فایل را یکباره تغییر داد، بهجای امیدواری به اینکه چیزی خراب نشده، میتوانی دقیقاً بررسی کنی چه اتفاقی افتاده و از کدام نقطه ادامه بدهی.
ویدیوی کامل
اگر میخواهی روند کار و آزمونها را هم ببینی، ویدیوی کامل این آموزش اینجاست:


دیدگاهتان را بنویسید
برای نوشتن دیدگاه باید وارد بشوید.