پزشکی که از پنج سال پیش حس کرد اگر به حوزه ی طراحی محصول ورود کنه تعداد بیمار خیلی بیشتری رو میتونه درمان کنه.
📄 مفاهیم برنامهنویسی به زبان ساده – Git
من چند ماهی هست که با کمک ابزارهای Vibe coding دارم محصول نرمافزاری میسازم. نمونهاش همین سایت jibilib که کارش خلاصه کردن کتابهاست.
ابزارهایی مثل Google AI Studio و Cursor به من کمک میکنن که فقط توضیح بدم چی میخوام، و اونها خودشون کدش رو مینویسن.
اما باز هم یه سوال مهم مطرح میشه:
آیا دیگه لازم نیست مفاهیم برنامهنویسی رو یاد بگیریم؟
به نظرم برای Syntax و جزئیات زبانی، خیلی وقتها نیاز نیست. ولی برای مفاهیم بنیادی مثل API، نه تنها لازمه بلکه فهمش باعث میشه بتونی هوش مصنوعی رو درست هدایت کنی. در یادداشت های قبلی روی مفهوم Cookie و API به زبان ساده صحبت کردیم و این بار میخوایم درباره ی گیت صحبت کنیم. چیزی که احتمالا بارها اسمش رو شنیدین.
گیت اصلا چیه؟
همه چیز برمیگرده به سال ۲۰۰۵، زمانی که لینوس توروالدز (این مرد پرده نشین و بی سر و صدایی که اگر نگیم خفن ترین، یکی از خفن ترین افراد تاریخ نرم افزار و همون کسیه که لینوکس رو هم ساخته) با یک مشکل بزرگ مواجه شد:
تیم بزرگی از برنامهنویس ها روی کرنل لینوکس کار میکردند، اما سیستم مدیریت نسخهای که داشتند، کند و محدود بود و هرکس داشت یک گوشه ای از نرم افزار رو جلو میبرد و کدهایی که میزد رو با کدهای بقیه ترکیب میکرد اما نظم کافی وجود نداشت. لینوس مثل یک سرآشپز توی یک آشپزخونه ی بزرگ بود که هر کس داشت یه کاری میکرد و یک سری مواد میریخت توی غذای نهایی اما کسی به اندازه ی کافی دقیق نمیدونست کی چه چیزی اضافه کرده و اگر غذا خراب شد دقیقا چی باعثش شده!
بنابراین تصمیم گرفت خودش یک نرمافزار سریع و هوشمند بسازه که هر تغییری رو دقیق ثبت کنه،ادم ها بتونن همزمان روی یک پروژه کار کنند و هیچ تغییر مهمی گم نشه.
نتیجه شد Git: مثل یک دفترچه دیجیتال برای پروژهها، که هم سریع هست، هم غیرمتمرکز، و اجازه میده تیمهای بزرگ با خیال راحت کنار هم کار کنن.

شما هر محصولی که بخواید توسعه بدید و یکمی جدی بشه به زودی به این مفهوم و نرم افزار نیاز پیدا میکنین چون ورژن های مختلف کد نرم افزاری دارید که باید بتونین بین شون تمایز قایل بشید و اگر کار خراب شد برگردید به اون نسخه ای که درست کار میکرد. من خودم زمانی که تازه یاد گرفته بودم محصول بسازم و مفهوم گیت رو نفهمیده بودم میومدم هر n ساعت یک بار کد رو دانلود میکردم و با ساعتی که دانلود شده بود نامگذاری میکردم. این هم اسکرین شاتش هست. واقعا خودم از این عکس خجالت زده ام اما میخوام نشون بدم که اگر گیت نباشه چه بلایی سر ادم میاد. حالا فکر میکنین من چندبار تونستم از این فولدر استفاده کنم؟ فقط یک بار. چرا؟ چون اصلا معلوم نبود چه خط کدی تو هر کدوم چی نوشته شده و فقط به یک درد میخورد. اونم به این درد که اگر محصول به فنا رفت بتونم لااقل برگردم به یک محصول Stable. یا بهتره بگم نسبتا Stable!

بریم سراغ توضیح دادنش. طبق معمول من مفهوم رو اول با یک مثال غیر فنی و در دنیای واقعی توضیح میدم.
بیاید فرض کنیم یک خانواده ای داریم که به خیلی از غذاهای دنیا حساسیت دارند و وقتی میخورنش مسموم میشن. این خانواده سه نفره (مادر، پدر و دختر) تصمیم میگیرن که بیان یک لیستی از غذاهایی که میتونن بخورن رو تهیه کنن که اگر یکی شون مسموم شد لااقل بقیه نشن. یا اگر یکی یک غذایی توی لیست دید که خوردنش اوکیه و مشکلی پیش نمیاد با خیال راحت بخوره. مادر میشه مسوول این کار و سه تایی کار رو شروع میکنن.
مادر میگه که من یدونه جعبه میذارم توی آشپزخونه که توش یک سری برگه هست. هربرگه مخصوص یک غذا هست و هرکس هر تجربه ای درباره اون غذا داره رو میاد اونجا مینویسه. مثلا یک کاغذ میذاریم و بالاش مینویسیم قرمه سبزی! هرجا که قرمه سبزی خوردید تجربه تون رو میاید مینویسید. مثلا میگید قرمه سبزی با لوبیا چیتی خوردم و مسموم نشدم و اوکی بود. یا مینویسید قرمه سبزی با لوبیا قرمز خوردم و مسموم شدم.
یک برگه دیگه داریم مخصوص پیتزا. مثلا مینویسید من پیتزا استیک خوردم مسموم شدم اما پیتزا مارگاریتا اوکی بود.
به اون جعبه میگیم Repository! مخزنی که همه چی اون تو هست.
این مخزن یک سری برگه (معادل فایل های پروژه ی نرم افزاری) داخلش هست. هر برگه رو میگیم یک فایل که داخل اون Repo (مخفف Repository) گذاشته شده.
حالا هرکس که میاد یک اطلاعات جدیدی توی اون ریپو اضافه کرده میگیم که یک Commit انجام داده. کامیت یعنی ثبت کردن. (یجور Commitment و تعهد هم هست که انگار من متعهد میشم به این تغییراتی که دادم)
بعد یه مدت چی شد؟ اعضای خانواده تصمیم گرفتن که هرکس توی محل کار یا دانشگاه و … هست همون موقع چیزهایی که میخوره رو دقیق روی کاغذ ثبت کنه که تا شب که برمیگرده خونه این همه گزارش و تغییر رو یکجا ننویسه که دقت کار بالا بره. وگرنه خیلی بی دقت و با خطا کار پیش میره. پس هرکسی صبح ها میومد از فایل های اون جعبه ی توی آشپزخونه یک کپی میگرفت میذاشت توی کیفش، هرچیزی میخورد رو توی همون کپی ها ثبت میکرد، بعدش وقتی میرسید خونه میرفت توی اون جعبه تغییرات رو ثبت میکرد. معنی اینکه هرکس یک نسخه ی شخصی از اون جعبه داره میشه چی ؟ Local repo! و معنی کپی کردن کل فایل های اون جعبه و برداشتن یک نسخه ی کپی از اون برای خود آدم میشه چی؟ Clone کردن یک ریپو.
بعدش یه اتفاقی افتاد. اومدن گفتن بیاید یه کاری کنیم. دختر خانواده تمرکز کنه روی تست کردن غذاهای فست فودی و پدر متمرکز بشه روی غذاهای سنتی. اینطوری هرکس میتونه به صورت تخصصی تری غذاها رو تست و ثبت کنه. ولی یک مدت توی مخزن اصلی هم که میگذاره بذاره اون گوشه ی جعبه که با فایل های دیگه قاطی نشه و وقتی مطمئن شد همه چیز اوکیه بذاره روی فایل های دیگه. به این کار میگن Branch گرفتن از پروژه.
مثال واقعی فنیش این میشه که مثلا من مسوول فیچر پروفایل هستم که توسعه بدم و شما مسوول فیچر Search bar. من یک شاخه از اون پروژه رو میگیرم، روش کارهام رو میکنم، تست میکنم و …. اگر دیدم استیبل هست و … تازه میام Merge میکنم با اون پروژه ی اصلی. اینطوری با اطمینان بیشتری میتونیم بگیم که پروژه ی اصلی مون (Main or Master) آسیبی نمیبینه و از تست و خطاهای ماها در امانه.
پس تو همین مثال مفهوم Merge کردن، Branch گرفتن و شاخه ی Main یا Master رو هم فهمیدیم.
یه روز یه اتفاقی میفته! مادر میاد فایل های توی جعبه ی اصلی رو بررسی کنه میبینه که اوه اوه! یکی اومده نوشته پیتزا مارگاریتا خوردم و اوکی بود و یکی دیگه نوشته پیتزا مارگاریتا خوردم و مسموم شدم! به این حالت میگیم Conflict خوردن. توی این حالت باید بررسی کنیم، شرایط رو بسنجیم و یکی رو انتخاب کنیم که درسته و اون یکی غلطه. گیت اینجا خیلی به کار میاد. میاد میگه اگر یکی اومده توی فایل قرمه سبزی چیزی نوشته و یکی دیگه توی فایل پیتزا و هردوتا شب میان اون گزارش هایی که توی کیف خودشون گذاشته بودن رو اضافه کنن به مخزن اصلی من خودم مدیریت میکنم و اوکیه. حتی اگر یکی بیاد درباره ی سس پیتزا چیزی بگه و یکی درباره ی نان پیتزا بازم اوکیه. اما اگر فرض کنیم پدر و دختر به صورت اتفاقی امروز پیتزا پستو خوردند و هردو نفر بیان دقیقا در مورد سس پستو (یک نکته ی مشترک) پیتزا چیزهای متفاوتی بگن (توی مثال کد میشه دوتا کد مختلف دقیقا در یک خط مشترک از فایلی که توش کد خاصی نوشته شده) وقتی که میخوان این تغییرات رو بفرستند روی مخزن اصلی من ارور میدم و میگم Conflict پیش اومده. درستش کنید.
مادر یک کار دیگه هم میکنن. میگن ازین به بعد برای اینکه مطمئن بشیم که چیز اشتباهی وارد مخزن اصلی توی آشپزخانه نمیشه هرکس که توی فایل های شخصیش (Local Repo) هرکاری کرد اوکیه اما وقتی میخواید بیاید اون تغییرات ریپوی شخصی (لوکال) تونو توی مخزن اصلی بفرستین (Push کنید) باید به من بگید و حق ندارید خودتون این کار رو بکنید. من میام بررسی میکنم مشکلی نباشه و اگر اوکی دادم خودم میبرم میذارمش قاطی بقیه فایل ها (Merge) توی جعبه ی اصلی. اگر اوکی نبود بهتون خبر میدم مشکلاتش رو اصلاح کنید و دوباره بهم درخواست اضافه شدن اون تغییرات به جعبه اصلی رو بدید. به این کار میگن Pull Request! یعنی برنامه نویس ها به Project Owner / Maintainer درخواست میدن (Pull Request)، صاحب پروژه اون بررسی میکنه و اگر اوکی بود و تایید کرد Merge میشه به مخزن اصلی.
مادر خانواده یک استراتژی هم دارند واسه اینکه مطمئن بشن مخزن تمیز و درسته. اون چیه؟میگن هرچیزی که میخورید رو همون موقع کامیت کنید تو نسخه ی شخصی تون و یک دفعه همزمان چندتا غذا رو با هم ننویسید. چرا؟که اگر مسموم شدید من بتونم بررسی کنم ببینم چه زمانی مسموم شدید و اون زمانی که مسموم شدید دقیقا قبلش کدوم غذا رو خورده بودید و بتونم دقیق بفهمم کدوم غذا باعث مسمومیت تون شده. اگر چندتا غذا رو همزمان ثبت کنید من نمیتونم بفهمم علت مسمومیت کدوم یکی از این ها بوده. وقتی هم که یک غذا رو نصفه خوردید کامیت نکنید. چون ممکنه در اون لحظه اوکی باشه اما یکمی بعدش مسموم بشید. برای همینه که میگن زیاد کامیت کنید و بعد از هر تغییر معنی دار در برنامه نویسی کامیت کنید. اما اگر تغییراتی که میدید هم هنوز معنی دار نیست بهتره فعلا کامیت نکنید که مشکلی پیش نیاد. ممکنه بگید آقا من میخوام یه چیزی رو سریع یه جا نگه دارم و حالا وقتی مطمئن شدم کامیت کنم. چکار کنم؟میگیم Stage ش کن. استیج میشه دقیقا زمانی که تازه یک تغییری رو میخواید کامیت کنید اما هنوز کامیت نکردید که حالا یا تست بیشتر کنید یا منتظر یه چیز دیگه اید. یه جور برگه ی نوشته شده رو میز که وقتی قطعی شد میذارید توی فایل هاتون.
حالا تفاوت Push, Pull, Fetch رو بگم (هرچند بخشیش رو قبلا گفتم) که کنار هم ببینیدشون.

اگر من صبح که میخوام برم سرکار کل مخزن رو (شامل همه ی فایل ها و کامنتهایی که کنارش هرکی ممکنه گذاشته باشه)کپی کنم ببرم میشه Clone کردن. وقتی که شب برمیگردم میخوام تغییرات لوکالم رو بفرستم (هل بدم) توی مخزن اصلی (که بهش مخزن ریموت هم میگن) میشه Push کردن. اگر یه لحظه در مخزن رو باز کنم یه نگاه سریع به محتویاتش بکنم ببینم چی به چیه اما چیزی رو کپی نکنم و درش رو ببندم میشه Fetch کردن. اگر در مخزن رو باز کنم که ببینم چی به چیه (Fetch کردن) ببینم که یکی اومده یه تغییری توی فایل پیتزا داده بذار من اون تغییرات رو Merge! کنم با نسخه ی لوکال خودم میشه Pull کردن.
Pull = Fetch + Merge
پس Pull کردن همیشه با Merge همراهه (میکشی میاری میریزی تو نسخه ی خودت) اما Fetch کردن در حد یه نگاه سریع و فضولیه و Merge ی در کار نیست.
حالا یه چیز دیگه! فکر نکنید که هر تغییری داده میشه توی مخزن اصلی قبلی ها میپره. فرق دنیای دیجیتال با کاغذی اینه که تمام نسخه های قدیمی نگه داشته میشن به همراه تاریخ اضافه شدن یا کم شدن شون از مخزن. انگار که هر تغییری داده میشه یک دونه به دونه های تسبیح با تاریخ و کامنت و تگ های احتمالی اضافه میشه و همیشه ثبت میمونه. ببینین چه تسلطی به مادر به عنوان صاحب اون پروژه میده و اگر بعدا مشکلی پیش بیاد دقیقا میتونه بره ببینه کی چه چیزی رو به چه فایلی در چه تاریخی اضافه یا کم کرده بوده که باعث اون مشکل شده. گیت این کار رو عالی انجام میده. حتی میتونه یک باگی که پیش اومده رو بهش بگی و بگی از بازه ی فلان تاریخ تا فلان تاریخ مشکل ایجاد شده و قبلش اوکی بوده. خودش میره دونه دونه برات تغییرات رو نگاه میکنه اون فایل مخصوص که مشکل از اونجا سرچشمه گرفته رو نگاه میکنه میبینه که چه زمانی و توسط چه کسی تغییری که باعث باگ شده ایجاد شده بوده و اینطوری دقت به راهه، سرعت به راهه و همه چیز به راهه…
و نکته ی نهایی! اگر یک روز عمو و خاله مون بیان خونه مون و بگن دقیقا ما هم همین بیماری رو داریم چه کار باحالی کردید اگه میشه بذارید ما هم از این استفاده کنیم فقط یه جاهاییش رو میخوایم طبق صلاحدید خودمون تغییر بدیم چکار میکنین؟ میگین اوکی! بیا یه کپی از همین بگیر و ببر از اینجا به بعد هرمسیری که میخوای رو در ادامه اش پیش ببر. به این میگیم Fork گرفتن از پروژه. حالا اگر عمو و خاله Fork گرفتن و دیدن خیلی باحال شد و خواستن به شما پیشنهاد بدن شما هم همین تغییرات رو توی نسخه ی اصلی تون بدید یه درخواست Pull Request میدن، مادر بررسی میکنن و اگر صلاح دیدین اون درخواست رو قبول میکنن و اون تغییرات رو Merge میکنن با مخزن آشپزخونه ی اولیه.
مخزن ریموت چیه؟ همون اصلی (که لوکال نیست). مخزن لوکال اونیه که هرکس تو کیف خودش داره. ریموت اون اصلیه هست که اخرش لوکال ها رو میریزیم توش.
گیت هاب و گیت لب چی هستند؟ میگن نمیخواد واسه هر پروژه ای برید سرور بگیرید گیت پروژه تون رو روی اون سوار کنید. ما بهتون فضا میدیم و میتونین ریپو (جعبه ی توی اشپزخونه تون) رو همونجا راه بندازید و به تیم تون دسترسی بدید.
الان هم که کلی ریپو ی Open Source روی هردوشون هست و میشه رفت کلی محصول جالب رو پیدا کرد، Fork گرفت ازشون، توشون مشارکت هست، بهشون ستاره داد ( لایک کردن ادم های فنی و باکلاس میشه ستاره دادن تو گیت هاب و گیت لب) و …
تمام! ایشالا که به کارتون بیاد. اگر دارید با AI کد میزنید و خوشحالید و مفاهیم فنی رو نمیدونین مراقب باشین بچه ها. AI کارگره! سرکارگر اگه نفهمه چی به چیه و کارگر چکار داره میکنه ساختمون به فنا میره.
دم امیررضا عاشوری عزیز و جادی عزیز گرم. خیلی کمکم کردن برای یاد گرفتن گیت.
چندتا منبع خوب که امیررضا لطف کرد بهم معرفی کرد:
https://www.youtube.com/playlist?list=PLwSYhER2SPaOQ5MMh29DqpYbpExXthlqW
مطلبی دیگر از این انتشارات
تکنیکهای ساده خواندن SMS برای توسعهدهندگان اندروید
مطلبی دیگر از این انتشارات
دستور If در sql
مطلبی دیگر از این انتشارات
چی شد که این شد!