آموزش گیت-بخش دوم-آموزش Stage در Git

در جلسه اول، گیت را معرفی کردیم، تفاوت آن را با گیتهاب بیان کردیم، نحوه دانلود و نصب و تنظیمات آن را نیز در ادامه آموزش دادیم. در این بخش می خواهیم به یکی از مفاهیم مهم و اساسی گیت یعنی Stage بپردازیم.
فهرست موضوعات جلسه دوم:
- مفهوم stage
- ایجاد فایل های پروژه
- روش های مختلف افزودن به stage
- دستور commit در گیت
- حذف فایل از پروژه
- تغییر نام فایل یا جابجایی آن
- ignore کردن فایل ها
- مشاهده وضعیت stage
- مشاهده تاریخچه کامیت ها
- نحوه خارج کردن فایل از stage
- بازگردانی فایل حذف شده
مفهوم stage در گیت:
یک مرحله واسط است که بین فولدر پروژه ما (سمت چپ تصویر زیر) و repository گیت (سمت راست تصویر زیر) قرار دارد:
با استفاده از دستور git add می توان تغییرات فایل های پروژه را به مرحله stage وارد کرد و سپس با دستور git commit این تغییرات را به rep گیت منتقل کرد. در ادامه با ذکر مثال قضیه روشن تر می شود.
ایجاد فایل های پروژه برای کار با stage:
اکنون می خواهیم فایل هایی را در پروژه ایجاد کنیم و آنها را تغییر دهیم.
دستور echo hello world > file1.txt را در git bash اجرا کنید.
حالا دستور echo hello world > file2.txt را اجرا کنید.
مشاهده می کنید که نام دو فایل file2.txt و file1.txt با رنگ قرمز مشخص شده اند. یعنی هنوز وارد مرحله stage نشده اند.
روش های مختلف افزودن به stage:
می توان دستور git add را به شکل های مختلف نوشت:
git add file1.txt file2.txt یا استفاده از پترن مانند git add *.txt یا . git add (انتقال تمام فایل ها و فولدرهای پروژه به ریپازیتوری)
نکته: در استفاده از دستور . git add دقت کنید. زیرا همیشه ما نمی خواهیم تمام فایل ها و فولدرهای پروژه را در stage ثبت کنیم. مانند فولدر node_modules که شامل تعداد بسیار زیادی فایل و فولدر است. در اینصورت حجم repository گیت ما بشدت افزایش خواهد یافت.
در ادامه پس از اجرای یکی از دستورات stage ، مطابق تصویر زیر، نام فایل ها از قرمز به سبز تغییر رنگ داده اند:
حالا با استفاده از دستور echo Ehsan Safari >> file1.txt یک خط دیگر با محتوای Ehsan Safari به فایل file1.txt اضافه می کنیم.
نکته: اگر از << استفاده کنیم، یک خط جدید به فایل متنی ما اضافه می شود و محتوای موردنظر درج می شود اما اگر از < استفاده شود، محتوای قبلی پاک شده و محتوای جدید در فایل نوشته می شود.
مشاهده می شود که فایل file1.txt با رنگ قرمز و برچسب modified مشخص شده است. یعنی محتویات این فایل تغییر کرده اما هنوز در stage اضافه نشده است.
به تصویر زیر دقت کنید:
درست است که فایل های file1 و file2 هم اکنون در stage قرار دارند اما تغییر جدیدی که در فایل file1 ایجاد کرده ایم به stage منتقل نشده است و هنوز ورژن قبلی آن است.
پس مانند قبل می توان با دستور git add file1.txt تغییرات جدید فایل file1 را به stage اضافه کرد و مجددا دستور git status را برای مشاهده وضعیت stage اجرا کرد:
دستور commit در گیت:
حالا نوبت commit کردن تغییرات stage در repository است. به دو روش می توان اینکار را انجام داد:
1- اجرای دستور git commit -m “our commit message here” مانند زیر:
2- اجرای دستور git commit و زدن اینتر. سپس در فایلی که در ویژوال استودیو باز می شود پیغام خود را مطابق تصویر زیر تعریف کرده و فایل را ذخیره می کنیم و می بندیم:
اکنون اگر به git bash برگردیم، مشاهده می کنیم که پیغام commit ما با موفقیت ثبت شده است:
حالا محتوای پروژه ما با محتوای stage و محتوای repository گیت یکسان شده است و در واقع sync هستند.
نکته 1: سعی کنید پیغام هایی که برای کامیت ها تعریف می کنید کاملا واضح و توصیفی باشند. یعنی وقتی یک توسعه دهنده دیگر پیغام های کامیت شما را می خواند متوجه شود که دقیقا چه تغییراتی در کامیت شما رخ داده است.
نکته 2: سعی کنید commit هایی که انجام می دهید زیاد کوچک یا زیاد بزرگ نباشند. یعنی به محض یک تغییر کوچک در فایل آن را کامیت نکنید. یا بالعکس، پس از سه روز کدنویسی تازه به فکر کامیت نیوفتید. بلکه حد وسط این دو را رعایت کنید.
*آیا لازم است حتما ابتدا تغییرات را به stage منتقل کنیم و سپس آنها را commit کنیم؟
پاسخ منفی است. در صورتیکه از کد خود مطمئن هستید که نیازی به بازبینی ندارد، می توانید مستقیما تغییرات را commit کنید. به این شکل:
ابتدا یک تغییر کوچک در فایل file2 ایجاد می کنیم. دستور echo Frontend Developer >> file2.txt را اجرا کنید.
سپس دستور git commit -a -m “your message here’ را اجرا کنید. در تصویر بالا مشاهده می شود که تغییرات فایل file2 مستقیما از working directory یا فولدر پروژه ما وارد repository شده است.
نکته: پیشنهاد می کنیم در اغلب موارد تغییرات خود را ابتدا وارد مرحله stage کنید و سپس آنها را کامیت کنید.
حذف فایل از پروژه:
فرض کنید دیگر نیازی به فایل file2 نداریم و می خواهیم آنرا پاک کنیم. ابتدا دستور rm file2.txt را مطابق تصویر زیر اجرا کنید:
سپس با اجرای دستور git status مشاهده می کنیم که فایل file2.txt با رنگ قرمر و لیبل deleted مشخص شده است. یعنی این فایل از working directory حذف شده است اما هنوز در stage قرار دارد.
برای مشاهده فایل هایی که هم اکنون در stage قرار دارند دستور git ls-files را اجرا کنید.
مشاهده می کنید که هر دو فایل file1, file2 در stage قرار دارند. در حالیکه ما فایل file2 را از پروزه خود حذف کردیم. برای اینکه stage نیز متوجه این تغییر شود، کافیست دستور git add file2.txt را اجرا کنیم. حال اگر مجددا دستور git ls-files را اجرا کنیم می بینیم که فقط file1 در stage قرار دارد.
حال کافیست دستور git commit -m را اجرا کرده و پیفام مرتبط را بنویسیم تا تغییرات stage وارد rep هم بشود.
نکته: بدلیل اینکه حذف فایل از پروژه بسیار پرکاربرد و رایج است، گیت برای راحت تر کردن فرآیند حذف، دستور git rm filename.txt را ارائه کرده است. با اجرای دستور git rm file2.txt این فایل هم از فولدر پروژه حذف می شود و هم از stage. پس کار راحت تر می شود!
تغییر نام فایل یا جابجایی آن:
فرض کنید می خواهیم نام فایل file1.txt را به main.js تغییر دهیم. کافیست دستور mv file1.txt main.js را اجرا کنیم.
همانطور که می بینید، دو فایل با رنگ قرمز در status گیت ما قرار دارد. اولی فایل file1.txt است که با لیبل deleted مشخص شده و دومی نام فایل جدید یعنی main.js است. واضح است که الان باید آنها را وارد stage کنیم. با اجرای دستور git add file1.txt main.js
تنها کاری که باقی می ماند کامیت کردن این تغییرات است. اما گیت همانند دستور rm برای حذف فایل از پروژه، یک دستور دارد برای تغییر نام فایل. دستور git mv main.js file1.js می تواند نام فایل main.js را به file1.js تغییر دهد و در stage نیز ثبت کند و دیگر نیازی نیست بصورت دستی این مراحل را انجام دهیم:
در مرحله آخر هم باید تغییرات را کامیت کنیم. به شکل زیر:
مشاهده می شود که در پیغام گیت، نوشته شده: 1 file changed, 0 insertion, 0 deletion یعنی هیچ فایلی حذف یا اضافه نشده. فقط یک فایل تغییر کرده است.
صرف نظر کردن از فایل ها در گیت:
در تمام پروژه ها، فایل ها و فولدرهایی وجود دارند که نمی خواهیم در گیت ثبت شوند و حجم ریپازیتوری را بالا ببرند. یکی از این موارد، فایل های لاگ هستند. در ادامه می خواهیم یک فولدر بنام logs بسازیم و یک فایل بنام dev.log در آن ایجاد کرده و مقدار test-log را در آن درج کنیم.
مشاهده می شود که فولدر logs هنوز در stage اضافه درج نشده است. در ادامه برای اینکه گیت از این فولدر و محتویات داخل آن صرف نظر کند و تغییرات آن را رهگیری نکند، باید یک فایل بسازیم بنام gitignore با محتوای /logs
سپس با اجرای دستور code .gitignore فایل gitignore را داخل VScode باز می کنیم. داخل این فایل نام فولدرها و فایل هایی را که می خواهیم گیت از آنها صرف نظر کند را می نویسیم.
اکنون اگر دستور git status را اجرا کنیم می بینیم که گیت دیگر با فولدر logs و تغییرات داخل آن کاری ندارد و فقط می گوید فایل gitignore به stage اضافه نشده است. کافیست مانند قبل توسط git add .gitignore این فایل را به stage اضافه کرده و سپس کامیت کنیم:
ignore کردن فایل ها یا فولدرهایی که قبلا در repository ثبت شده اند:
اگر فایل یا فولدری را قبلا به repository اضافه کرده ایم و الان در فایل gitignore آن را تعریف کنیم، جواب نمی دهد. یعنی گیت فایل ها و فولدرهایی که از قبل به ریپازیتوری کامیت شده اند را نمی تواند ignore کند. اما فرض کنید ما اشتباها فولدر node_modules را به ریپازیتوری کامیت کرده ایم و الان می خواهیم گیت از آن صرف نظر کند و در کامیت بعدی به ریپازیتوری اضافه نشود. برای اینکار راه حل زیر را داریم:
ابتدا یک فولدر بنام node_modules می سازیم و یک فایل بنام package1.js با محتوای تستی به آن اضافه می کنیم. سپس آن را به stage اضافه و در نهایت commit می کنیم:
در مرحله بعد فایل .gitignore را توسط VSCode باز کنید و عبارت node_modules/ را در آن تعریف کنید.
سپس دستور git ls-files را برای مشاهده فایل های داخل stage اجرا کنید. مشاهده می کنید که فولدر node_modules در stage قرار دارد. اما ما می خواهیم این فولدر از stage حذف شود. کافیست دستور git rm –cached -r node_modules را مطابق تصویر زیر اجرا کنید:
با اینکار کل فولدر node_modules از stage خارج شدند. با اجرای دستور git ls-files مطمئن شوید
حالا اگر برای مشاهده وضعیت stage دستور git status را اجرا کنید خواهید دید که فولدر node_modules از stage پاک شده است و منتظر کامیت ماست:
در مرحله آخر برای اینکه چک کنیم که آیا فولدر node_modules بدرستی توسط گیت ignore می شود تغییراتی در آن ایجاد می کنیم و status را می بینیم:
مشاهده می شود که تغییرات داخل فولدر node_modules از طرف گیت نادیده گرفته یا ignore می شود و فقط می گوید فایل gitignore. تغییراتی داشته که باید در stage ذخیره شود. در نهایت دستور git add .gitignore را اجرا کنید تا این فایل به stage اضافه شود.
مشاهده وضعیت stage:
می خواهیم یکی دیگر از قابلیت های گیت را شرح دهیم. ابتدا دستورات زیر را برای ایجاد تغییر در فایل های file1.js و file2.js اجرا کنید:
در مرحله بعد ابتدا دستور git status و سپس دستور git status -s را اجرا کنید
همانطور که ملاحظه می کنید، گیت با اجرای status -s وضعیت خلاصه تر و کوتاه تری ارائه می دهد. فایل file1 چون از قبل در پروژه موجود بود بعنوان modified برچسب گذاری شده است و فایل file2.js چون جدید است بعنوان untracked files شناخته شده است. در گزارش وضعیت خلاصه یا short status دو ستون در کنار نام هر فایل می بینیم. در کنار نام فایل file2 دو علامت سوال درج شده که بیانگر اینست که این فایل جدید است و در stage اضافه نشده است. اما در کنار فایل file1.js یک M قرمز رنگ قرار دارد. ستون سمت راست بیانگر وضعیت آن فایل در فولدر پروژه است و ستون سمت چپ بیانگر وضعیت فایل در stage است. به این ترتیب در تصویر بالا، محتوای فایل file1 در فولدر پروژه تغییر کرده است (Modified) اما به stage اضافه نشده است. و فایل file2 چون یک فایل جدید است دو تا علامت سوال دارد. فایل gitignore هم یک M سبزرنگ در ستون stage دارد یعنی به stage اضافه شده است.
حالا می خواهیم تغییرات فایل file1 را توسط دستور git add file1.js به stage منتقل کنیم. سپس یک تغییر در همین فایل اعمال کنیم.
مشاهده می کنید که در کنار نام فایل file1.js دو M با رنگ های سبز و قرمز قرار دارد. M قرمز بیانگر اینست که تغییراتی روی فایل file1 در پروژه رخ داده که هنوز به stage اضافه نشده اند. M سبز هم نشانگر اینست که بخشی از تغییرات فایل file1 در stage ثبت شده است. حالا می توان با دستور git add file1.js تغییرات جدید این فایل را وارد stage کنیم (تصویر زیر)
در مرحله بعد نوبت به بررسی فایل file2 می رسد. اگر دستور git add file2.js را اجرا کنیم، مطابق تصویر زیر، یک حرف A سبزرنگ در کنار نام این فایل درج می شود:
فایل file2 چون یک فایل جدید است و قبلا در stage وجود نداشته، با دستور git add به stage اضافه یا Add می شود. حرف A هم ابتدای کلمه Added است. اما فایل file1 چون از قبل وجود داشته و تغییرات جدیدش به stage منتقل شده، با حرف M سبز رنگ، به معنای Modified مشخص شده است.
مشاهده تغییرات فایل ها در stage:
دستور git status فقط نام فایل هایی که به stage اضافه شده اند یا هنوز اضافه نشده اند را به ما نشان می دهد. اما برای اینکه بتوان تغییراتی که هر فایل داشته را ببینیم، باید دستور git diff –staged را اجرا کنیم:
این دستور تغییرات هر فایل را با ورژن قبلی خودش مقایسه می کند. بعنوان مثال در خط diff –git a/file1.js b/file1.js بخش a/file1.js یعنی محتوای فایل file1 در آخرین کامیت، و بخش b/file1.js یعنی محتوای فایل file1 در stage فعلی.
در بررسی کدهای مربوط به فایل file2، بدلیل اینکه این فایل جدید بود، لاین /dev/null را داریم.
نکته: برای مشاهده تغییراتی که هنوز stage نشده اند، و فعلا در working directory قرار دارند، دستور git diff را بدون هیچ آرگومانی اجرا می کنیم.
در ادامه آموزش می خواهیم از نرم افزار VSCode برای مشاهده و مقایسه تغییرات فایل ها در گیت استفاده کنیم.
تعریف ویژوال استودیو کد بعنوان ادیتور پیش فرض برای مشاهده git diff:
به منظور تعریف نرم افزار ویژوال استودیو کد بعنوان ابزار پیش فرض git diff کافیست دستور زیر را اجرا کنید:
git config --global diff.tool vscode
سپس باید گیت را تنظیم کنیم که چگونه ویژوال استودیو را لانچ کند. دستور زیر را تعریف کنید:
git config --global difftool.vscode.cmd "code --wait --diff $LOCAL $REMOTE"
حال برای اینکه مطمئن شویم تنظیمات فوق بدرستی انجام شده اند دستور زیر را اجرا کنید تا فایل کانفیگ گیت در ویژوال استودیو باز شود:
فایل gitconfig. را با دقت بررسی کنید. زیرا باید مطابق تنظیمات فوق باشد. اگر عبارات $LOCAL $REMOTE حذف شده است آنها را بصورت دستی اضافه کنید:
اکنون به git bash بر می گردیم و یک تغییر کوچک در فایل file1.js اعمال می کنیم. سپس دستور git difftool را برای مقایسه تغییرات موجود در دایرکتوری پروژه و stage اجرا می کنیم:
در آخر از ما می پرسد آیا می خواهید Diff را در VScode مشاهده کنید یا خیر؟ ما باید حرف y را تایپ کرده و اینتر کنیم. حالا ویژوال استودیو باز می شود و تغییرات قابل مشاهده هستند.
ستون سمت راست بیانگر تغییرات در فولدر پروژه است و ستون سمت چپ تغییرات stage شده. مشاهده می شود که در لاین 6 یک کلمه test در پروژه اضافه شده است که هنوز به stage اضافه نشده است.
نکته: این روزها بندرت از Diff Tools استفاده می شود زیرا اغلب IDE و ادیتورها این امکان را دارند که با نصب یک extension وضعیت گیت و تغییرات فایل ها و فولدرهای پروژه را بصورت بصری و زیبا به ما نمایش دهند.
مشاهده تاریخچه کامیت ها یا Commit History:
با دستور commit آشنا شده ایم اما این کامیت ها و پیغام آنها کجا ثبت می شوند و چطور می شود لیست آنها را مشاهده کرد؟
کافیست دستور git log را اجرا کنید:
مشاهده می کنید که هر کامیت چند فیلد دارد: آیدی، نام یوزر، ایمیل یوزر و تاریخ و ساعت کامیت. دستور git log را می توان به روش های گوناگونی اجرا کرد:
git log –oneline برای مشاهده commit های انجام شده در یک خط:
ملاحظه می فرمایید که کامیت های ما به ترتیب آخرین کامیت به اولین کامیت لیست شده اند.
برای اینکه بتوان کامیت ها را بر اساس اولین به آخرین مرتب سازی کرد کافیست reverse را به دستور فوق اضافه کنیم. یعنی:
git log --oneline --reverse
مشاهده جزئیات یک Commit:
در بخش قبل دیدید که هر کامیت یک آیدی یکتا دارد که 7 کاراکتری است. برای مشاهده یک کامیت خاص می توان دستور git show a55c453 را اجرا کرد. عبارت آخر آیدی کامیت موردنظر است.
همچنین می توان برای رسیدن به commit موردنظر (مثلا سومین کامیت از آخر) از HEAD استفاده کرد. به این شکل که دستور git show HEAD~2 را اجرا کنیم. یعنی از آخرین کامیت که نشانگر HEAD روی آن قرار دارد دو تا به عقب برود.
حالا برای اینکه ببینیم در یک کامیت مشخص محتوای فایل موردنظرمان چه بوده کافیست دستور زیر را اجرا کنیم:
git show HEAD~2:file1.js
نحوه خارج کردن یک فایل از stage یا unstage:
فرض کنید بنا به دلایلی می خواهیم تغییرات stageشده فایل file1.js را از stage خارج کنیم (یا unstage کنیم). دستور git restore –staged file1.js تغییرات فایل file1 را از stage خارج می کند و در همان فولدر پروژه نگه میدارد.
با اجرای git status -s تغییرات فایل file1.js از مرحله stage حذف شدند و مجددا به working directory برگشتند (M قرمز رنگ در ستون سمت راست)
نکته: برای اینکه تغییرات یک فایل را در working directory نیز حذف کنیم و به آخرین کامیت برگردانیم، دستور git restore file1.js را اجرا کنید.
بازگرداندن فایل حذف شده:
برای شبیه سازی سناریوی حذف، دستور git rm file1.js را اجرا کنید. سپس با دستور git status -s از صحت کار خود مطمئن شوید، در نهایت آن را کامیت کنید:
اکنون نگاهی کوتاه به commit های انجام شده تا الان می اندازیم. توسط دستور git log –oneline
در واقع ما می خواهیم فایل file1 به آخرین کامیت یعنی f8c038f بازگردد. کافیست دستور git restore –source=HEAD~1 file1.js را اجرا کنید:
بنابراین توانستیم فایل file1.js را به کامیت یکی مانده به آخر برگردانیم.
در جلسه بعد نحوه Commit تغییرات در گیت را بطور مفصل آموزش خواهیم داد. همراه ما باشید…!
دیدگاهتان را بنویسید