logo-mini
معرفی source controlها و لزوم استفاده از آنها

معرفی source control ها مانند GIT و SVN – لزوم استفاده از آنها

به اشتراک گذاری این پست

معرفی source control ها مانند GIT و SVN – لزوم استفاده از آنها

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

حال این راه حل چه مشکلاتی می تواند داشته باشد؟ خب اولین مشکل این که شما دو تا پروژه دارید یا از یک پروژه دوتا نسخه دارید حالا چطوری اینها را یکی کنید که بتوانید نتیجه کار دو نفره را نشان دهید؟ خب برای این هم یکی از شما یا هردوی شما باید یکی دو ساعت وقت بگذارد و تغییرات هر دو را اعمال کند و یک پروژه واحد را بسازد. حالا برای این کار باید بر روی کارهایی که از دوطرف اعمال شده کاملا مسلط باشد. به شما قول می دهم که این کار بسیار خسته کننده خواهد بود. برای مثال اگر خطایی پیدا شود چه مشکلی پیش خواهد آمد؟ اگر یکی از شما مسئول UI باشید و یکی دیگر مسئول کد backend باشد چه؟ با تخصصی شدن کار ها استفاده از این روش سخت خواهد بود. مشکل دیگری که ممکن است پیش بیاید این است که تصور کنید که نام پروژه شما MyProject است.

حالا شما تغییراتی را بر روی پروژه انجام می دهید و شاید در قالب این تغییرات کدهایی را حذف کنید. ولی برای این که کد قبلی را هم داشته باشید که اگر مشکلی پیش آمد آن را دوباره برگردانید پروژه را در یک پوشه دیگر به نام MyProject2 ذخیره می کنید. بعد از یک مدت خواهید دید که چند تا پوشه MyProject دارید که پسوند عددی مختلف دارند و یا پسوند تاریخ دارند. حال ببینید که چه حجمی از فضای شما اشغال می شود. اینجاست که اگر بخواهید به دنبال کدی بگردید باید بگوییم پیدا کنید پرتقال فروش را .... 


شاید شما بگویید که خب من که تنهایی بر روی یک پروژه کار می کنم و با کسی روی پروژه کار نمی کنم پس مشکلی برایم پیش نمی آید. ولی اینطور نیست. اگر شما تنها بر روی یک پروژه کار می کنید و دوست یا تیمی ندارید باز به مشکل برمی خورید. در نظر بگیرید که شما در حال کار بر روی پروژه هستید. بعد از یک مدت به این نتیجه می رسید که راهی که رفته اید اشتباه بوده و از یک مرحله از پروژه باید با یک روش دیگر پیش می رفته اید. در این صورت باید کارهایی را که انجام داده اید را به طور دستی حذف کنید و تغییرات جدید را اعمال نمایید. که این کار هم به وقت نیاز دارد و باعث می شود که پیشرفت پروژه کم شود. و یا اگر خود شما بر روی دوعدد کامپیوتر مشغول برنامه نویسی هستید. برای مثال هم در خانه بر روی پروژه کار می کنید و هم سرکار بر روی پروژه کار می کنید مشکلاتی در کار با فلش و سی دی و .... برای شما پیش خواهد آمد. حال اگر برای هارد شما مشکلی پیش بیاید و یا لپتاپ شما دزدیده شود آن وقت است که باید فریاد از دل برآورید. برای حل این مشکلات در کار های تیمی و حتی کار های شخصی از version control و یا source control استفاده می شود. 

 

Source Control چیست؟


سورس کنترل یک مکانیزمی است که امکان می دهد که یک پروژه بر روی آن قرار گیرد و تغییرات در آن مدیریت شود و همچنین سورسی که بر روی آن است مدیریت شود. به شکلی که همه ی تغییرات بر روی پروژه را به صورت بهینه ای در خود نگهداری می کند و این قابلیت را دارد که هر وقت یک مجموعه تغییرات بر روی پروژه اعمال شد آن را در یک رکورد ذخیره می کند و تغییرات فایل ها را اعمال می کند و همچنین امکان قرار دادن کامنت و توضیحات را نیز می دهد که اعضای تیم یا خود شخص متوجه بشود که در تغییری که ایجاد شده است کدام فایل های تغییر کرده اند و کدام فایل ها دست نخورده باقی مانده اند. با استفاده از سورس کنترل شما همیشه مطمئن هستید که آخرین ورژن برنامه را دارید و اگر ویژگی هایی به برنامه اضافه شده است و توسط برنامه نویس مربوطه نهایی شده است در پروژه وجود دارد و شما لازم نیست نگران آن باشید که این تغییرات را خودتان اعمال کنید.

در ضمن هر وقت که شما بخواهید که سورس را به عقب برگردانید و تغییراتی را که بر روی پروژه انجام داده اید منحل کنید به سادگی می توانید این کار را انجام دهید و لازم نیست که تغییرات را به صورت دستی خنثی نمایید. با استفاده از سورس کنترل شما می توانید ببینید که هر تغییر در چه تاریخی و توسط کدام یک از اعضای تیم انجام شده است. سورس کنترل کل تاریخچه تغییرات برنامه را در خود نگهداری می کند ولی نه به شکلی که گفتیم که هر بار یک پروژه از اول ساخته شده باشد بلکه فقط فایل هایی را که تغییر کرده است را در تاریخچه اش اضافه می کند. به همین دلیل استفاده از فضای ذخیره سازی پروژه هم بسیار بهینه استفاده می شود. در حال حاضر همه تیم های برنامه نویسی پروژه های خود را بر روی سورس کنترل نگهداری می کنند و مدیریت سورس خود را به آن داده اند. در حال حاضر سورس کنترل های متفاوتی وجود دارند که معروف ترین آن ها Git می باشد ولی علاوه بر آن می توان از SVN و TFS نیز نام برد. البته فقط اینها سورس کنترل های موجود نیستند ولی معروفترینشان این ۳ تا می باشد. در این مطلب به معرفی سورس کنترل و لزوم استفاده از آن پرداختیم در قسمت های بعدی به بررسی سورس کنترل ها می پردازیم  .

در مطلب بالا درمورد لزوم استفاده از سورس کنترل ها صحبت شد. حال به ادامه بحث در مورد سورس کنترل ها می پردازیم. در کار های تیمی معمولا سورس کنترل را بر روی یک سرور راه اندازی می کنند و همه ماشین ها و برنامه نویسان به آن متصل می شوند و سورس برنامه را از آن دریافت می کنند. 

انواع source control ها (version control System)

سورس کنترل ها انواع مختلفی دارند. و این دسته بندی به نوع پیاده سازی سورس کنترل ها بستگی دارد. سورس کنترل ها را به دو نوع اصلی تقسیم بندی می کنیم. سورس کنترل های متمرکز و سورس کنترل های توزیع شده. این تقسیم بندی بر اساس نحوه نگهداری و مدیریت سورس می باشد. 

 

ورژن کنترل های محلی ( Local version control System)

در این نسخه که ابتدایی ترین نسخه از ورژن کنترل ها می باشد سیستم به این شکل است که بعد از که تغییراتی را در پروژه انجام دادیم آن را در یک پوشه دیگر ذخیره می کنیم. همانطور که در مقاله قبلی گفتیم این روش با این که خیلی ساده است ولی احتمال خطای زیادی دارد و از نظر فضای ذخیره سازی هم بهینه نیست. 

 

Source control های متمرکز (Centralized Version Control Systems)

در این نوع سورس کنترل ها یک سرور اصلی وجود دارد که داده های متادیتا و مدیریتی در مورد سورس ها در آن نگهداری می شود و هر برنامه نویسی که درخواست سورس را بدهد پروژه یا قسمتی از پروژه که برای او وجود ندارد یا ورژن آن قدیمی است برای او ارسال می شود. ولی هیچ داده مدیریتی برای او ارسال نمی شود و همه داده های مدیریتی و ورژن های قدیمی و تاریخچه بر روی سرور نگهداری می شود. برای مثال TFS یک سورس کنترل متمرکز است. این نوع سورس کنترل کمک بسیاری به برنامه نویسی می کند. همچنین قابلیت‌های ویژه ای مانند single checkout را نیز ارائه می‌دهد. به عمل گرفتن سورس از سرور سورس کنترل checkout می‌گوییم. حال single checkout به این معنی است که اجازه دهیم که در یک زمان تنها یک کاربر بر روی یک فایل کار کند. یعنی وقتی که یک کاربر در حال کار بر روی یک فایل از پروژه است آن فایل برای برنامه نویسان و کاربران دیگر در حالت قفل باشد تا وقتی که برنامه نویسی که بر روی فایل مورد نظر کار می‌کرد کار خود را به اتمام برساند و تغییرات را check in کند. به اعمال تغییرات انجام شده بر روی سرور check in می گوییم.این قابلیت در TFS یا SVN وجود دارد. زیرا که آن‌ها از نوع سورس کنترل متمرکز می‌باشند. یکی از مشکلاتی که این نوع version control ها دارند این است که یک نقطه مرکزی دارند. حال اگر سرور سورس کنترل به هر دلیلی از کار بیفتد عملاً سورس کنترل دیگر کارایی ندارد و نمی‌توان از آن استفاده کرد و در این حالت اگر کاربر بخواهد فایلی را از سورس کنترل checkout کند یا بخواهد فایلی را check in کند نمی‌تواند این کار را بکند و در‌واقع تیم بیکار می شود. 

 

سیستم های کنترل سورس توزیع شده (Distributed Version Control Systems)


برای حل مشکلاتی که برای سورس کنترل های متمرکز گفتیم سورس کنترل های توزیع شده به وجود آمدند. از سورس کنترل هایی که توزیع شده هستند می‌توان Git , Mercurial, Bazaar ,Darcs را نام برد. دراین نوع سورس کنترل ها وقتی که برنامه نویسان عمل checkout را انجام می‌دهند فقط سورس پروژه را دریافت نمی‌کنند بلکه یک کپی آینه وار از کل فایل‌ها دریافت می‌کنند هم فایل‌های پروژه و هم فایل‌های مدیریتی سورس کنترل و تاریخچه پروژه را دریافت می کنند. با این کار اگر حتی سرور اصلی سورس کنترل هم از کار بیفتد و یا از بین برود باز مشکلی پیش نمی‌آید زیرا که همه کلاینت ها یک کپی از کل فایل‌ها دارند و در صورت بروز مشکل یکی از این نسخه ها جایگزین نسخه سرور شوند. یکی از قابلیت‌هایی که در این سیستم‌های سورس کنترل وجود دارد این است که کلاینت ها را می‌توان در گروه‌های مختلف قرار داد که همزمان با هم بر روی پروژه کار کنند. معروف ترین سورس کنترل توزیع شده Git می باشد. git یک سورس کنترل اوپن سورس است که می توان آن را به راحتی بر روی یک سیستم معمولی هم راه اندازی کرد. git با ابزار های برنامه نویسی بسیاری سازگار است برای مثال اگر شما جاوا کار می کنید نرم افزار intellij خود به صورت درونی گیت را پشتیبانی می کند و می تواند به راحتی و به طور کامل با آن ارتباط داشته باشد. و یا اگر شما با تکنولوژی دات نت کار می کنید در ویژوال استودیو ۲۰۱۵ به بعد به صورت درونی گیت برای کنترل پروژه قرار داده شده است. به شکلی که وقتی شما یک پروژه را می سازید خود ویژوال استودیو برای آن یک گیت محلی در نظر می گیرد.

با همه این حالات اگر شما بخواهید فایل های خود را خارج از محیط IDE در گیت قرار دهید و با یک سرور گیت ارتباط داشته باشید نیز می توانید از انواع متنوع ابزار های ویژوال و کنسولی استفاده کنید. البته رابط اصلی گیت کنسول است و شما باید دستورات را تایپ نمایید ولی می توانید از ابزار های ویژوال نیز استفاده کنید. یک سرور معروف گیت که اوپن سورس نیز می باشد و پروژه های بسیاری بر روی آن قرار دارد گیت هاب (github) می باشد که پروژه های بسیاری بر روی آن قرار دارند. در این مطلب به انواع سورس کنترل ها پرداختیم. در مطلب بعدی بیشتر وارد سورس کنترل ها خواهیم شد و آنها را شرح می دهیم .

تا الان با توجه به دو مقاله قبلی یک دید کلی از سورس کنترل ها به دست آورده ایم. در این مطلب می خواهیم در مورد عملیات و کارهایی که می شود در سورس کنترل انجام داد نیز صبحت کنیم. در این بخش ابتدا به کارها و عملیاتی که می توان بر روی Git انجام داد صحبت می کنیم و سپس به اعمالی که می توان بر روی TFS می توان انجام داد صحبت خواهیم کرد. دقت کنید که این عملیات مربوط به کارهایی است که هنگام استفاده از این سورس کنترل ها انجام می دهیم می باشد و فقط در مورد عملیات هنگام استفاده صحبت خواهیم کرد. 

 

عملیات معمول سیستم Git

بر روی سورس کنترل Git اعمال متنوعی برای کار با سورس انجام می شود که در ادامه آمده است. شما برای استفاده از گیت می توانید هم از خط فرمان آن استفاده کنید و یا هم می‌توانید از ابزارهای ویژوالی که تعداد آن‌ها هم بسیار است استفاده کنید. ما در این مطلب به معنی و مفهوم هرکدام از عملیات می‌پردازیم. 

 

عملیات clone

حالتی را در نظر بگیرید که شما در یک تیم عضو شده‌اید و یا می‌خواهید از سایت گیت هاب یک سورس را بگیرید در حالی که هیچ فایلی از سورس مورد نظر را ندارید. در این حالت شما باید پروژه را clone کنید. به عبارت دیگر عملی که برای اولین بار انجام می‌شود و کل پروژه را به همراه repository های آن دریافت می‌کند را clone می گوییم. با clone کردن یک پروژه کل فایل‌های پروژه مورد نظر به سیستم شما کپی می‌شود و در محلی که مشخص کرده‌اید ریخته می شود. کل فایل‌ها و تنظیمات و تاریخچه تغییر فایل‌ها به سیستم شما کپی خواهد شد. دوستان دقت کنند که تاریخچه پروژه معمولاً در سیستم گیت در یک پوشه git نگهداری می شود.که معمولاً این پوشه مخفی می باشد.در ضمن این‌طور نیست که بگوییم چون این پوشه تاریخچه و اطلاعات را نگهداری می‌کند حجم بسیار زیادی دارد شما اگر این پوشه را ببینید می‌فهمید که حجم کمی را به خود اختصاص داده است. 

 

عملیات commit

گفتیم که همه ی اعضای تیم پروژه را دریافت می‌کنند و کار های و وظایف خود را بر روی آن انجام می‌دهند. حال اگر بخواهند که تغییرات خود را دسته بندی نمایند ولی فعلاً آن را بر روی سرور ارسال نکنند از کامیت استفاده می کنند. یعنی کامیت برای تغییرات یک رکورد ثبت می‌کند و فایل‌هایی که تغییر کرده‌اند را نیز ثبت می نماید. همچنین هنگام کامیت باید یک سری توضیحات در مورد تغییرات انجام شده به عنوان کامنت برای کامیت قرار دهید. سپس این تغییرات بر روی سیستم شما ذخیره می‌شود دقت کنید که فقط بر روی سیستم شما ذخیره خواهد شد و هنوز بر روی سرور اصلی اعمال نشده است. 

 

 

عملیات Revert

اگر شما کامیت انجام داده باشید و از انجام آن پشیمان شده باشید شما می‌توانید آن کامیت را revert کنید. این کار باعث می‌شود که در رکوردهای کامیت یک کامیت جدید اضافه شود که تغییرات کامیت قبلی را ندارد. به عبارت دیگر revert کردن undo کردن تغییراتی است که انجام داده ایم. البته در سیستم گیت عملیات دیگری نیز برای undo کردن وجود دارند مانند reset و یا checkout که پیشنهاد می‌شود خود شما در مورد آن‌ها مطالعه کنید. 

 

عملیات push

وقتی که یک سری تغییرات انجام شد و شما نیز آن‌ها را کامیت کردید تغییرات بر روی سیستم شما انجام شده است و هنوز بر روی سرور آپلود نشده است. پس بقیه اعضای تیم نمی‌توانند از تغییرات شما خبردار شوند. برای اینکه تغییرات شما بر روی سرور آپلود شود شما باید کامیت های انجام شده را push کنید. دقت کنید که اول باید کامیت کنید سپس کامیت ها را push نمایید. با این کار فایل‌های تغییر داده شده شما به سرور انتقال می یابند و بقیه نیز می‌توانند تغییرات شما را با جزئیات مشاهده کنند. 

 

عمل pull

اگر شما بخواهید تغییرات انجام شده توسط دیگر اعضای تیم را بر روی کامپیوتر خود لود کنید باید این از سرور عمل pull را انجام دهید. با این کار بررسی می‌شود که کدام یک از فایل‌هایی که دست شما است تغییر کرده است‌. سپس آخرین نسخه از آن فایل‌ها از سرور گرفته و بر روی سیستم شما قرار داده می شوند. همچنین repository شما نیز آپدیت خواهد شد. 

 

عمل merge

حالتی را در نظر بگیریدکه شما بر روی یک فایل کار می‌کنید و یکی دیگر از اعضای تیم نیز بر روی همان فایل کار می کند. حال کار شما با فایل تمام شده و آن را کامیت کرده و بر روی سرور push می‌کنید. حال هم تیمی شما تغییراتی که شما انجام داده‌اید را ندارد. چون او هنوز pull نکرده است وهمچنین او نیز فایل مورد نظر را تغییر داده است. وقتی که هم تیمی شما می خواهد فایل را push کند سیستم گیت تشخیص می‌دهد که فایل قبلاً هم تغییر کرده است. بنابراین پیام میدهد که شما باید فایل را merge کنید. یعنی تغییرات شما وخودش را در یک فایل قرار دهد و جاهایی را که با هم تداخل دارند را تشخیص بدهد و مشکل را برطرف کند. برای merge کردن باید دو فایل را مقایسه یا compare کند. ابزار های بسیاری هستند که دو صفحه کد را با هم مقایسه می‌کنند و جاهایی که بین دو فایل متفاوت است را به رنگ دیگری نشان می‌دهند و این قابلیت را دارند که هر قسمت از تغییرات را که خواستید از فایلی به فایل دیگر اعمال کنید. 
عملیاتی که گفته شد ساده‌ترین عملیات مربوط به سیستم سورس کنترل گیت بود و حداقل چیزی بود که شما برای کار با گیت به آن‌ها نیاز خواهید داشت. در قسمت بعدی در مورد TFS صحبت خواهیم کرد.

در بخش بالا در مورد سورس کنترل گیت صحبت کردیم و عملیات معمول و مهم را برای این سیستم سورس کنترل گفتیم. در این مطلب می خواهیم در مورد TFS و اعمالی که بر روی آن انجام می شود صحبت کنیم. TFS برخلاف گیت یک سورس کنترل توزیع شده نیست و یک سورس کنترل متمرکز است. بنابراین این سورس کنترل Repository محلی ندارد پس اعمالی که معادل کامیت در گیت بود وجود ندارد و همه ی کار های آن با سرور است. دقت داشته باشید که TFS فقط یک سورس کنترل نیست و می توان از آن برای تعریف وظایف هر یک از کاربران نیز استفاده کرد. همچنین می توان از TFS برای پیاده سازی متدولوژی Agile و روش اسکرام نیز استفاده کرد. TFS مخصوص زبان های برنامه نویسی مایکروسافتی است و با ویژوال استودیو به خوبی مجتمع می شود و ویژوال استودیو به راحتی با آن ارتباط برقرار می کند. برای برپایی سرور TFS هم می توانید نرم افزار سرور آن را بر روی سرور نصب کنید و یا از حالت آنلاین این سورس کنترل اضافه کنید که البته یک سری محدودیت ها در حالت رایگان دارد. حال در ادامه عملیاتی که می توان بر روی TFS انجام داد را توضیح می دهیم. 

 

عملیاتی قابل انجام بر روی TFS


TFS مخفف Team Foundation Server می باشد که سرور اصلی برای سورس کنترل مایکروسافت می باشد که توسعه دهندگان از آن برای کنترل ورژن پروژه های مختلف از آن استفاده می شود. از tfs می توان برای عملیاتی مانند مدیریت کاربران و کنترل دسترسی هرکدام به پروژه ها نیز استفاده می شود. عملیاتی که برای کار با پروژه می توان انجام داد کارهای زیر می باشد. 

عمل Map

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

عمل Get Latest Version

با این عمل فایل هایی که بر روی سیستم شما موجود است بررسی می شود. و فایل هایی که وجود ندارد و یا این که ورژن فایل ها قدیمی است آن فایل ها را بر روی سیستم شما کپی می کند. شما بعد از عمل مپ کردن نیز باید عمل Get Latest Version را انجام دهید تا کل فایل های پروژه بر روی سیستم شما دانلود شود. 

عمل Undo pending changes

اگر شما تغییراتی بر روی پروژه انجام داده باشید و بخواهید که از اعمال آن تغییرات بر روی سرور انصراف دهید باید تغییرات را undo کنید. با این کار فایل هایی را که تغییر داده بودید از سرور درخواست می شود و همه تغییراتی را که انجام داده بودید نادیده گرفته می شود و فایل موجود در سرور لود خواهد شد.

 

عمل check in

این عمل شبیه عمل push در سیستم گیت است. یعنی تغییراتی را که انجام داده اید را بر روی سرور آپلود می کند. البته قبل از آن شما می توانید یک کامنت و توضیحاتی برای این ورژن از فایل ها قرار دهید و شرح بدهید که چه تغییراتی انجام شده است. البته نوشتن توضیحات در tfs اجباری نیست ولی در گیت شما باید توضیحات را وارد کنید. هر check in یک شماره دارد. 

 

عمل Compare

اگر شما بخواهید ببینید که فایل شما در مقایسه با یکی از فایل های سرور چه تغییراتی داشته است از دستور compare استفاده می کنید. در این حالت تغییرات و حذف و اضافه ها را با رنگ های مختلف یه شما نشان می دهد. 

 

عمل Get Specific Version

برخی اوقات شما نمی خواهید که آخرین ورژن موجود بر روی tfs را دریافت کنید بلکه می خواهید یک ورژن خاص را از سرور دریافت کنید وتغییرات آن را ببینید. برای این کار از Get Specific Version استفاده می شود. با این کار پنجره ای باز می شود که به شما اجازه می دهد ورژنی از پروژه را که می خواهید انتخاب کنید و از سرور دریافت نمایید. 

 

عمل shelve pending changes

حالتی را در نظر بگیرید که کار شما تمام نشده است ولی باید تغییرات خود را بر روی سرور آپلود کنید ولی جزء ورژن های پروژه محصوب نشود در این صورت شما می توانید از این عمل استفاده کنید. و بعدا آن را گرفته و ادامه دهید. یکی از خواصی که tfs دارد این است که وقتی که کلاینتی یک فایل را ویرایش می کند می توان طوری پیکر بندی کرد که سایر کلاینت ها نتوانند دیگر آن فایل را ویرایش کنند و فایل مورد نظر برای آنها قفل می شود. برای این کار در سطح سرور باید single checkout را فعال کنیم. 
با توجه به این که در کشور ما زبان های برنامه نویسی بر پایه دات نت کاربرد بسیار دارد به توضیح tfs پرداختیم که کاربران خود را عادت بدهند که از سورس کنترل ها استفاده کنند. زیرا که این کار باعث می شود که سورس های آنها به طور منظمی ذخیره شود و دسترسی به قسمت های مختلف پروژه برای آنها راحت تر باشد.

 

مقایسه‌ی Git با Subversion

 توی شرکت داریم پروژه‌ها رو از svn به git سوئیچ می‌کنیم. دیدم بهانه‌ی خوبیه تا درباره‌ی git بنویسم.

از اونجایی که اکثر برنامه‌نویس‌ها با svn آشنایی دارن به جای نوشتن در مورد git به مقایسه‌ی git با svn می‌پردازم. اینجوری راحت‌تر می‌تونید تصمیم بگیرید که آیا نیازی به تغییر سیستم کنترل سورس فعلیتون به git هست یا نه.

این روزها سیستم‌های توزیع شده‌ی کنترل سورس (Distributed Version Control) کم کم دارن جای سیستم‌های کنترل سورس سنتی متمرکز (Centralized) مثل svn رو می‌گیرن. از جمله git یکی از این سیستم‌های کنترل سورس توزیع شده است که محبوبیت زیادی پیدا کرده.

قسمت عمده‌ای از تفاوت‌های git و svn برمی‌گرده به تفاوت مدل توزیع شده و مدل متمرکز، برای همین ابتدا این دو مدل رو توضیح میدم.

 

مدل متمرکز

در این مدل یک مخزن (Repository) داریم که روی یک سرور قرار می‌گیره که شامل کل پروژه با تاریخچه‌اش است. هر کس که می‌خواد روی پروژه کار کنه یک کپی از آخرین نسخه‌ی پروژه رو از سرور دریافت می‌کنه (همون working copy)، تغییراتی میده و بعد تغییراتش رو به سرور ارسال (commit) می‌کنه تا در مخزن قرار بگیره. همچنین می‌تونه آخرین تغییرات سایرین رو از مخزن دریافت (update) کنه و به این ترتیب هر کس می‌تونه آخرین نسخه‌ی پروژه رو روی کامپیوتر خودش داشته باشه.

با توجه به لزوم وجود سرور در این مدل به این مدل، مدل کلاینت-سرور هم میگن.

 

مدل توزیع شده

در این مدل نیازی به وجود سرور برای نگهداری مخزن نیست و هر کس به جای working copy یک مخزن از پروژه رو داره. که این مخزن میتونه شامل working directory هم باشه.

برای مثال با git وقتی یک نفر یک پروژه رو شروع می‌کنه یک مخزن روی کامپیوتر خودش ایجاد می‌کنه و شروع به کار میکنه. حالا نفر دوم می‌تونه از این مخزن یک کلون (clone) تهیه کنه به عبارت دیگه یک مخزن عین مخزن نفر اول روی کامپیوتر خودش ایجاد کنه و در توسعه پروژه مشارکت کنه. حالا هر یک از این دو نفر هر موقع که خواستند میتونن از مخزن یکدیگر تغییرات یکدیگر را دریافت (fetch) و یا برای دیگری تغییرات خود را ارسال (push) کنند و تغییرات را ادغام (merge) کنند. وقتی نفر سوم می‌خواد وارد پروژه بشه، از هر یک از دو مخزن نفرات قبل میتونه کلون تهیه کنه و کار رو شروع کنه و می‌تونه تغییرات خودش رو با هر یک از اونها مبادله کنه. و این روند ادامه پیدا میکنه.

در واقع در این روش مخزن بین تمام مشارکت کنندگان در پروژه توزیع شده، برای همین به این مدل، مدل توزیع شده گفته میشه.حتما با خودتون فکر می‌کنید که این روش شاید برای یک گروه سه یا چهار نفره مناسب باشه ولی برای تیم های بزرگتر کارایی نداره چون هماهنگ کردن مخازن کار خیلی مشکلی میشه. در جواب باید گفت گرچه در مدل توزیع شده وجود سرور الزامی نیست ولی محدودیتی برای استفاده از این مدل به صورت کلاینت-سروری وجود نداره. یعنی شما می‌تونید یک مخزن روی یک سرور بگذارید و به صورت توافقی همه‌ی توسعه‌دهنده‌ها به جای مبادله تغییرات با یکدیگر، تغییرات را با مخزن روی سرور مبادله کنند. خوب حالا حتما با خودتون می‌گین این که همون مدل متمرکز شد! عجله نکنید. تا انتهای مطلب رو بخونید بعد قضاوت کنید.

 

مزایای مدل توزیع شده

عدم نیاز به شبکه

با توجه به اینکه در این روش مخزن روی کامپیوتر شما قرار داره برای انجام خیلی از عملیات‌ها نیازی به اتصال به شبکه نیست. مثلا commit کردن، log گرفتن، diff گرفتن، و خیلی عملیات‌های دیگه نیازی به ارتباط با شبکه نداره. که باعث کاهش ترافیک شبکه میشه و در عین حال این امکان رو به شما میده که در هنگامی که شبکه قطع است و یا هنگامی که با لپتاپ خود به مسافرتی و یا جایی می‌روید که دسترسی به شبکه ندارید همچنان به کار خودتون روی پروژه ادامه بدید.

سرعت بیشتر

عدم نیاز به شبکه در انجام اکثر عملیات‌ها باعث افزایش قابل توجه سرعت در اینگونه عملیات‌ها میشه.

مشارکت در پروژه بدون نیاز به دسترسی کامیت

با توجه به ماهیت توزیع شده در این مدل برای مشارکت در یک پروژه نیازی به دسترسی کامیت نیست. به این صورت که شما یک clone از یک پروژه تهیه می‌کنید و تغییراتی را در آن می‌دهید و روی مخزن خود کامیت می‌کنید. حالا می‌تونید از یک نفر که دسترسی کامیت داره بخواهید که کامیت‌های شما رو بررسی کنه و اگر صلاح دونست توی مخزن اصلی merge کنه. در نتیجه بدون اینکه شما دسترسی مستقیم کامیت داشته باشید کامیت‌های شما با نام خودتان در مخزن اصلی ثبت میشه. این مزیت برای پروژه‌های بازمتن خیلی مفیده و به گسترش و توسعه پروژه با افزایش مشارکت داوطلبین کمک میکنه. بگذارید یک مثال عینی بزنم. من برای ارسال patch به پروژه cakephp که قبلا از svn استفاده میکردند فایل patch تغییرات رو ضمیمه‌ی تیکت کردم(؟). یکی از برنامه نویسان تغییرات رو بررسی و روی پروژه کامیت کرد(؟). در اینجور مواقع از اونجایی که svn این کامیت رو به نام شخص کامیت کننده ذخیره میکنه نه مولف اصلی، معمولا برای مشخص شدن نویسنده‌ی اصلی توی کامنت می‌نویسند “applying patch from x” و ضمن اینکه اگر تغییرات زیاد باشه بررسی تغییرات کار سختی میشه.

حالا ببینیم git چطور این مشکل رو حل میکنه. بعد از اینکه cakephp به git منتقل شد من یک باگ گزارش دادم(؟) و برای نوشتن testcase برای این باگ یک fork از پروژه گرفتم، testcase رو نوشتم و کامیت کردم(؟) و لینک تغییرات رو به تیکت اضافه کردم. یکی از برنامه نویسان تغییرات رو بررسی و در مخزن اصلی ادغام میکنه(؟). اینجا git این کامیت رو با نام مولف اصلی و تاریخ اصلی تغییرات ذخیره میکنه و در عین حال نام کامیت کننده و تاریخ کامیت رو هم ذخیره میکنه. ضمن اینکه اینجا اگر تغییرات زیاد باشه میشه به کامیت‌های مختلف تفکیک بشه که هر کدوم توضیحات خودش رو داره و بررسی این تغییرات کار راحت تری میشه.

کاهش خطر از دست رفتن اطلاعات

در این مدل با توجه به اینکه هر توسعه دهنده یک مخزن از پروژه رو داره در صورت ترکیدن سرور و از دست رفتن کل اطلاعات هیچ مشکلی پیش نمیاد و می‌تونید مجددا یکی از مخازن موجود رو روی سرور قرار داده و بدون هیچ مشکلی کار رو ادامه بدید.

پشتیبانی از مدل‌های کاری(workflow) متعدد

با استفاده از سیستم های توزیع شده تقریبا هر نوع مدل کاری رو میشه پیاده سازی کرد. مثلا شما می‌تونید مثل سیستم های متمرکز به صورت کلاینت-سرور کار کنید. البته این مبحث خودش یک مقاله جداگانه رو می‌طلبه. اگر حوصله داشتید برای کسب اطلاعات بیشتر اینجا و اینجا رو مطالعه کنید.

امکان داشتن مخزن خصوصی از یک پروژه

برای مثال شما می‌تونید یک clone از یک پروژه بگیرید و یکسری تغییرات خصوصی برای خودتون بدید ولی در پروژه اصلی اعمال نکنید. و در عین حال همیشه می‌تونید آخرین تغییرات پروژه اصلی رو روی مخزن خصوصی‌تان ادغام کنید.

تمیزتر بودن مخزن اصلی

با توجه به اینکه در این روش کامیت‌ها را روی مخزن محلی خودتان انجام می‌دهید. در صورت بروز اشتباه در کامیت دیگه اون کامیت رو در مخزن سرور اصلی ادغام نمی‌کنید. ولی در سیستم هایی مثل svn در صورتی که اشتباها یک فایل cd.iso رو توی مخزن کامیت کنید. حتی بعد از حذفش هم حجم مخزن کاهش پیدا نمیکنه و اون فایل برای همیشه در تاریخچه مخزن باقی می‌مونه و حجم مخزن به مرور زمان در اثر این اشتباهات افزایش پیدا میکنه و تاریخچه‌ی مخزن شلوغ و کثیف میشه.

 

معایب مدل توزیع شده

مشکل درک مفاهیم

گفته میشه اکثر افراد در درک مفاهیم سیستم‌های توزیع شده مشکل دارند و کمی طول می‌کشه تا بتونن بهش عادت کنند. البته علت اصلی اینه که اکثرا به سیستم‌های متمرکز عادت کردند و همون انتظاراتی رو از سیستم‌های توزیع شده دارند که از یک سیستم متمرکز دارند. این باعث میشه مثلا به نظرشون بیاد بعضی از مراحل و عملیات‌ها اضافه است.

در صورتی که ساختار و نحوه عملکرد سیستم‌های توزیع شده رو زیربنایی یاد بگیرید درک مفاهیم اون خیلی برایتان ساده خواهد شد.

مشکل کنترل دسترسی

با توجه به اینکه در مدل توزیع شده کل مخزن در اختیار توسعه دهندگان قرار می‌گیره هر کس که بتونه به یکی از این مخازن دسترسی داشته باشه به کل پروژه دسترسی پیدا میکنه. ولی در مدل متمرکز میشه مطمئن بود که فقط کسانی به مخزن دسترسی دارند که به مخزن سرور اصلی دسترسی داشته باشند. البته این مسئله در مورد پروژه‌های بازمتن مشکل به حساب نمیاد.

امروزه سیستم‌های کنترل سورس توزیع شده‌ی متعددی وجود داره که هر کدوم طرفدارهای خاص خودش رو داره از جمله معروف‌ترین اونها Git و Bazaar و Mercurial هستند.

همه‌ی این سیستم‌ها تفاوت‌های گفته شده رو نسبت به سیستم‌های متمرکز دارند. علاوه بر این، این سیستم‌ها کم و بیش مزایای دیگری هم دارند که در این بین Git از جایگاه بهتری نسبت به بقیه برخوردار است.

 

مزایای Git

سرعت فوق العاده

یکی از اهداف اولیه طراحی git سرعت بوده. و از این نظر واقعا git موفق بوده.

در کل سیستم‌های توزیع شده از سرعت بهتری نسبت به سیستم‌های متمرکز برخوردارند. و در بین سیستم‌های توزیع شده git بهترین جایگاه رو از نظر سرعت داره. یکی از دلایل سرعت git اینست که با زبان C نوشته شده که نسبت به زبان‌های سطح بالا نظیر python سرعت بهتری داره. (Bazaar و Mercurial با python نوشته شده‌اند.)

 

حجم کم

حجم یک working directory به همراه مخزن در git به ندرت از یک working copy در svn بیشتر میشه. برای مثال مخزن Mozilla در svn چیزی حدود ۱۲GB بوده در حالیکه حجم همین مخزن در git حدود ۴۲۰MB بیشتر نیست. یعنی حدود ۳۰ بار کوچکتر از svn. مخزن پروژه Ruby on Rails در git که شامل کل تاریخچه فایل‌هاست حدود ۱۳MB بیشتر نیست درحالیکه حجم پروژه (بدون مخزن) ۹MB است یعنی حجم کل مخزن فقط یک ونیم برابر حجم پروژه است. و مخزن همین پروژه قبلا در svn حدود ۱۱۵MB بوده.

حتی در بین سیستم‌های توزیع شده هم git از نظر حجم بهترین جایگاه رو داره.

 

پایداری

معماری داخلی git از سادگی و پایداری فوق‌العاده‌ای برخورداره که تقریبا امکان خراب شدن مخزن در اون وجود نداره. ولی تا به حال موارد زیادی از خراب شدن خود به خود مخازن svn مشاهده شده.

 

راحتی کار با شاخه ها (branch)

یکی از قابلیت‌های فوق العاده‌ی git پشتیبانی خیلی خوب از شاخه هاست. در git می‌تونید برای تست یک ایده‌ی جدید شاخه‌ی محلی بسازید و در حین کار هر زمان خواستید به شاخه اصلی برگردید و یکسری کامیت انجام دهید و مجددا به شاخه تست برگردید و می‌تونید هر زمان خواستید شاخه ها رو با هم ادغام کنید و یا حذف کنید. و تمام این عملیات‌ها بدون نیاز به ارتباط با سرور انجام می‌شود. و به خاطر معماری فوق العاده‌ی git در مقایسه با سایر سیستم‌ها از سرعت و کارایی فوق العاده ای برخوردار است.

 

دنبال کردن محتوای فایل به جای نام فایل

git محتوای فایل‌ها را دنبال می‌کند. یعنی اگر فایلی را بدون استفاده از دستورات git تغییر نام داده، جابه‌جا و یا کپی کنید git با توجه به این ویژگی، این عملیات را تشخیص داده و ثبت میکند و لذا تاریخچه مربوط به اینگونه فایل‌ها را حفظ می‌کند.

 

کامیت با جزئیات بیشتر

در git یک کامیت علاوه بر نام کامیت کننده و تاریخ کامیت شامل نام مولف و تاریخ تغییرات هم هست. برای مثال این قابلیت git باعث میشه که در اعمال patch ها نام مولف اصلی و تاریخ تغییرات حفظ شود.

شلوغ نکردن working directory با پوشه‌های .git

اگر با svn کار کرده باشید می‌دانید که svn در تمام پوشه‌های پروژه یک پوشه به نام .svn ایجاد می‌کند که باعث بوجود آمدن مشکلات زیادی می‌شود. مثلا اینکه نمی‌توانید شاخه‌ها را کپی کنید و باید از دستورات خود svn استفاده نمایید. و در صورت عدم استفاده از دستورات svn چنانچه تغییراتی در کپی بدهید، بر روی شاخه‌ی اصلی کامیت می‌شود و یا تغییرات شاخه‌ی اصلی روی کپی شما هم اعمال می‌شود. این مشکل معمولا برای اکثر برنامه نویسان تازه‌کار اتفاق می‌افتد.

اما در git فقط یک شاخه به نام .git در پوشه‌ی اصلی پروژه ایجاد می‌شود که مانع از به وجود آمدن مشکلاتی نظیر مشکلات فوق می‌شود.

 

نمایش میزان پیشرفت عملیات

در اکثر عملیات‌های شبکه‌ای در git مراحل و میزان پیشرفت عملیات نمایش داده می‌شود و می‌توانید بفهمید چه میزان از کار انجام شده و چه مقدار باقی ماده است. اما در svn این امکان وجود ندارد.

تنوع در مجموعه دستورات و امکانات (feature-rich)

درgit مجموعه دستورات متعددی (بالغ بر ۱۴۰ دستور) وجود دارد که با یادگیری آنها می‌توان کارهایی را انجام داد که در سایر سیستم‌ها یا قابل انجام نیست و یا بسیار دشوار است. قابلیت‌های منحصر به فردی نظیر stage area و stash و local branching که با یادگیری آنها در روش کارتان تحولاتی ایجاد خواهد شد و دیگر قادر به برگشتن به سایر سیستم‌ها نخواهید بود.

معایب Git

کدهای طولانی SHA1 به جای شماره‌های متوالی revision

در واقع این مورد ایراد به حساب نماید و حتی معماری git به گونه‌ای است که از این شناسه‌های SHA1 به عنوان امضای دیجیتال برای کامیت‌ها و سایر آبجکت‌های داخلی گیت استفاده شده که باعث بالا رفتن امنیت و جلوگیری از دستکاری مخازن خواهد شد.

اما معمولا در شروع کار با git اولین چیزی است که، عجیب و غیرعادی به نظر می‌رسد و اکثر تازه‌کارها را دچار سردرگمی می‌کند.

از آنجایی که در معماری توزیع شده کامیت‌ها در یک مکان انجام نمی‌شود امکان تخصیص شماره های منحصر به فرد و متوالی به کامیت‌ها وجود ندارد. در git از کدهای ۴۰ کاراکتری SHA1 به عنوان شناسه‌ی کامیت استفاده می‌شود. از آنجایی که به خاطر سپردن این کدها کار دشواری است می‌توان فقط از چند کاراکتر اول آن استفاده کرد. و چنانچه این چند کاراکتر در مورد دو شناسه‌ تکراری نباشد git میتواند شناسه‌ی مورد نظر شما را پیدا کند. معمولا از ۷ کاراکتر اول استفاده میشود که احتمال تکراری بودن آن در یک پروژه بسیار کم است.

در git راه‌های مختلفی برای ارجاع به آبجکت‌های داخلی(از جمله کامیت‌ها) وجود دارد که به اصلاح به آن ها Treeish  گفته میشود. مثلا برای ارجاع به کامیت‌ها می‌توان از tag ها و یا میانبرهایی نظیر^ و ‍~ و @ استفاده کرد.

عدم سازگاری دستورات با سیستم‌های سنتی

اکثر دستورات git یا عملکرد کاملا متفاوتی با دستورات هم نام خود در سیستم‌های دیگر نظیر svn دارند و یا اینکه اسامی متفاوتی با معادل‌های رایج در سیستم‌های دیگر دارند. و این باعث میشود برنامه نویسانی که به سیستم‌هایی نظیر svn عادت کرده‌اند در ابتدای کار با git دچار سردرگمی شوند. تعدد دستورات git که بالغ بر ۱۴۰ دستور می‌شود نیز مزید بر علت است.

 

 

امکان checkout جزئی وجود ندارد

در svn می‌توانید فقط از یک شاخه‌ از پروژه checkout بگیرید ولی در git این امکان وجود ندارد و باید کل پروژه clone گرفته شود. البته با استفاده از قابلیت submodule در git می‌توان قسمت‌های مختلف پروژه را در مخازن جداگانه ذخیره کرد و این مخازن را در مخزن اصلی به صورت submodule استفاده کرد. که در این حالت می‌توان برای کار کردن روی یکی از این قسمت‌ها به جای clone گرفتن از کل پروژه فقط از submodule مربوطه clone گرفت.

امکان افزودن پوشه خالی به مخزن وجود ندارد

مبنای کار git بر اساس محتوای فایل‌هاست و در معماری git امکان تعریف پوشه‌ی خالی وجود ندارد. لذا برای رفع این مشکل معمولا به صورت قراردادی یک فایل خالی به نام empty در این پوشه‌ها قرار می‌دهند.

 

عدم سازگاری با ویندوز

git را نویسنده‌ی لینوکس(لینوس تروالدز) برای میزبانی پروژه‌ی کرنل لینوکس نوشته است. و از همان ابتدا قابلیت حمل(portability)   جزو اهداف پروژه نبوده است و فقط روی سیستم های ‎*nix اجرا می‌شود. و رسما از ویندوز پشتیبانی نمی‌کند. البته این مشکل امروز تا حدود زیادی با کمک پروژه msysgit برطرف شده است. msysgit در واقع با پیاده سازی gcc و دستورات مورد نیاز در ویندوز قابلیت اجرا شدن git در ویندوز را فراهم میکند.

 

کمبود رابط گرافیکی قوی

برای svn تاکنون رابط‌های گرافیکی فوق‌العاده‌ای نظیر TortoiseSVN نوشته شده است. ولی در مورد git هنوز در ابتدای راه هستیم. البته به تازگی نسخه‌های اولیه‌ای از TortoiseGit که تلاشی برای شبیه سازی رابط گرافیکی محبوب TortoiseSVN برای git است منتشر شده است که هنوز تمام امکانات و دستورات git را پوشش نمی‌دهد.

یکی از دلایلی که قبلا برنامه‌نویسان کمتر به سیستم‌های کنترل سورس توزیع شده روی می‌آوردند عدم پشتیبانی میزبان‌هایی نظیر SourceForge و Google Code بود. اما امروز تقریبا این مشکل حل شده است.

هم اکنون SourceForge  از CVS و SVN و Git و Mercurial و Bazaar پشتیبانی می‌کند. و Google Code هم از SVN و Mercurial پشتیبانی میکند.

GitHub هم به عنوان یک میزبان برای پروژه‌های Git محبوبیت زیادی پیدا کرده و البته بیشتر از اینکه یک میزبان باشه یک شبکه اجتماعی برای میزبانی کدهاست.

 

M6R7M

محمدرضا محمودی هستم ، سعی شده در این وبلاگ مطالب مفید و کارامدی قرار بگیره ، از اینکه وقت میگذارید و مطالب رو مطالعه میکنید متشکرم... ممنون میشم اگر موردی و یا ... میبینید حتما نظرات خودتون رو ارسال کنید


نظر بدهید