در این آزمایش ما یک صفحه ماشین حساب با چهار عمل اصلی طراحی کردیم که در این لینک قابل مشاهده است:
در شکل زیر ساختار کلی پروژه را مشاهده میکنید. ما دو تا branch اصلی داریم: main
که فرایند اسقرار محصول روی آن انجام میشود و staging
که تغییرات را ابتدا روی آن مرج کرده، تست میکنیم و سپس با pull-request
روی main
مرج کرده و فرایند استقرار بصورت خودکار انجام میشود. بقیه branch ها هم با فرمت feature/[FEATURE_NAME]
برای ویژگی جدید و یا fix/[FIX_TYPE]
برای حل مشکلی از یک ویژگی در نظر گرفته شده است.
همچنین فایل gitignore.
برای جلوگیری از push شدن فایلها و فولدرهای local در نظر گرفته شده است:
برای حالت conflict هم زمانیکه میخواستیم شاخه feature/calculator-functions
را یه staging
مرج کنیم پیش آمد که با استفاده از viewer خود github آن را resolve کردیم.
در شکلهای زیر چند نمونه از دستوراتی که استفاده کردیم را نشان دادیم:
همچنین برای محافظت از شاخه main
یک ruleرا اضافه کردیم تا هیچ کس حتی administrator نتواند مستقیما به آن پوش کند.
برای آن گزینههای Require a pull request before merging
و Do not allow bypassing the above settings
را فعال کردیم.
بعد از آن نتوانستیم مستقیما به main
پوش کنیم:
برای افزودن قابلیت به main
و staging
از pull request استفاده کردیم و بعد از review و approve آن را مرج کردیم.
برای استقرار محصول در github pages از workflow های آماده استفاده کردیم. در آن آدرس root پروژه و شاخهای که باید روی صفحه مستقر شود را مشخص میکنیم.
آدرس جایی که محصول مستقر میشود هم بعدا نشان داد:
بعد از آن با هر push روی main
اکشن مربوطه اجرا میشد.
- پوشهی
git.
چیست؟ چه اطلاعاتی در آن ذخیره میشود؟ با چه دستوری ساخته میشود؟
این پوشه شامل همه پیکربندیهای مورد نیاز گیت است. در بخش زیر به تعدادی از آنها اشاره میکنیم:
- مورد اول
head
: برای دنبال کردن آنچه در شاخه فعلی اتفاق میافتد. - مورد دوم
refs
: ذخیره سازی ارجاعات به شاخهها و کامیتها. - مورد سوم
objects
: ذخیره سازی codebase به شکل دنبالهای از snapshot ها. - مورد چهارم
config
: ذخیره سازی اطلاعات پیکربندی مختص گیت. - مورد پنجم
hooks
: اجرای اسکریپت برای نقاط خاصی در workflow مربوط به گیت.
- منظور از atomic بودن در atomic commit و atomic pull-request چیست؟
در commit معنی atomic این است که همه تغییرات در یک commit باید باهم اتفاق بیفتند؛ این به این معنی است که اگر یک تغییر در commit با مشکل مواجه شود، هیچکدام از تغییرات commit اعمال نمیشوند.همین اصل برای pull-request هم وجود دارد؛ در واقع pull-request هم مجموعهای از commit ها است و در صورتی که یک commit به مشکل بخورد، pull-request به خطا میخورد.
- تفاوت دستورهای
fetch
وpull
وmerge
وrebase
وcherry-pick
را بیان کنید.
در قسمتهای زیر به بیان تعریف و تفاوت آنها میپردازیم:
- در
merge
یک commit ایجاد میشود که تفاوت بین شاخه مقصد با شاخه فعلی را بیان میکند. - در
rebase
تغییرات یک شاخه را در شاخه دیگر merge می کند، تاریخچه مربوط به شاخه را خطی می کند و از merge های غیر ضروری اجتناب می کند. بنابراین برخلافmerge
هیچ commit ای برای این تغییرات ایجاد نمیکند. - در
cherry-pick
بر خلاف دو مورد قبلی برای مواردی استفاده میشود که به تنها چند commit از شاخه دیگر نیاز دارد؛ یعنی میتوانیم از شاخه دیگر، چندتا commit انتخاب کنیم و آن را به شاخه فعلی merge کنیم؛ بدون آنکه کل شاخه را merge کنیم. - در
fetch
تغییرات شاخه را از remote repository به local میآورد ولی آن را به شاخه merge نمیکند. - در
pull
عملیاتfetch
وmerge
از remote branch به شاخه local انجام میدهد.
- تفاوت دستورهای
reset
وrevert
وrestore
وswitch
وcheckout
را بیان کنید.
- در
reset
ما working directory را به commit مشخصی rollback میکنیم؛ به این شکل که شاخه فعلی را به آن حالت برگردانده و commit ها از آنجا به بعد حذف میشوند. این مورد برای حذف تغییراتی که commit نشدند، مناسب است. - در
revert
بر خلافreset
برای rollback تغییرات commit هم ساخته میشود و آن تغییرات را بیان میکند. این مورد برای rollback کردن تغییرات commit شده مناسب است. - در
restore
ما به منظور بازیابی فایلهای working tree از index یا commit مشخص از این دستور استفاده میکنیم. این دستور branch را آپدیت نمیکند. همچنین میتوانیم برای بازیابی فایلها از index مربوط به commit دیگر استفاده کنیم. - در
switch
ما برای جابجایی و ایجاد branch جدید از آن استفاده میکنیم. محدودیتی که نسبت بهcheckout
دارد این است که اگر تغییری در فایل tracked داشته باشیم ابتدا باید آن راstash
یاcommit
کنیم و سپس بین branch ها جابجا شویم؛ در غیر اینصورت به خطا میخوریم. - در
checkout
چندین کار همزمان انجام میشود و اگر حواسمان نباشد ممکن است به مشکل بخوریم. در واقع میتوانیم بین branch های مختلف جابجا شویم و branch های جدید بسازیم. همچنین اگر تغییراتی در فایلهای tracked داشته باشیم به ما این اجازه را میدهد تا switch کنیم و ممکن است در commit کردن تغییرات مربوط به branch جدید دچار خطا شویم.
- منظور از
stage
یا همانindex
چیست؟ دستورstash
چه کاری را انجام میدهد؟
منظور از stage
همان محیطی است که تغییراتی که میخواهیم commit کنیم در آن قرار میگیرد و به ما این قابلیت را میدهد که چه تغییراتی را برای commit در نظر بگیریم. دستور stash
بصورت موقت آن تغییرات را در محیط local ذخیره میکند تا ما بتوانیم کار دیگری انجام دهیم (یکی از کاربردهای استفاده آن در switch
بود که در سوال قبل اشاره شد). هر زمانی که به آن تغییرات نیاز داشتیم، میتوانیم با git stash pop
آن را از حالت stashed خارج کنیم.
- مفهوم snapshot به چه معناست؟ ارتباط آن با commit چیست؟
به معنی وضعیت یک چیز (مثلا فایل یا فولدر) در زمان مشخصی است؛ یعنی چه کسی چه تغییری را در کدام قسمت آن ایجاد کرده است و ... . در واقع هر commit دارای یک snapshot از کل وضعیت repository تا به آنجا است؛ بجای آنکه فقط تغییرات جدید را ذخیره کند. به عبارتی !commits are snapshots, not diffs
.
- تفاوتهای local repository و remote repository چیست؟
اگر یک تیم با local repository کار کند، پروژه فقط در سیستم اعضای تیم است؛ در حالیکه remote repository در سروری روی اینترنت یا شبکه داخلی مستقر میشود که برای همه اعضای تیم قابل دسترس است.