نظرات مطالب
4# آموزش سیستم مدیریت کد Git : نصب و پیکر‌‏بندی

با سلام و عرض خسته نباشید به همه‌ی دوستان و همکاران

سوالی که بنده داشتم این بود که چرا و به چه علتی با وجود ابزاری مثل visual studio team foundation server 2010 , 2012  باید با ابزاری مثل git کار کرد و البته با توجه به اینکه دوستان این سایت یا وبلاگ عموما در حوضه دات نت هستند این سوال مهم‌تر هم میشه ، در مورد مطالب در خصوص git  باید بگم طرز کار کردن با این ابزار بسیار پیچیده‌تر و غیر اصولی‌تر از tfs هست ، مثلا اینکه خود فایل رو پس از تغییر نگهداری میکنه یک نقطه ضعفه ولی نویسنده مطلب از اون به عنوان نقطه قوت یاد کرده ، اگر فایل به صورت مجموعه تغییرات ذخیره بشه هم حجم اطلاعات ذخیره شده کاهش پیدا میکنه و هم منبع نگهداری سورس‌ها میتونه مثل ماشین زمان ما رو به جلو و عقب ببره و محدودیتی نخواهد داشت ، در هر حال با توجه به محصول مایکروسافت بودن tfs  و رایگان بودن git فکر کنم حتی مقایسه این دو حتی درست هم نباشه.

با تشکر از تمامی زحمات شما دوستان عزیز

مطالب
طبقه بندی Bad Code Smell ها
نقل قول‌های زیادی، در مورد کیفیت کد وجود دارند. دستور العمل‌های فراوانی نیز در این راستا وجود دارند. یکی از ابزارهایی که برای نوشتن کدهایی با کیفیت مطلوب وجود دارد، مجموعه الگوهای بد کد نویسی است که به Code smell یا بوی بد کد مشهور هستند.  
بوی بد کد، نشانه‌هایی در کد هستند که حکایت از مشکلات عمیق‌تری دارند. بوی بد کد مساوی با باگ نیست. ولی خطر افزایش باگ‌ها و یا مشکلاتی را در آینده، به دنبال خواهند داشت. بوی بد کد معمولا حاصل رعایت نکردن یک سری اصول اولیه برنامه نویسی و یا طراحی شیء گرا هستند. 
برای بهبود کیفیت نرم افزار در دراز مدت نیاز است موارد بوی بد کد به دقت بررسی و رفع شوند. رفع شدن آنها ریسک انباشته شدن بوی بد کد را در پروژه کم خواهد کرد. یکی از فواید جلوگیری از انباشته شدن چنین الگوهای بدی در پروژه، بهبود فرآیند نگهداشت آن می‌باشد که موضوعی بسیار مهم برای چابکی یک تیم نرم افزاری است. 
هنگام مشاهده‌ی بوی بد، در بخشی از کدها، معمولا اولین اقدام، رفع آن است (Refactoring). در فرآیند رفع آن ممکن است الگوهای بد دیگری در کد یافت شوند که با آنها نیز به همین صورت برخورد خواهد شد. 
انوع بوهای بد کد به دسته‌های زیر طبقه بندی می‌شوند. 

کدهای متورم (Bloaters) 


این دسته در واقع تکه کدهایی (متد، کلاس و ...) هستند که به دلیل بزرگی بیش از اندازه عملا امکان کار با آن‌ها وجود ندارد. این بخش‌های بزرگ کد معمولا با توسعه تدریجی محصول ایجاد و روی هم انباشته می‌شوند. بوهای بد این دسته بندی به صورت زیر هستند:

1 - متدهای بلند (Long method): در این الگوی بد، متدها تعداد خطهای زیادی از کد را شامل می‌شوند. به طور معمول متدهایی با تعداد خطوط بیشتر از 10 خط، متدهای بلند محسوب می‌شوند. نکته قابل توجه این است که هیچ کس متدی را با تعداد خطوط زیاد طراحی نمی‌کند! معمولا به مرور زمان تعداد خط‌های یک متد افزایش می‌یابند. 
2 - کلاس‌های بزرگ (Large class): کلاسی که تعداد فیلدها، متدها و خطوط کد زیادی دارد. 
3 - وسواس استفاده از متغیرهای داده‌ای اولیه (Primitive obsession): این بوی بد معمولا به سه شکل بروز می‌کند. 
  • استفاده از متغیرهای اولیه بجای ساختارهای کوچک برای کارهای اولیه مانند Currency, DateTime, PhoneNumber 
  • استفاده از constant‌ها برای کد کردن اطلاعات مانند USER_ADMIN_ROLE = 1 
  • استفاده از constant‌های رشته‌ای به عنوان نام فیلدها در آرایه‌های داده 
4 - تعداد پارامترهای زیاد متد (Long parameter list): تعداد پارامترهای بیشتر از سه یا چهار عدد در یک متد. 
5 - توده داده (Data clumps): در بعضی موارد ممکن است از متغیرها به صورت دسته‌ای در مکان‌های مختلف کد استفاده شود. مانند استفاده از دسته‌ای از متغیرها برای نگه داشتن اطلاعات مربوط به اتصال پایگاه داده. این دسته‌ها باید به کلاس‌های حمل کننده داده خود تغییر کنند. 
 

بد استفاده کنندگان از شیء گرایی (Object orientation abusers)  


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

1 - گذاره‌های switch: وجود یک گذاره switch پیچیده یا دنباله‌ای از گذاره‌های if  
2 - درخواست رد شده (Refused request): در این حالت یک کلاس مجموعه محدودی از اعضای کلاس پدر خود را پیاده سازی می‌کند و باقی اعضای کلاس پدر یا بدون استفاده می‌مانند یا با استفاده از پرتاب کردن استثناء (Exception throwing) از کار انداخته می‌شوند. 
3 - فیلد موقتی (Temporary field): در این حالت متغیرها مقدار خود را در شرایط خاصی می‌گیرند و در بقیه شرایط خالی هستند. 
4 - کلاس هایی دقیقا مشابه در کارایی ولی متفاوت در مشخصات (Alternative Classes with Different Interfaces): دو کلاس دقیقا یک کار را انجام می‌دهند ولی نام اعضای آنها (متد و ...) متفاوت است. 

جلوگیری کنندگان از تغییر(Change preventers) 


این نشانه‌ها حاکی از این دارند زمانیکه تغییری در یک بخش کد نیاز باشد، در راستای آن حتما باید دیگر بخش‌های کد نیز به مقدار زیادی تغییر کنند. در این حالات اعمال تغییرات و نگهداری کد به شدت سخت خواهد شد. 
مواردی که در این دسته بندی قرار دارند به صورت زیر می‌باشند:  

1 - تغییر واگرا (Divergent change): این حالت زمانی اتفاق می‌افتد که برای اعمال یک تغییر به کلاس نیاز است متدهای زیادی را تغییر دهید. به طور مثال به ازای هر نوع محصولی که به محصولات شما اضافه می‌شود باید متدهای ذخیره، بازیابی، جستجو را تغییر دهید. 
2 - Shotgun Surgery: این حالت شباهت زیادی به تغییر واگرا دارد. تنها تفاوت آن این است که در این حالت شما به ازای هر تغییر نیاز است کلاس‌های زیادی را تغییر دهید. تغییر واگرا در بدنه یک کلاس اتفاق می‌افتد. 
3 - سلسله مراتب موازی ارث بری (Parallel inheritance hierarchy): این مورد یکی کمتر درک شده‌ترین موارد است. در این حالت زمانی که یک زیر کلاس برای یک کلاس ایجاد می‌کنید به ازای آن ناخودآگاه مجبور می‌شوید یک زیر کلاس برای کلاس دیگری ایجاد کنید. 

کدهای غیر ضروری (Dispensables) 


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

1 - کامنت: یک متد، با مقادیر فراوانی از کامنت‌های توضیحی پر شده است. 
2 - کد تکراری: در این بوی بد، دو قطعه کد دقیقا مانند یکدیگر هستند. 
3 - کلاس داده (ِData class): کلاس‌هایی که تنها فیلدهای اطلاعاتی در آنها وجود دارند و متدهای خامی که جهت دریافت یا ذخیره اطلاعات در آنها استفاده می‌شوند. این کلاس‌های معمولا هیچ روال منطقی ای در خود ندارند. یکی از قدرت‌های شیء گرایی افزودن رفتار به کلاس‌ها در کنار اقلام اطلاعاتی موجود در آن است.  
4 - کلاس تنبل (Lazy class):  اگر کلاس کار چندانی که درخور نگهداری و توسعه باشد، انجام نمی‌دهد بهتر است از بین برود. 
5 - کد مرده (Dead code): متغیر، پارامتر، متد یا کلاسی که دیگر هیچ استفاده‌ای از آن متصور نیست و هیچ استفاده‌ای در حال حاضر از آن وجود ندارد. 
6 - کلی نگری بیش از اندازه (Speculative Generality): این الگو نیز کدهایی را شامل می‌شود که بلااستفاده هستند. ولی دلیل بلااستفاده بودن آن کلی نگری و دور اندیشی بدون دلیل است. معمولا کدهای تولیدی برای شرایط فعلی و پیش‌بینی آینده تولید می‌شوند. اگر این پیش‌بینی آینده به درستی و بر مبنای واقعیات انجام نشود، معمولا نتیجه کار، طراحی و پیاده سازی ای بی فایده و بلااستفاده خواهد بود. 

کدهایی بیش از اندازه وابسته به هم (Couplers) 


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

1- متد حسود (Feature envy): متدی که از اعضای یک شیء دیگر بیشتر از اعضای کلاس خود استفاده می‌کند! این اتفاق معمولا زمانی می‌افتد که فیلدهایی به یک "کلاس داده" منتقل می‌شوند. وقتی این اتفاق می‌افتد یکی از راه حل‌ها، انتقال روالهای استفاده کننده از فیلدها به "کلاس داده" مربوطه است.
2 - کلاس‌های بیش از اندازه صمیمی (Inappropriate Intimacy): کلاس‌ها از اعضای internal یکدیگر بیش از اندازه استفاده می‌کنند. کلاس‌های خوب کلاس‌هایی هستند که کمترین اطلاعی را از وضعیت داخلی یکدیگر دارند. 
3 - کتابخانه‌های ناقص (Incomplete Library Class): زمانیکه کتابخانه‌ای آماده می‌شود، بالاخره روزی می‌رسد که این کتابخانه نیازهای پروژه را رفع نمی‌کند و نیاز به توسعه خواهد داشت. ولی از آنجایی که کتابخانه‌ها به صورت فقط خواندنی در اختیار پروژه‌ها قرار می‌گیرند، در صورتیکه توسعه دهنده اصلی آن از توسعه کتابخانه سر باز بزند، مشکلاتی بوجود خواهد آمد. 
4 - زنجیره فراخوانی‌ها (Message chain): زمانیکه یک متد در بدنه خود پیامی به شیء دیگری می‌فرستد که آن شیء نیز به خودی خود پیامی به شیء دیگری می‌فرستد (و الی آخر) یک زنجیره فراخوانی بوجود آمده است. در این روش بیرونی‌ترین استفاده کننده از متد در واقع وابسته به یک زنجیره‌ای از فراخوانی‌ها است که تغییر در هر قدمی از آن باعث خرابی خواهد شد. 
5 - دلال (Middle man): اگر کلاسی تنها کاری که انجام می‌دهد انتقال فراخوانی به کلاس دیگری است، دیگر نیازی به این کلاس وجود نخواهد داشت.

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

There a misinformed notions floating around the agile community that products and better than projects. That some how - unspecified and unsubstantiated  as usual - that projects are undesirable and focusing on products and their value - again unspecified how to measure that value and unsubstantiated that value measurement isn't what projects do as well. 

محصول ، مدیریت محصول و مدیریت پروژه
اشتراک‌ها
دانلود Microsoft Visual Studio Team Foundation Server 2013 with Update 3

Download Link: ISO File

Visual Studio Team Foundation Server 2013 is the source-code-control, project-management, and team-collaboration platform at the core of the Microsoft suite of Application Lifecycle Management (ALM) tools, which help teams be more agile, collaborate more effectively, and deliver quality software more consistently. 

دانلود Microsoft Visual Studio Team Foundation Server 2013 with Update 3
مطالب
Microsoft Test Manager - قسمت اول

مقدمه:

مدیریت آزمون مایکروسافت یا Microsoft Test Manager یک ابزار تست نویسی است که به تستر‌ها این اجازه را می‌دهد تا بتوانند برای UI برنامه‌های خود یا sprint‌های پروژه خود تست بنویسند. این ابزار برای نوشتن آزمون‌های پیشرفته و مجتمع سازی مدیریت طرح‌های تست یا test plans همراه با موردهای تست یا test case در طول توسعه برنامه است. یکی از مزایایی که این ابزار دارد این است که در طول انجام تست می‌توانید اشکالات تست را ثبت کنید و هم چنین می‌توانید شرحی در مورد انجام تست یا اشکالی که در آن تست وجود دارد، ثبت کنید. همچنین می‌توانید گزارشی از تست هایی که انجام داده اید و پاس شدن یا پاس نشدن تست‌ها و تاریخ انجام آن‌ها را نیز مشاهده کنید. قبل از کار با نرم افزار MTM باید یک سری مطالب مهم را در مورد انجام تست و مفهوم Agile بدانیم.

استراتژی تست:

زمانی که شما تست Agile را معرفی می‌کنید تیم برنامه نویسی شما می‌تواند بر روی تست‌های شما هم در سطح sprint و هم در سطح پروژه تمرکز کنند. تست در سطح sprint شامل تست هایی می‌شود که همه user story‌ها در بر بگیرد یعنی در واقع همان تست‌های واحد شما می‌شود. در سطح پروژه هم شامل تست هایی می‌شود که چندین sprint را در بر می‌گیرد که در واقع می‌توان تست‌های integrated گفت. بهتر است زمانی که تیم برنامه نویسی کدنویسی می‌کنند شما طرح تست‌های خود را بسازید و برای انجام تست کاملا آماده باشید. این تست‌ها شامل تست واحد، تست performance، تست امنیتی و تست usability و غیره می‌باشد.

برای آماده کردن تست Agile در ابتدا شما باید یک تاریخچه یا history از برنامه یا سیستم خود داشته باشید. شما می‌توانید با استفاده از Microsoft Test Manager طرح تست خود را برای هر یک از sprint‌های پروژتان بسازید و موردهای تست را مشخص کنید.

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

تست یک فرآیند تکراری می‌باشد که همزمان با اجرای پروژه تان صورت می‌گیرد در زیر می‌توانید فرآیند کار تست و انجام کدنویسی را مشاهده نمایید:

Test Planning:

Test Planning فرآیندی است که به تیم شما کمک می‌کند تا درک درستی از پروژه داشته باشند و همچنین تیم را برای انجام هر گونه تستی آماده کند. تست Agile در سطح Sprint انجام می‌شود که در هر Sprint تیم شما تست هایی را ایجاد می‌کنند تا user story هایی که در هر Sprint وجود دارد، مورد بررسی قرار گیرند. در شکل زیر قالبی از test plan‌های شما در یک پروژه را نمایش می‌دهد:

البته این قالب‌ها بر اساس سلیقه شخصی است اما در کل می‌توانیم قالب تست را به صورت بالا در نظر بگیریم.

همیشه باید این را در نظر داشته باشیم که در طول هر sprint حتما باید تست‌ها را اجرا کرده و در صورت وجود خطا، آن خطا را رفع کنیم تا در مراحل بالاتر با مشکلی مواجه نشویم. در قسمت بعد با Microsoft Test Manager و روش‌های نوشتن sprint و تست‌ها آشنا خواهیم شد.

مطالب
8# آموزش سیستم مدیریت کد Git
در این بخش به بررسی چگونگی ایجاد branchها و همچنین نحوه‌ی merge کردن آن‌ها خواهیم پرداخت.

Branch:
در این مقاله به بررسی شاخه‌ها و همچنین ضرورت ایجاد آن‌ها پرداخته شده است. جهت ایجاد یک شاخه می‌توان از دستور زیر استفاده کرد:
git branch  [branch name]
توجه کنید که دستور فوق تنها یک شاخه را ایجاد می‌کند؛ اما همچنان git در شاخه جاری باقی می‌ماند.
همچنین جهت مشاهده شاخه‌های ایجاد شده از دستور زیر استفاده می‌شود:
git branch
شاخه جاری، با یک علامت * در کنار آن مشخص می‏شود:

در حالت پیش‌فرض، تمامی عملیات در git، در شاخه master انجام می‌گیرد. برای تعویض و رجوع به شاخه ایجاد شده می‌توان از دستور checkout استفاده کرد. همانطور که قبلا گفته شد، یکی دیگر از کاربردهای این دستور تعویض شاخه‌ها است:
git checkout [branch name]
همچنین می‌توان به صورت همزمان هم شاخه جدید ایجاد کرد و هم به این شاخه جدید سوئیچ نمود:
git checkout -b [branch name]

تذکر:
در صورتیکه working tree تقریبا clean نباشد، یعنی تغییراتی در فایل‌ها صورت گرفته باشد که این تغییرات هنوز در repository ذخیره نشده باشند، git امکان تعویض شاخه را نخواهد داد. علت تقریبا به این جهت است که در مواردی git می‌تواند برخی تفاوتها را نادیده بگیرد؛ مثلا اگر فایلی در شاخه‏‏‌ی دیگر وجود نداشته باشد. در این حالت سه راهکار پیش روی کاربر است:
۱) حذف تغییرات
۲) ذخیره تغییرات در repository
۳) استفاده از stash
دو مورد نخست مشخص هستند و استفاده از stash در ادامه همین مقاله آورده شده است.

برای حذف یک شاخه ایجاد شده از دستور زیر استفاده می‌شود:
git branch -d [branch name]
در این حالت نباید در شاخه‌ای باشیم که قصد حذف آن را داریم. همچنین اگر تغییرات در شاخه والد موجود نباشند، git هشداری را مبنی بر آن‌که «شاخه دارای تغییراتی است که در صورت حذف آن از بین می‌روند» به کاربر می‌دهد. در این حالت اگر مسر به انجام حذف باشیم، دستور فوق را این بار با D- به کار می‏‌بریم. بنابراین جهت جلوگیری از اشتباه بهتر است دستور حذف ابتدا با d انجام شود و در صورت نیاز از D استفاده شود.
برای تغییر نام یک شاخه از دستور زیر استفاده می‌شود:
git branch -m [old name][new name]

ادغام شاخه‌ها:
معمولا بعد از آن‌که ویرایش فایل‌ها در یک شاخه به پایان رسید و فایل‌های نهایی تولید شدند، باید این فایل‌ها را در شاخه‌ای دیگر مثلا master قرار داد. برای این منظور، از دستور merge استفاده می‌شود. در هنگام merge باید در شاخه مقصد قرار داشت؛ یعنی در همان شاخه‌ای که قرار است فایل‌های شاخه‌ای دیگر با آن ادغام شوند.
برای ادغام یک شاخه به شاخه دیگر از دستور زیر استفاده می‌شود:
git merge [branch name]

نکته مهم:
در git  دو نوع ادغام وجود دارد:
۱) fast forward
۲) real merge
حالت اول زمانی اتفاق می‌افتد که در شاخه والد، commit جدیدی ثبت نشده باشد. در این حالت در هنگام merge، اشاره‌گر آخرین فرزند والد، به اولین commit در شاخه‌ی فرزند اشاره می‌کند و دقیقا مانند یک زنجیر دو شاخه به هم متصل می‌شوند. اما اگر در شاخه والد بعد از تشکیل شاخه فرزند commit هایی صورت گرفته باشد، ما یک real merge خواهیم داشت.

تداخل یا conflict:
در هنگام merge کردن شاخه‌ها گاهی این مساله به وجود می‌آید که فایل‌هایی که قرار است تغییرات آن‌ها با هم ادغام شوند، به گونه‌ای ویرایش شده‌اند که git نمی‌تواند عمل merge را انجام دهد. به عنوان مثال تصور کنید فایلی دارای ۱۰ خط است. در شاخه والد خطوط ۱ و ۴ و در شاخه فرزند خطوط ۲ و ۴ ویرایش شده‌اند. git برای ادغام فایل، برای خطوط ۱ و ۲ دچار مشکلی نیست؛ زیرا خط یک را از شاخه والد و خط ۲ را از شاخه فرزند بر می‌دارد. اما برای خط ۴ چه کار کند؟ git نمی‌تواند تصمیم بگیرد که داده نهایی از خط شماره ۴ فرزند است و یا والد. به همین جهت در این‌جا ما یک merge conflict داریم. برای رفع این مشکل یا می‌توان با استفاده از دستور زیر از انجام merge صرفنظر کرد:
git merge --abort
و یا به صورت دستی و یا با استفاده از برخی از ابزارهای موجود، اقدام به رفع دوگانگی فایل‌ها کرد. بعد از رفع conflictها با دستور:
git merge --continue
می‌توان ادامه ادغام را خواستار شد.

Stash:
در هنگام توضیح چگونگی تعویض شاخه‌ها، به مطلبی به نام stash اشاره شد. Stash در واقع مکان جدایی در git است که از آن به عنوان محلی جهت ذخیره‌سازی موقت تغییرات استفاده می‌شود. عملکرد stash مانند commit می‌باشد. با این تفاوت که SHA-1 منحصر به فردی برای آن در نظر گرفته نمی‌شود. بنابراین stash محلی است که به طور موقت می‌تواند تغییرات فایل‌ها را ذخیره کند.
برای ایجاد یک stash از دستور زیر استفاده می‌شود:
git stash save "[stash name]"
همچنین جهت مشاهده تمامی stash‌های ذخیره شده از دستور زیر می‌توان استفاده کرد:
git stash list
در صورت اجرای این دستور، همانطور که در شکل زیر مشخص است، هر stash توسط یک شماره به صورت:
stash@{number}
مشخص می‌شود.

برای مشاهده تغییرات در یک stash از دستور زیر استفاده میشود:
git stash show stahs@{[number]}
همچنین در صورتیکه جزئیات بیشتری مورد نیاز باشد، می‌توان p- را قبل از شماره stash به دستور فوق اضافه کرد.
در صورتیکه بخواهید stash ایجاد شده را حذف کنید، می‌توانید از دستور زیر استفاده کنید:
git stash Drop [stash name]
همچنین می‌توان با دستور زیر کل stash‌های موجود را حذف نمود:
git stash clear
برای اعمال تغییرات با استفاده از stash می‌توان از دو دستور استفاده کرد:
۱) pop : در این حالت همانند ساختار پشته، آخرین stash اعمال و از لیست stashها حذف می‌شود.
۲) apply : در این دستور، در صورتیکه شماره stash ذکر شود، آن stash اعمال می‌شود. در غیر این صورت، آخرین stash استفاده خواهد شد. تفاوت این دستور با دستور فوق در این است که در اینجا stash بعد از استفاده حذف نمی‌گردد.


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

در شاخه master فایل readme5 اضافه شده و در شاخه a2 فایل readme4 اضافه شده و بعد تغییری در آن ذخیره شده است

شاخه a1 در master ادغام شده است

شکل درختی شاخه‌ها پس از ادغام



در شکل فوق از دستور rebase استفاده شده است


شکل شاخه‌ها بعد از اعمال rebase



همانطور که مشاهده می‌شود با سوئیچ به شاخه master هنوز head در محل قبلی خود است




با اعمال دستور ادغام، head به محل آخرین commit منتقل می‌شود


اکنون می‌توان شاخه a1 را حذف کرد. همانطور که دیده می‌شود، به نظر می‌رسد این شاخه هیچگاه وجود نداشته است.

تذکر:
بعد از انجام دستور rebase باید از دستور merge استفاده کرد. زیرا هر شاخه برای خود head جداگانه‌ای دارد. بعد از اجرای این فرمان، هنوز head در شاخه مقصد به آخرین فرمان خود اشاره می‌کند. در آخرین فرمان، شاخه‌ای اضافه شده، بنابراین اجرای دستور merge حالت fast forward را پیاده می‌کند و head به آخرین commit منتقل می‌شود.

تذکر:
همانطور که مشاهده کردید، دستور rebase به صورت فوق سوابق شاخه را از بین می‌برد. بنابراین نباید از این دستور برای شاخه‌های عمومی یعنی آنهایی که دیگران تغییرات آنها را دنبال می‌کنند استفاده کرد.
شکل استفاده از این دستور به صورت زیر است:
git rebase [destination branch]
یا
git rebase [destination][source]
همانند دستور merge این دستور نیز ممکن است سبب ایجاد تداخل شود و  برای رفع این موضوع باید مانند merge عمل کرد؛ این دستور نیز دارای دو اصلاح کننده abort-- و continue-- می‌باشد

تذکر مهم :

به تفاوت محل درج ادغام‏‌ها در merge و rebase توجه کنید.

دستور  cherry-pick :
با استفاده از این فرمان می‌توان یک یا چند commit را از شاخه‌ای برداشته و در شاخه‌ی دیگری اعمال کنیم. در واقع دستور  cherry-pick  همانند بخشی از دستور rebase است. با این تفاوت که rebase در واقع چندین  cherry-pick  را یک‌جا انجام می‌دهد. البته در  cherry-pick هر commit بدون تغییر باقی می‏‌ماند.
بیشترین کاربرد این دستور برای اعمال patchها و رفع باگ‌ها در یک شاخه است. این دستور به صورت زیر استفاده می‌شود:
git cherry-pick [branch name]
 
مطالب
مقدمه‌ای بر بازسازی کد (Refactoring)
بازسازی کد یا  Refactoring، یکی از روال‌های بسیار مهم در حفظ کیفیت نرم افزار است. انجام به موقع و مداوم این روال در یک پروژه نرم افزاری، اثرات بلند مدت بسیار مثبتی را برای آن خواهد داشت. این نوشتار مقدمه کوتاهی بر مفاهیم ابتدایی و سوالاتی مهم در این زمینه است. 

تعریف بازسازی کد

از نظر لغوی Refactoring به معنی «بازسازی» است و در منابع مهندسی نرم افزار، بازسازی کد به صورت زیر تعریف شده است: 
بازسازی ساختار درونی یک نرم افزار که باعث سهولت در درک آن و سادگی نگهداری آن می‌شود، بدون تغییر رفتار بیرونی آن  
چند نکته در تعریف بالا قابل توجه است: 
  • Refactoring بازسازی است، نه بازنویسی
  • بازسازی مربوط به ساختار درونی یک نرم افزار است؛ نه رفتاری که مشتریان از یک نرم افزار یا کامپوننت انتظار دارند
  • حاصل بازسازی باید سهولت درک کد و سادگی نگهداری آن باشد 


چرا کد را بازسازی کنیم؟ 

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

1-  طراحی نرم افزار را بهبود می‌بخشد 

زمانیکه کد به طور منظم بازسازی نشود، طراحی کلی آن رو به زوال خواهد رفت. هنگام ایجاد تغییر در بخشی از کد، ممکن است تنها هدف کوتاه مدت درست کار کردن آن بخش، مد نظر برنامه نویس باشد و به دلایل مختلفی مانند کمبود زمان، به نتایج بلند مدت آن تغییر توجه نشود. یکی از مزایای بازسازی کد، ایجاد تعادل بین تاثیرات کوتاه مدت و تاثیرات بلند مدت اعمال تغییرات بر روی کد است؛ به طوری که طراحی و تفکر کلی کد نویسی یک سیستم نرم افزاری، رو به بهبود برود. بهبود طراحی نرم افزار به درک کدهای آن، ایجاد آسان‌تر تغییرات و افزودن امکانات جدید، کمک بسیاری خواهد کرد. 

2-  درک کد را آسان‌تر می‌کند 

یکی از مزیت‌های کد خوب، درک آسان آن توسط سایر افراد است. هنگام بازسازی کد، با کدی مواجه هستیم که کار می‌کند، ولی نظم و طراحی درستی ندارد. درک آسان کد، یکی از کلیدی‌ترین نکات جهت سهولت نگهداری یک نرم افزار است.

 3- به یافتن خطاها کمک می‌کند 

یافتن تمامی باگ‌ها در زمان نوشتن یک کد، به نظر می‌رسد غیر ممکن باشد. اما اقدام به بازسازی کد می‌تواند قدمی باشد برای بازنگری و بهبود ساختار آن. زمانیکه ساختار کد خواناتر و منظم‌تر شد، یافتن برخی باگ‌ها نیز آسان‌تر خواهند شد. 

4-  سرعت توسعه را بالا می‌برد 

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

چه زمانی کد را بازسازی کنیم؟ 

روش‌های مختلفی برای زمان بندی انجام بازسازی کد مطرح است. یکی از پرکاربردترین زمان بندی‌ها برای انجام بازسازی کد به صورت زیر می‌باشد: 
  • زمانیکه امکان جدیدی اضافه می شود 
  • زمانیکه باگ یا اشکالی، رفع می شود 
  • زمان بازبینی کد یا Code review