کنترل نسخه چیست؟ - نسخهی قابل چاپ +- انجمن عمومی گسترش فناوری آگو (http://forums.ago.ir) +-- انجمن: انجمن های عمومی گسترش فناوری آگو (/forumdisplay.php?fid=1) +--- انجمن: برنامه نویسی (/forumdisplay.php?fid=13) +--- موضوع: کنترل نسخه چیست؟ (/showthread.php?tid=2074) |
کنترل نسخه چیست؟ - agotd - 01-07-2013 06:08 AM شما در پروژه خود از ابزارهای کنترل نسخه توزیع شده (مانندGIT) استفاده می کنید یا از ابزارهای کنترل نسخه مرکزی (مانند SVN) ؟ مزیت و معایب هر کدام از این رویکردها کدام است؟ ما بر این باوریم که ابزارهای کنترل نسخه توزیع شده از ابزارهای کنترل نسخه مرکزی برای تیم های چابک انعطاف پذیری بیشتری دارند. با رویکرد ایجاد branch در سیستم های کنترل نسخه می توانید تیم های چابک خود را چابک تر کنید. چکیده: رویکرد ایجاد شاخه[1] نقش مهمی در تولید نرم افزار دارد. در پروژه های چابک[2] ایجاد شاخه با وجود تغییرات مداوم در سیستم متضاد تلقی شده و در نتیجه مورد توجه قرار نگرفته است. در این مقاله مشخص می شود چه رویکردی در زمینه ایجاد شاخه می تواند در فرایند های چابک استفاده شود. همچنین تحلیل می شود که سیستم های کنترل نسخه[3] توزیع شده[4] برای چنین رویکردهایی مناسب تر از سیستم های کنترل نسخه مرکزی هستند. مقدمه: ساخت نرم افزار فرایندی است که در آن محتوای زیادی تولید می شود. این محتوا اغلب پیچیدگی بسیاری دارد. این محتوا می تواند توسط تیم هایی کوچک یا تیم هایی با هزاران نفر برنامه نویس تولید شود. بنابراین چنین فرایندی نیاز به هماهنگی بسیار بالایی دارد. این هماهنگی بخشی از فرایند تولید را می سازد که به آن مدیریت پیکربندی نرم افزار ([5]SCM) می گویند. در گذشته این کار به کمک ابزارهای کنترل نسخه مرکزی انجام می شد. همچنین رویکرد ایجاد شاخه در میان تیم ها به ویژه تیم های چابک رایج نبود. در سال های اخیر ابزارهای جدید کنترل نسخه تولید شده اند. این ابزارها مدل سنتی ابزارهای کنترل نسخه مرکزی (CVC[6]) مانند CVS و Subversion را تغییر داده اند. ابزارهای جدید مبتنی بر مدل های توزیع شده هستند. ابزارهایی مانند Arch، Bazaar، BitKeeper و Git در این دسته قرار می گیرند. ابزارهای کنترل نسخه مرکزی یک مخزن[7] مرکزی دارند که هر برنامه نویس می تواند با آن هماهنگ شده[8] و کدهای خود را با آن تلفیق[9] کند. برای برنامه نویسان و کاربران دیگر درک چنین مدل ساده ای بسیار آسان است. در این مقاله توضیح داده می شود چرا ابزارهای کنترل نسخه توزیع شده (DVC[10]) نسبت به ابزارهای مرکزی برای تیم های چابک مناسب تر هستند. همچنین جریان کاری و مسئولیت هایی که باید در نظر گرفته شود تا یک تیم چابک بتواند از تمام مزایای ابزارهای توزیع شده استفاده کند شرح داده می شود. تفاوت ابزارهای کنترل نسخه مرکزی و توزیع شده: روش سنتی برای ردگیری نسخه های مختلف نرم افزار مدل مرکزی بوده است. در این مدل یک سرور مرکزی وجود دارد که تمام محتوا و تاریخچه تغییرات آن را ذخیره می کند. برنامه نویس یک کپی از محتوا را از سرور گرفته روی سیستم محلی خود نگهداری کرده سپس تغییراتی که لازم است را روی محتوای محلی ایجاد می کند. در پایان محتوای تغییر داده شده به سرور منتقل می شود. در این مدل تمام تغییرات روی سرور مرکزی وجود دارد. زمانی که یک برنامه نویس تغییری روی کد ایجاد کرده و آن را به سرور منتقل می کند، تمام برنامه نویسان دیگر این تغییر را در زمان گرفتن محتوا از سرور دریافت می کنند. مدل مرکزی که در شکل زیر نشان داده شده است، یک مدل ساده است که به راحتی قابل فهم و اجرا می باشد ولی مشکلاتی نیز ایجاد می کند. اگر برنامه نویس محتوای نادرستی را به سرور منتقل کند، به طور مثال کدهایی که به درستی کامپایل نمی شوند یا کدهایی که تست نشده اند، محتوای نادرست به تمام برنامه نویسان منتشر می شود. شکل 1 مدل ابزارهای کنترل نسخه مرکزی
مشکل دیگر زمانی ایجاد می شود که یک برنامه نویس روی یک ویژگی آزمایشی کار می کند. چنین برنامه نویسی نمی خواهد تا زمانی که ویژگی به حالت پایداری نرسیده است آن را به سرور منتقل کند. در مدل ساده ابزارهای مرکزی برنامه نویس مجبور است تغییرات را تا زمان پایدار شدن در سیستم محلی خود نگه دارد. این کار باعث می شود برنامه نویس نتواند از امکانات ابزارهای کنترل نسخه مانند نگهداری تاریخچه و بازگشت به نسخه پایدار قبلی استفاده کند. همچنین راهی برای هماهنگ شدن این برنامه نویس با برنامه نویسان دیگر وجود ندارد. به همین جهت اگر ویژگی آزمایشی گسترش یابد و به نفرات دیگری در پیاده سازی آن نیازمند شود، نمی توان از این مدل استفاده کرد. در چنین شرایطی رویکرد ایجاد شاخه مفید است. مهمترین دلیل استفاده از شاخه حل مشکل ذکر شده است. شاخه در یک ابزار کنترل نسخه مرکزی یک ساختار سمت سرور است که به برنامه نویس اجازه می دهد محل منتقل شدن تغییرات خود به سرور را انتخاب کند. با ابزار کنترل نسخه توزیع شده یک مخزن مرکزی وجود ندارد. هر برنامه نویس یک مخزن کامل با تاریخچه تغییرات جداگانه دارد. هر برنامه نویس محتوا را تغییر داده و آن را منتشر می کند. هر برنامه نویس دیگر می تواند در صورتی که بخواهد و تغییرات از نظر او مناسب باشد آن ها را بگیرد ولی الزامی در این کار وجود ندارد. این مدل پیچیده تر از مدل مرکزی است چرا که در آن فهمیدن این که چه کسی چه تغییراتی را ایجاد کرده است و حالت کلی پروژه چیست دشوارتر می باشد. این مدل در شکل زیر قابل مشاهده است. شکل 2 مدل ابزارهای کنترل نسخه توزیع شده
ابزارهای کنترل نسخه توزیع شده انعطاف پذیری بالایی دارند. این انعطاف پذیری بالا اجازه می دهد با توجه به ساختار تیم رویکرد کنترل نسخه تغییر کند. در عین حال چنین انعطاف پذیری باعث ایجاد پیچیدگی نیز می شود. برای مقابله با این پیچیدگی و استفاده مناسب از انعطاف پذیری این ابزارها لازم است ساختار تیم و رویکرد آن نسبت به کنترل نسخه به صورت دقیق مشخص شود. در ادامه جریان کاری و ساختار مناسب تیم های چابک برای استفاده از این ابزارها شرح داده می شود. یک فرایند ساده با ابزارهای کنترل نسخه توزیع شده: در ابتدای کار هر برنامه نویس یک مخزن محلی برای خود ایجاد می کند. این مخزن به صورت کامل تحت اختیار برنامه نویس است و برنامه نویسان دیگر آن را نمی بینند. سپس برنامه نویس یک نمونه مشابه ولی عمومی از مخزن محلی خود می سازد. سایر برنامه نویسان به این مخزن عمومی دسترسی خواندن دارند. دسترسی نوشتن در مخزن عمومی و محلی برنامه نویس فقط در اختیار خودش می باشد. فرایند پایه برای تیم به این صورت است. هر برنامه نویس (در واقع هر دو برنامه نویس در مدل برنامه نویسی دونفره[11]) روی یک مورد کاربرد[12] یا داستان[13] کار می کند. زمانی که برنامه نویس بخشی از عملکرد داستان را تولید کرد، تغییرات را به مخزن محلی خود منتقل می کند. در اینجا لازم نیست برنامه نویس تغییرات را به سایر برنامه نویسان منتشر کند، بلکه آن را برای حفظ تاریخچه در مخزن محلی خود نگه می دارد. زمانی که برنامه نویس داستان را به طور کامل تولید کرد، تغییرات ایجاد شده را به مخزن عمومی خود منتقل می کند. سپس به مربی که نقش نگهبان مخزن[14] را دارد اطلاع می دهد که تغییرات منتقل شده است. مربی تغییرات را از مخزن عمومی برنامه نویس گرفته به مخزن محلی خود منتقل می کند. مربی وظیفه دارد خطوط یکپارچه سازی را مدیریت کند. یعنی تغییرات را بررسی کند و مطمئن شود تغییرات از کیفیت لازم برخوردار هستند. به طور مثال باید تغییرات را کامپایل کرده و unit tests (تستهای واحد) و acceptance tests (تستهای پذیرش) را روی آن ها اجرا کند. اگر تغییرات کیفیت مطلوب را نداشتند رد می شوند و برنامه نویس باید آنها را اصلاح کند. اگر تغییرات مورد قبول بودند، مربی آن ها را به مخزن عمومی خود منتقل می کند. سپس به سایر برنامه نویسان خبر می دهد که عملکرد جدیدی منتشر شده است و آن ها باید این عملکرد را از مخزن عمومی مربی دریافت کرده، با مخزن محلی خود تلفیق کنند. این مدل در شکل زیر قابل مشاهده است. شکل 3 فرایند تیم های چابک برای استفاده از ابزارهای کنترل نسخه توزیع شده
در این مدل برنامه نویس تنها به تغییراتی که در مخزن عمومی مربی داده می شود حساس است. بنابراین لازم نیست از تغییرات تمام برنامه نویسان مطلع باشد. باید در نظر گرفت که چنین مدلی می تواند در تیم های معمول چابک بسیار پیچیده باشد. به طور مثال در این مدل 12 شاخه، 10 شاخه برای برنامه نویسان و 2 شاخه برای مربی ها، وجود دارد. اگر برنامه نویسان از مدل برنامه نویسی دونفره استفاده کنند، 5 شاخه برای برنامه نویسان و 1 شاخه برای مربی وجود خواهد داشت. در نتیجه تیم به صورت معمول بین 10 تا 15 تلفیق غیر بدیهی در طول یک تکرار[15] باید انجام دهد. همچنین تعداد بسیار بیشتری تلفیق بدیهی وجود خواهد داشت که ناسازگاری ندارند و به صورت خودکار انجام می شوند. همچنین باید در نظر گرفت وجود مربی به عنوان نگهبان مخزن ضروری نیست. هر فرد می تواند نگهبان مخزن خود باشد و تغییرات را منتشر کند. از نظر ابزارهای کنترل نسخه توزیع شده وجود نگهبان مخزن الزامی نیست اما از دیدگاه تیم های چابک وجود چنین نقشی مفید است. تغییرات در تیم های چابک زمانی باید منتشر شود که کامل شده باشد. تکمیل تغییرات تنها توسط مشتری قابل ارزیابی است. در نتیجه مشتری باید نقش نگهبان مخزن را ایفا کند. از آن جایی که مشتری نمی تواند همواره حضور داشته باشد، همچنین معیارهای کیفی دیگری مانند unit tests (تستهای واحد) برای ارزیابی تکمیل تغییرات وجود دارد، نقش نگهبان مخزن می تواند به مربی واگذار شود. یک فرایند پیشرفته با ابزارهای کنترل نسخه توزیع شده: با وجود آن که فرایند ساده ذکر شده در بخش قبلی از برخی از قابلیت های پیشرفته مدیریت پیکربندی نرم افزار استفاده می کند، به آسانی قابل فهم، نصب و پیاده سازی می باشد. روی این فرایند ساده می توان مفاهیم پیشرفته تری اضافه کرد که ارزش های بیشتری برای تیم فراهم کند. اولین مفهوم خطوط یکپارچه سازی است که بر اساس وابستگی میان داستان ها تیم را به چند تیم کوچک می شکند. مفهوم دیگر استفاده از شاخه های محلی است که به ازای هر فعالیت برای هر فرد تشکیل می شود و اجازه می دهد هر فرد کنترل بیشتری روی فضای کاری خود داشته باشد. خطوط یکپارچه سازی مرحله ای: در فرایند ساده یک خط یکپارچه سازی وجود دارد. در این خط همواره یک نسخه از نرم افزار که قابل ارائه به مشتری است نگهداری می شود. به همین دلیل تنها زمانی که یک داستان به طور کامل پیاده سازی شد می تواند به این خط اضافه شود. وضعیت های دیگری وجود دارد که در آن ها لازم است قبل از آن که داستان ها برای ارائه به مشتری آماده شوند بین افراد مربوطه هماهنگی ایجاد شود. یکی از این وضیعت ها زمانی رخ می دهد که یک داستان به چند فعالیت موازی تقسیم شده باشد. در این حالت داستان به طور کامل زمانی پیاده سازی می شود که تمام فعالیت های زیر آن انجام شود. تمام افرادی که روی این داستان کار می کنند باید تغییرات را از یکدیگر بگیرند. اگر داستان بین چند برنامه نویس شکسته شود، یکی از آن ها باید نقش نگهبان مخزن را برای خط یکپارچه سازی آن داستان ایفا کند. این فرد فعالیت ها را به افراد دیگر می سپارد و تغییرات آن ها را دریافت کرده به خط یکپارچه سازی داستان اضافه می کند. زمانی که تمام افراد فعالیت های خود را انجام دادند و تغییرات را به خط یکپارچه سازی داستان اضافه کردند، خط یکپارچه سازی داستان با خط یکپارچه سازی اصلی تلفیق می شود. این فرایند زمانی بسیار مفید است که داستان های وابسته به هم وجود داشته باشد. وابستگی حالت های مختلفی دارد. در برخی از حالت ها یک داستان زمانی می تواند شروع شود که داستان دیگری به طور کامل تمام شده باشد. در حالت دیگری که بسیار رایج است ممکن است یک داستان فقط به ساختار داده ای کلی داستان دیگری برای شروع نیاز داشته باشد، ولی لازم نیست داستان مربوطه به طور کامل پیاده سازی شده باشد. فرایند پیشرفته ذکر شده این حالت دوم را به خوبی پشتیبانی می کند. در شکل زیر یک سناریوی رایج قابل مشاهده است که در آن داستان B به داستان A وابسته است. زمانی که کار پیاده سازی داستان A تا حدی پیش رفت، داستان B شروع می شود. برای شروع B تغییرات از خط یکپارچه سازی داستان A دریافت می شود. سپس تغییرات لازم برای B روی آن ها پیاده سازی می شود. در زمان پیاده سازی B، به طور متناوب تغییرات از خط یکپارچه سازی A دریافت می شود تا هماهنگی های لازم صورت گیرد. زمانی که پیاده سازی B تمام شد به برنامه نویسان A اطلاع داده می شود تا تغییرات را از خط یکپارچه سازی B دریافت کنند. زمانی که پیاده سازی A تمام شد تمام تغییرات A و B با خط یکپارچه سازی اصلی تلفیق می شود. شکل 4 خطوط یکپارچه سازی مرحله ای
شاخه محلی: یک ویژگی قوی در ابزارهای کنترل نسخه توزیع شده که بسیار محبوب است امکان ایجاد شاخه محلی می باشد. این شاخه ها سبک و قوی هستند و به راحتی ایجاد می شوند. جریان کاری معمول این است که برنامه نویس برای داستان جاری که روی آن کار می کند یک شاخه ایجاد می کند. این فرایند در شکل زیر قابل مشاهده است. شکل 5 کار روی یک شاخه برای یک داستان
تغییرات جدید از خط یکپارچه سازی اصلی دریافت شده مطابق شکل زیر به شاخه اصلی اضافه می شود. شکل 6 تغییرات روی داستان های دیگر از خط یکپارچه سازی اصلی دریافت شده است
به جای تلفیق دو شاخه که در شکل زیر قابل مشاهده است، پدرِ شاخهِ داستان مربوطه تغییر کرده (rebased) و روی تغییرات جدید ساخته می شود. این ساختار در شکل بعدی قابل مشاهده است. شکل 7 تلفیق دو شاخه
شکل 8 تغییر پدرِ شاخه
تغییر پدر با تلفیق دو شاخه متفاوت است. در تلفیق یک شاخه ایجاد می شود که دو پدر دارد. تغییر پدر باعث می شود یک شاخه با یک پدر ایجاد شود که تاریخچه ساده تر و قابل فهم تری ایجاد می کند. باید در نظر داشته باشید که تغییر پدرِ شاخه نیز مانند تلفیق دو شاخه نیاز به رفع ناسازگاری ها دارد تا شاخه جدید روی محل جدید قابل ساخت شود. آیا ایجاد شاخه با استراتژی یکپارچه سازی مداوم در روش های چابک تناقض دارد؟ یک نقد به فرایند ارائه شده وجود دارد. این نقد بدین شرح است که ایجاد شاخه در تیم های چابک نمی تواند انجام شود چرا که با ایده یکپارچه سازی مداوم تناقض دارد. زمانی که شاخه روی کد ایجاد می شود کد را از یکپارچه بودن خارج می کند، آگاهی تیم از کل پروژه را کاهش می دهد و ممکن است تلفیقات زیادی با ناسازگاری های زیادی ایجاد کند. اولین پاسخ این نقد به این نکته مربوط است که در تیمهای چابک کدی که کار می کند به عنوان روشی برای اندازه گیری میزان پیشرفت تیم استفاده می شود. به همین دلیل کدی که کامپایل نمی شود یا unit tests (تست های واحد) را پشت سر نگذاشته است نباید با کدهای دیگر یکپارچه شود. چرا که اگر کد خراب در مخزن وجود داشته باشد، نسخه کامل و درستی از پروژه برای ارائه به مشتری وجود ندارد و فضای کاری تمام افراد تیم نیز به کد خراب آلوده می شود. درعین حال لازم است کدی که هنوز به مرحله ارائه به مشتری نرسیده است میان افراد تیم منتقل شود. به همین دلیل استفاده از روش های ایجاد شاخه ضروری است. دومین پاسخ در این نکته است که وقتی یک خط یکپارچه سازی وجود دارد، تغییرات به صورت مداوم روی آن قرار می گیرند. در این صورت تغییرات جدید نسبت به کل کد بسیار کوچک خواهند بود. به همین دلیل فهمیدن این که برنامه نویس با ایجاد تغییرات به دنبال تحقق چه هدفی بوده است بسیار دشوار می شود. در روش های ایجاد شاخه ایجاد تغییرات و تلفیق آن ها روی شاخه های کوچک تری انجام می شود. به همین دلیل مدیریت و فهم دلیل ایجاد تغییرات برای تمام افراد تیم راحت تر خواهد بود. چرا ابزار کنترل نسخه توزیع شده از ابزار کنترل نسخه مرکزی بهتر است؟ نقد دیگری که به فرایند ارائه شده وارد می شود در این است که ابزارهای کنترل نسخه توزیع شده ویژگی جدیدی نسبت به ابزارهای کنترل نسخه مرکزی ندارند. به همین جهت به طور مثال تفاوت مهمی میان ابزار Git و CVS وجود ندارد. تمام جریان های کاری و روش های ایجاد شاخه که در این مقاله مطرح شده است می توانند با ابزارهای کنترل نسخهی مرکزی مانند CVS نیز پیاده سازی شوند ولی مشکلاتی در این راه وجود دارد. اگر بخواهیم از ابزارهای کنترل نسخه مرکزی استفاده کنیم ایجاد شاخه به ازای هر فرد در یک تیم حداقل ۱۲ شاخه به علاوه یک شاخه اصلی ایجاد می کند که برنامه نویس تمام آن ها را میبیند. در حالی که در مراحل اولیه برنامه نویس تنها به شاخه خود و شاخه اصلی نیاز دارد. اگر تعداد افراد تیم بیشتر شود تعداد شاخه ها بیشتر شده و مدیریت آن ها برای هر فرد دشوارتر می شود. در ابزارهای کنترل نسخه توزیع شده هر فرد تنها از شاخه خود و شاخه نگهبان مخزن اطلاع دارد که مدل بسیار ساده تری است. مشکل دیگر در این است که تمام شاخه ها در ابزارهای مرکزی در یک دامنه نام گذاری می شوند. به همین دلیل لازم است هر شاخه نام یکتایی داشته باشد. این موضوع انتخاب و مدیریت نام ها را برای افراد دشوار می کند. در حالی که در ابزارهای توزیع شده انتخاب نام می تواند توسط هر فرد به صورت محلی انجام شود. مشکل بزرگ تر دیگری وجود دارد. با وجود ایجاد شاخه های زیاد در ابزارهای مرکزی راهی برای محدود کردن دسترسی افراد به شاخه ها وجود ندارد. به همین جهت همیشه این احتمال هست که برنامه نویس کد را روی شاخه اشتباهی قرار دهد. این موضوع با توجه به وجود مشکل نام گذاری ریسک بالاتری ایجاد میکند. در حالی که در ابزارهای توزیع شده هیچ کس دسترسی نوشتن روی شاخه های افراد دیگر را ندارد. به همین جهت ریسک قرار دادن کد روی شاخه اشتباه از بین میرود. نتیجه گیری: در این مقاله نشان داده شد روش های ایجاد شاخه به تیم های چابک کمک می کنند تا چابک تر شوند. همچنین نشان داده شد ابزارهای کنترل نسخه توزیع شده از ابزارهای کنترل نسخه مرکزی برای تیم های چابک انعطاف پذیری بیشتری دارند. تفاوت های مهم میان این دو نوع ابزار در جدول زیر خلاصه شده است. RE: کنترل نسخه چیست؟ - mortezafs - 02-21-2014 02:40 AM سلام و خسته نباشید تصاویر دارای ایراد هستن لطفا اصلاح کنید RE: کنترل نسخه چیست؟ - agotd - 02-27-2014 05:19 PM دوست عزیز با سلام متاسفانه تصاویر از روی سرور پاک شده و الان اصلا موجود نیست که بتونم لینکهاش رو دریت کنم روی کامپیوتر خودم هم ندارم خیلی عذر می خوام |