آموزش TypeScript #1
سوالی که همیشه من داشته ام این است .... چرا خود زبان JavaScript را تغییر نمیدهند؟
مسلما TypeScript و CoffeeScript برای برطرف کردن ضعف JavaScript بوجود آمده اند اما چرا خود مشکل را برطرف نمیکنند؟
میتوانستند همانند ارائه HTML5 و CSS3 نسخه جدیدی از JavaScript ارائه کنند که سختیهای کار با JavaScript را برطرف کرده باشند!
// api.model.ts export interface Customer { id: number; name: string; } export interface User { id: number; isActive: boolean; }
// using the interfaces import { Customer, User } from './api.model'; export class MyComponent { cust: Customer; }
// api.model.ts namespace ApiModel { export interface Customer { id: number; name: string; } export interface User { id: number; isActive: boolean; } }
// using the interfaces export class MyComponent { cust: ApiModel.Customer; }
// api.v2.model.ts namespace ApiModel { export interface Order { id: number; total: number; } }
export class MyComponent { cust: ApiModel.Customer; order: ApiModel.Order; }
// api.model.d.ts interface Customer { id: number; name: string; }
// using the interfaces of d file export class MyComponent { cust: Customer; }
// lib.es5.d.ts type Partial<T> = { [P in keyof T]?: T[P]; };
import { Customer } from './api.model'; export class MyComponent { cust: Partial<Customer>; / ngOninit() { this.cust = { name: 'jane' }; } }
if (false) { console.log('x'); }
if (false) { // @ts-ignore console.log('x'); }
مطلبی رو در سایت آقای اسکات هنسلمن دیدم که به نظرم برای برگرداندن به فارسی جالب اومد. شاید باعث شود که اندکی به فکر فرو رویم که ... چکار داریم میکنیم و قرار است به کجا برویم/برسیم.
- - آیا هنوز کد مینویسید؟ آیا به آن علاقمندید؟!
- - آیا میدانید SOLID چیست؟
- - آیا میدانید SRP مخفف چیست و چه اهمیتی دارد؟
- - پروژهای مبتنی بر یک فناوری جدید به شما انتساب داده شده است. چگونه آنرا آغاز خواهید کرد؟
- - در مورد IOC یا Inversion of control چه میدانید؟ ارتباط آن با dependency injection چیست؟
- - برنامه 2 tier با برنامهی 3 tier چه تفاوتی دارد؟
- - فلسفهی وجودی Interface چیست و چه اهمیتی دارد؟
- - الگوی Repository را شرح دهید. الگوی Factory چیست؟ چرا الگوهای طراحی برنامه نویسی شیءگرا مهم هستند؟
- - Anti-patterns کدامند؟ توضیح دهید.
- - آیا تابحال اسم Gang of Four به گوشتان خورده است؟ در چه موردی است؟
- - ارتباط الگوهای MVP ، MVC و MVVM در چیست؟ هر کدام از این الگوها در چه زمانیهایی بهتر است بکار گرفته شوند؟
- - مفهوم جداسازی وابستگیها (Separation of Concerns) چیست. مزایا و معایب آن کدامند؟
- - سه ویژگی اصلی طراحی شیءگرا را نام برده و توضیح دهید.
- - یک الگوی طراحی را توضیح دهید که در خانوادهی الگوی Factory قرار نمیگیرد. این الگو چه زمانی بهتر است بکار برده شود و چگونه؟
- - فرض کنید یک پروژهی قدیمی را که از مشکلات حاد نگهداری رنج میبرد، به شما انتساب دادهاند. چه فاکتورها و اقداماتی را جهت بهبود این وضعیت درنظر گرفته و چگونه برنامه را به سمت یک پروژهی پایدار پیش خواهید برد؟
- - مفهوم Service Orientation چه اثری را بر طراحی سیستمها خواهد گذاشت؟ کجاها بهتر است استفاده شود؟
- - در مورد portfolio تمام برنامههایی که تاکنون بر روی آنها کار کردهاید توضیح دهید. شما چه نقشی در طراحی آن داشتهاید؟
- - منهای بانکهای اطلاعاتی رابطهای، با چه روشهایی جهت ذخیره سازی اطلاعات آشنایی دارید؟ مزایا و معایب آنها چیست؟
- - در مورد مفهوم convention over configuration توضیح دهید. آخرین مثال عملی که در این مورد دیدهاید چه بوده است؟
- - در مورد سیستمهای بدون حالت و با حالت (stateless and stateful) توضیح دهید. اثر هر کدام بر parallelism چیست؟
- - تفاوتهای بین Stubs و Mocks چیست و از هر کدام در کجاها استفاده خواهید کرد؟
- - مفهوم YAGNI را به همراه یک مثال عملی توضیح دهید.
- - sandbox چه معنایی دارد؟ آیا میتوانید مثالهایی عملی از این مفهوم را در سیستمهای موجود نام ببرید؟
- - حالتهای با و بدون قفل در مدلهای Concurrency چه تفاوتی دارند؟
- - زمانیکه از مدلهای با قفل و یا بدون قفل استفاده میکنید ممکن است به چه مشکلاتی برخورد کنید؟
- - مفهوم resource contention را توضیح دهید.
- - مدل بر مبتنی بر وظیفه با مدل مبتنی بر ریسمان چه تفاوتهایی دارند؟ ( task-based model & threaded model )
- - تفاوتهای بین asynchrony و concurrency را توضیح دهید.
مثال 1: یافتن زمانهای شروع رزرو کردن امکانات مختلف، توسط یک کاربر مشخص.
چگونه میتوان زمانهای شروع رزروهای کاربری به نام «David Farrell» را یافت؟
همانطور که در دیاگرام فوق مشاهده میکنید، به ازای هر ID کاربری در جدول کاربران، به دنبال ردیفهایی در جدول Bookings هستیم که این ID در آنها درج شدهاست. اما ... در EF-Core برخلاف SQL نویسی معمولی، ما کاری به ذکر قسمت اتصالی ON [Bookings].[MemId] = [Members].[MemId] نداریم. همینقدر که در کوئری نوشته شده به یک سر دیگر رابطه و خاصیت راهبری (navigation property) دیگری اشاره شود، خود EF-Core جوینی را به صورت خودکار تشکیل خواهد داد و شرط یاد شده را نیز برقرار میکند.
در قسمت اول این سری، در حین طراحی موجودیت کاربر، برای تشکیل سر دیگر رابطهی one-to-many آن، به جدول Bookings، خاصیت Member را نیز که بیانگر کلید خارجی به جدول کاربران است، اضافه کردیم:
namespace EFCorePgExercises.Entities { public class Booking { // ... public int MemId { set; get; } public virtual Member Member { set; get; } // ... } }
var startTimes = context.Bookings .Where(booking => booking.Member.FirstName == "David" && booking.Member.Surname == "Farrell") .Select(booking => new { booking.StartTime }) .ToList();
مثال 2: یافتن زمانهای شروع به رزرو شدن یک امکان خاص در مجموعه.
لیست زمانهای شروع به رزرو شدن زمین(های) تنیس را برای روز 2012-09-21 تولید کنید. خروجی آن باید به همراه ستونهای StartTime, FacilityName باشد.
طراحی موجودیت Booking، به همراه یک کلید خارجی به Facility نیز هست:
namespace EFCorePgExercises.Entities { public class Booking { // ... public int FacId { set; get; } public virtual Facility Facility { set; get; } // ... } }
int[] tennisCourts = { 0, 1 }; var date1 = new DateTime(2012, 09, 21); var date2 = new DateTime(2012, 09, 22); var startTimes = context.Bookings .Where(booking => tennisCourts.Contains(booking.Facility.FacId) && booking.StartTime >= date1 && booking.StartTime < date2) .Select(booking => new { booking.StartTime, booking.Facility.Name }) .ToList();
- در قسمت Where این کوئری چون booking.Facility ذکر شده، سبب ایجاد جوین خودکاری به جدول Facilities خواهد شد.
- علت استفادهی از دو تاریخ در اینجا برای یافتن اطلاعات تنها یک روز، ثبت زمان، به همراه تاریخ رزرو است. ستون تاریخ شروع، به صورت «2012-09-21 18:00:00.0000000» مقدار دهی شدهاست و نه به صورت «2012-09-21». البته در EF-Core راه دیگری هم برای حل این مساله وجود دارد. هر خاصیت از نوع DateTime، به همراه خاصیت Date نیز هست. برای مثال اگر بجای booking.StartTime نوشته شود booking.StartTime.Date (به خاصیت Date اضافه شده دقت کنید)، کد SQL حاصل، به همراه «CONVERT(date, [b].[StartTime])» خواهد بود که سبب حذف خودکار قسمت زمان این ستون میشود.
مثال 3: تولید لیست کاربرانی که کاربر دیگری را توصیه کردهاند.
چگونه میتوان لیست کاربرانی را یافت که کاربر دیگری را توصیه کردهاند؟ این لیست نباید به همراه ردیفهای تکراری باشد و همچنین باید بر اساس surname, firstname مرتب شود.
در اینجا به مفهوم جوین کردن یک جدول با خودش رسیدهایم. جدول کاربران، یک جدول خود ارجاع دهندهاست:
namespace EFCorePgExercises.Entities { public class Member { // ... public virtual ICollection<Member> Children { get; set; } public virtual Member Recommender { set; get; } public int? RecommendedBy { set; get; } // ... } }
var members = context.Members .Where(member => member.Recommender != null) .Select(member => new { member.Recommender.FirstName, member.Recommender.Surname }) .Distinct() .OrderBy(member => member.Surname).ThenBy(member => member.FirstName) .ToList();
مثال 4: تولید لیست کاربران به همراه توصیه کنندهی آنها.
چگونه میتوان لیست کاربران را به همراه توصیه کنندهی آنها تولید کرد؟ این لیست باید بر اساس surname, firstname مرتب شود.
var members = context.Members .Select(member => new { memFName = member.FirstName, memSName = member.Surname, recFName = member.Recommender.FirstName ?? "", recSName = member.Recommender.Surname ?? "" }) .OrderBy(member => member.memSName).ThenBy(member => member.memFName) .ToList();
همانطور که ملاحظه میکنید، نوع جوین خودکار تشکیل شده، Left join است و دیگر مانند جوینهای مثالهای ابتدای بحث، inner join نیست. در inner join، جدول سمت راست و چپ بر اساس شرط ON آنها با هم مقایسه شده و ردیفهای کاملا تطابق یافتهای بازگشت داده میشوند. کار Left join نیز مشابه است، با این تفاوت که در اینجا ممکن است برای جدول سمت چپ، هیچ ردیف تطابق یافتهای در جدول سمت راست وجود نداشته باشد (نوع آن بر اساس نال پذیری خاصیت RecommendedBy تشخیص داده شدهاست)؛ برای مثال یک کاربر ممکن است توسط کاربر دیگری توصیه نشده باشد (و RecommendedBy او نال باشد)، اما علاقمندیم که نام او در لیست نهایی حضور داشته باشد و حذف نشود.
یک نکته: در SQL Server تفاوتی بین left join و left outer join وجود ندارد و ذکر واژهی کلیدی outer کاملا اختیاری است. جدول موارد مشابهی در SQL Server که به یک معنا هستند، صورت زیر است:
A LEFT JOIN B A LEFT OUTER JOIN B A RIGHT JOIN B A RIGHT OUTER JOIN B A FULL JOIN B A FULL OUTER JOIN B A INNER JOIN B A JOIN B
مثال 5: تولید لیست کاربرانی که از زمین تنیس استفاده کردهاند.
چگونه میتوان لیست کاربرانی را تولید کرد که از زمین(های) تنیس استفاده کردهاند؟ خروجی این گزارش باید به همراه یک ستون جمع نام و نام خانوادگی و ستون نام زمین باشد. این گزارش نباید دارای ردیفهای تکراری باشد و همچنین باید بر اساس حاصل جمع نام و نام خانوادگی، مرتب شده باشد.
جدول Bookings به همراه دو کلید خارجی به جداول Facilities و Members است:
namespace EFCorePgExercises.Entities { public class Booking { // ... public int FacId { set; get; } public virtual Facility Facility { set; get; } public int MemId { set; get; } public virtual Member Member { set; get; } // ... } }
namespace EFCorePgExercises.Entities { public class Member { // ... public virtual ICollection<Booking> Bookings { set; get; } } }
int[] tennisCourts = { 0, 1 }; var members = context.Members .SelectMany(x => x.Bookings) .Where(booking => tennisCourts.Contains(booking.Facility.FacId)) .Select(booking => new { Member = booking.Member.FirstName + " " + booking.Member.Surname, Facility = booking.Facility.Name }) .Distinct() .OrderBy(x => x.Member) .ToList();
پس از آن برای حذف ردیفهای تکراری حاصل از گزارش، از متد Distinct استفاده شده و OrderBy نیز بر اساس خاصیت جدید Member، قابل تعریف است:
مثال 6: تولید لیست رزروهای گران قیمت
لیست رزروهای روز 2012-09-14 را تولید کنید که هزینهی آنها بیشتر از 30 دلار باشد. باید بخاطر داشت که هزینههای کاربران با مهمانها متفاوت است و هزینهها بر اساس Slotهای نیم ساعته محاسبه میشوند و ID کاربر مهمان همیشه صفر است. خروجی این گزارش باید به همراه نام کامل کاربر، نام امکانات مورد استفاده و هزینهی نهایی باشد. همچنین باید بر اساس هزینههای نهایی به صورت نزولی مرتب شود.
var date1 = new DateTime(2012, 09, 14); var date2 = new DateTime(2012, 09, 15); var items = context.Members .SelectMany(x => x.Bookings) .Where(booking => booking.StartTime >= date1 && booking.StartTime < date2 && ( (((booking.Slots * booking.Facility.GuestCost) > 30) && (booking.MemId == 0)) || (((booking.Slots * booking.Facility.MemberCost) > 30) && (booking.MemId != 0)) )) .Select(booking => new { Member = booking.Member.FirstName + " " + booking.Member.Surname, Facility = booking.Facility.Name, Cost = booking.MemId == 0 ? booking.Slots * booking.Facility.GuestCost : booking.Slots * booking.Facility.MemberCost }) .Distinct() .OrderByDescending(x => x.Cost) .ToList();
سپس بر اساس صفر بودن یا نبودن booking.MemId (کاربر مهمان بودن یا خیر)، شرط هزینهی بیشتر از 30 دلار اعمال شدهاست.
در آخر Select گزارش مورد نیاز، به همراه جمع نام و نام خانوادگی، نام امکانات استفاده شده و خاصیت محاسباتی Cost است که بر اساس مهمان بودن یا نبودن کاربر، متفاوت است.
متد Distinct ردیفهای تکراری حاصل از این گزارش را حذف میکند (محل درج آن مهم است) و متد OrderByDescending، مرتب سازی نزولی بر اساس خاصیت محاسباتی Cost را انجام میدهد.
مثال 7: تولید لیست کاربران به همراه توصیه کنندهی آنها، بدون استفاده از جوین.
در اینجا میخواهیم همان مثال 4 را بدون استفاده از جوین بررسی کنیم. بدون استفاده از جوین در اینجا به معنای استفاده از sub-query است (نوشتن یک کوئری داخل کوئری اصلی).
var members = context.Members .Select(member => new { Member = member.FirstName + " " + member.Surname, Recommender = context.Members .Where(recommender => recommender.MemId == member.RecommendedBy) .Select(recommender => recommender.FirstName + " " + recommender.Surname) .FirstOrDefault() ?? "" }) .Distinct() .OrderBy(member => member.Member) .ToList();
مثال 8: تولید لیست رزروهای گران قیمت با استفاده از یک sub-query.
هدف از این مثال، ارائهی روش حل دیگری برای مثال 6، به نحو تمیزتری است. در مثال 6، هزینهی رزرو را دوبار، یکبار در متد Where و یکبار در متد Select محاسبه کردیم. اینبار میخواهیم با استفاده از sub-queryها این محاسبه را یکبار انجام دهیم.
var date1 = new DateTime(2012, 09, 14); var date2 = new DateTime(2012, 09, 15); var items = context.Members .SelectMany(x => x.Bookings) .Where(booking => booking.StartTime >= date1 && booking.StartTime < date2) .Select(booking => new { Member = booking.Member.FirstName + " " + booking.Member.Surname, Facility = booking.Facility.Name, Cost = booking.MemId == 0 ? booking.Slots * booking.Facility.GuestCost : booking.Slots * booking.Facility.MemberCost }) .Where(x => x.Cost > 30) .Distinct() .OrderByDescending(x => x.Cost) .ToList();
هرچند کوئری SQL نهایی تولید شدهی توسط EF-Core آن، تفاوتی چندانی با نگارش قبلی ندارد:
کدهای کامل این قسمت را در اینجا میتوانید مشاهده کنید.
روشهای تولید اعداد یا رشته تصادفی:
1- معمولترین روش تولید یک کد شش رقمی با استفاده از کلاس random
[TestMethod] public void TestRandomClass() { var code = new Random().Next(100000, 999999); Assert.IsTrue(code.ToString().Length == 6); }
[TestMethod] public void TestRandomWithEnumerable() { var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; var random = new Random(); var result = new string( Enumerable.Repeat(chars, 6) .Select(s => s[random.Next(s.Length)]) .ToArray()); Assert.IsTrue(result.Length == 6); }
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuwxyz~!@#$%^&*";
Guid.NewGuid().ToString().Replace("-", string.Empty).Substring(0, 6);
Guid.NewGuid().ToString("n").Substring(0, 6);
public static string GetUniqueKey(int maxSize) { char[] chars = new char[62]; chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".ToCharArray(); byte[] data = new byte[1]; using (RNGCryptoServiceProvider crypto = new RNGCryptoServiceProvider()) { crypto.GetNonZeroBytes(data); data = new byte[maxSize]; crypto.GetNonZeroBytes(data); } StringBuilder result = new StringBuilder(maxSize); foreach (byte b in data) { result.Append(chars[b % (chars.Length)]); } return result.ToString(); } }
5 - استفاده از متد Path.GetRandomFileName
public string Get8CharacterRandomString() { string path = Path.GetRandomFileName(); path = path.Replace(".", ""); // Remove period. return path.Substring(0, 6); // Return 6 character string }
var chars = "abcdefghijklmnopqrstuvwxyz123456789".ToArray(); string pw = Enumerable.Range(0, passwordLength) .Aggregate( new StringBuilder(), (sb, n) => sb.Append((chars[random.Next(chars.Length)])), sb => sb.ToString());
آموزش Prism #1
- MVVM Light
- Prism
- Caliburn
- Cinch
- WAF
- Catel
- Onyx
- MVVM helpers
- و...
هر کدوم از فریم ورکهای بالا مزایا، معایب و طرفداران خاص خودشون رو دارند(^) ولی به جرات میتونیم Prism رو به عنوان قویترین فریم ورک برای پیاده سازی پروژهای بزرگ و قوی و ماژولار با تکنولوژی WPF یا Silverlight بنامیم. در این پست به معرفی و بررسی مفاهیم اولیه Prism خواهیم پرداخت و در پستهای دیگر به پیاده سازی عملی همراه با مثال میپردازیم.
*اگر به هر دلیلی مایل به یادگیری و استفاده از Prism نیستید، بهتون پیشنهاد میکنم از WAF استفاده کنید.
پیش نیازها:
برای یادگیری PRISM ابتدا باید با مفاهیم زیر در WPF یا Silverlight آشنایی داشته باشید.(فرض بر این است که به UserControl و Xaml و Dependency Properties، تسلط کامل دارید)
- Data binding
- Resources
- Commands
- Behaviors
چرا Prism ؟
- Prism به صورت کامل از Modular Programming برای پروژههای WPF و Silverlight پشتیانی میکند*
- از Prism هم میتوانیم در پروژههای WPF استفاده کنیم و هم Silverlight.
- Prism به صورت کامل از الگوی MVVM برای پیاده سازی پروژهها پشتیبانی میکند.
- پیاده سازی مفاهیمی نظیر Composite Command و Command Behavior و Asynchronous Interacion به راحتی در Prism امکان پذیر است.
- مفاهیم تزریق وابستگی به صورت توکار در Prism فراهم است که برای پیاده سازی این مفاهیم به طور پیش فرض امکان استفاده از UnityContainer و MEF در Prism تدارک دیده شده است.
- پیاده سازی Region navigation در Prism به راحتی امکان پذیر است.
- به وسیله امکان Event Aggregation به راحتی میتوانیم بین ماژولهای مختلف ارتباط برقرار کنیم.
*توضیح درباره برنامههای ماژولار
در تولید پروژهای نرم افزاری بزرگ هر چه قدر هم اگر در تهیه فایلهای اسمبلی، کلاس ها، اینترفیسها و کلا طراحی پروژه به صورت شی گرا دقت به خرج دهیم باز هم ممکن است پروژه به صورت یک پارچه طراحی نشود. یعنی بعد از اتمام پروژه، توسعه، تست پذیری و نگهداری آن سخت و در بعضی مواقع غیر ممکن خواهد شد. برنامه نویسی ماژولار این امکان را فراهم میکنه که یک پروزه با مقیاس برزگ به چند پروژه کوچک تقسیم شده و همه مراحل طراحی و توسعه و تست برای هر کدام از این ماژولها به صورت جدا انجام شود.
Prism امکاناتی رو برای طراحی و توسعه این گونه پروژهها به صورت ماژولار فراهم کرده است:
- ابتدا باید نام و مکان هر ماژول رو به Prism معرفی کنیم که میتونیم اونها رو در کد یا Xaml یا Configuration File تعریف کنیم.
- با استفاده از Metadata باید وابستگیها و مقادیر اولیه برای هر ماژول مشخص شود.
- با کمک تزریق وابستگیها ارتباطات بین ماژولها میسر میشود.
- ماژول مورد نظر به دو صورت OnDemand و Available لود خواهد شد.
در شکل زیر مراحل بالا قابل مشاهده است:
Bootstrapper چیست؟
در هر پروژه ماژولار (مختص Prism نیست) برای اینکه ماژولهای مختلف یک پروژه، قابلیت استفاده به صورت یک پارچه رو در یک Application داشته باشند باید مفهومی به نام Bootstapper رو پیاده سازی کنیم که وظیفه اون شناسایی و پیکربندی و لود ماژول هاست. در Prism دو نوع Bootstrapper پیش فرض وجود دارد.
- MefBootstrapper : کلاس پایه Bootstrapper که مبنای آن MEF است. اگر قصد استفاده از MEF رو در پروژههای خود دارید(^) Bootstrapper شما باید از این کلاس ارث ببرد.
- UnityBootstrapper : کلاس پایه Bootstrapper که مبنای آن UnityContainer است. اگر قصد استفاده از UnityContainer یا Service Locator (^) رو در پروژههای خود دارید Bootstrapper شما باید از این کلاس ارث ببرد.
تصویری از ارتباط Bootstrapper با ماژولهای سیستم
مفهوم Shell
در پروژههای WPF، در فایل App.xaml توسط یک Uri نقطه شروع پروژه را تعیین میکنیم. در پروژههای Silverlight به وسیله خاصیت RootVisual نقطه شروع سیستم تعیین میشود. در Prism نقطه شروع پروژه توسط bootsrapper تعیین میشود. دلیل این امر این است که Shell در پروژههای مبتنی بر Prism متکی بر Region Manager است. از Region برای لود و نمایش ماژولها استفاده خواهیم کرد.
ادامه دارد...
در طول روند تولید یک برنامه، چه به صورت تیمی و یا حتی انفرادی، بارها برای برنامه نویسان این نیاز پیش میآید که به نسخههای قدیمیتر فایلهای خود دسترسی داشته باشند تا بتوانند آنچه را که در قبل نوشتهاند مورد بازبینی قرار دهند. شاید کسانی که با سیستمهای مدیریت نسخه آشنایی ندارند، این کار را با استفاده از copy و paste کردن فایلها در پوشههای جداگانه انجام دهند؛ اما روند توسعه یک برنامه در محیط عملی، امکان استفاده از چنین روشی را به ما نمیدهد. زیرا مدیریت این فایلها علی الخصوص در پروژههای تیمی، بعد از مدتی بسیار دشوار خواهد شد. بنابراین نیاز به سیستمی احساس میشود که بتواند این کار را به صورت خودکار انجام دهد.
Git توسط سازنده سیستم عامل لینوکس یعنی آقای Linus Torvalds و برای مدیریت کدهای آن ساخته شد که بعدها توسط Linux-BitKeeper ارتقا یافت. BitKeeper یک سیستم مدیریت کد توزیع شده است که البته رایگان نیست. تیم BitKeeper در ابتدا پروژه لینوکس را به صورت رایگان پشتیبانی میکرد اما در سال 2005 این حمایت را قطع کرد. در این هنگام تیم توسعه لینوکس تصمیم گرفت که خود یک سیستم مدیریت کد توزیع شده ایجاد کند. آنها این سیستم را با Perl و C نوشتند و آن را برای اجرا شدن بر روی انواع سیستم عاملها نظیر لینوکس ویندوز و حتی مک آماده کردند اهداف اصلی Git عبارتند از:
سیستمهای کنترل نسخه را میتوان بر اساس خصوصیات مختلف در دستههای متفاوتی قرار داد اما از نظر معماری سیستم, به دو دستهی زیر تقسیم میشوند :
مخزن یا همان Repository محلی است که یک سیستم مدیریت نسخه از آن برای نگهداری تغییرات فایلها استفاده میکند. در سیستمهای VCS این مخزن به صورت متمرکز یا اصطلاحا Centralized Repository میباشد. به این معنا که یک Repository بر روی یک ماشین، خواه سیستم خود برنامه نویس(در پروژههای انفرادی) و خواه یک سرور قرار دارد (در پروژههای تیمی) و برنامه نویسان تغییرات فایلهای خود را به سمت این سرور میفرستند و این سرور وظیفه نگهداری تمامی نسخهها و اطلاعات مربوطه از برنامه نویسان مختلف را به عهده دارد. اشکال این روش در این است که برنامه نویس تنها به نسخه جاری که بر روی سیستم خود است دسترسی دارد و اگر بنا به دلیلی بخواهد از نسخههای پیشین استفاده کند باید آن را از سرور بخواهد که این کار مشکل دیگری ایجاد میکند و آن این است که ممکن است برنامه نویس همیشه در موقعیتی نباشد که بتواند به سرور دسترسی داشته باشد. به همین دلیل این روش وابستگی زیادی برای برنامه نویس ایجاد میکند اما پیاده سازی این روش آسانتر از مدل توزیع شده است.
پاسخ به این سوال بسیار ساده است: هر آنچه برای ما مهم است که این شامل فایلهای کد, فایلهای پیکربندی, خروجیهای نظیر dll و غیره است. البته در این بین استثنائاتی نظیر فایلهای EXE و یا پکیجهای نصب شده وجود دارد که در بسیاری از موارد نیازی به پیگیری نسخههای آنها نیست اما تمامی اینها وابسته به نظر برنامه نویس است.