چند سالی هست که dotfileهام رو به وسیله git مدیریت می‌کنم. روش مورد استفاده رو می‌تونید اینجا ببینید: چه‌طور dotfileها را مدیریت می‌کنید؟. یک نمونه تر و تمیزتر از این روش هم رو وبسایت atlassian در دسترس هست: مدیریت dotfileها به وسیله git.

یکی از ویژگی‌های اصلی گیت، توزیع شده بودن اون هست. توزیع شده بودن اجازه می‌ده که در نبود شبکه بشه روی پروژه کار کرد. سرعت بالاتری نسبت به cvcs‌ها بهمون میده. چون نیازی به ارتباط با سرویس دهنده مرکزی نیست. داشتن کپی های مختلف در مقابل می‌تونه ما رو در مقابل single point of failure محافظت کنه و غیره.

شاید با خوندن عنوان بپرسید خوب این چه کاریه؟ همین کپی عادی از مخزن که در حال کار کردن باهاش هستیم مگه ویژگی‌های لازم رو بهمون نمی‌ده؟

هدف ما این هست که یک کپی Local از Repo مورد نظر داشته باشیم و بتونیم باهاش به عنوان یک Remote رفتار کنیم. خیلی‌ ساده هست. قصد داریم از مزایای یک Remote به شکل محلی بهره‌مند باشیم.

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

وقتی تعداد زیادی Home Directory رو مدیریت می‌کنید (سیستم‌های مختلف، سیستم‌عامل‌های مختلف و روی هر سیستم‌عامل کاربرهای مختلف) بهتر هست یک لایه Abstraction در نظر بگیرید، که روی هر سیستم یک تعداد Home Directory مختلف رو Push می‌کنید به ریموت محلی روی خود سیستم و در صورتی که همه چیز بدون مشکل بود می‌فرستیم روی ریموت اصلی تا کاربر دیگه‌ای روی سیستم و سیستم‌عامل دیگه‌ای با یک تغییر ساده یک جای دیگه ناگهانی دچار مشکل نشه.

یک ریموت محلی با سرعتی بیشتر و همیشه در دسترس در حین نداشتن اینترنت و تحریم بهمون اجازه می‌ده به شکل استاندارد ازش Clone بگیریم و یک HOME جدید رو راه اندازی یا تغیرات اعمال شده در فایل‌ها رو بین خانه کاربرهای مختلف بدون نیاز به شبکه و… جا به جا کنیم. از طرفی دیگه به کپی کردن دستی مخزن و تغییر سطوح دسترسی فایل‌ها و… نیازی نداریم.

کار پیچیده‌ای رو در پیش نداریم:

$ cd ~/Documents/Repos
$ git init --bare config.git
$ cd ~
$ git remote add local ~/Documents/Repos/config.git 

یک مخزن ساده (bare) ایجاد می‌کنیم. به محل اصلی پروژه که فرضا ~ هست می‌ریم. و آدرس مخزن ساده ایجاد شده رو به عنوان یک remote با اسم دلخواه اضافه می‌کنیم. حالا می‌تونیم از دایرکتوری‌های خانگی مختلفی که باهاشون سر و کار داریم تغییرات رو بفرستیم به Remote محلی ایجاد شده. و بعد از اینکه مطمئن بودیم مشکلی ندارند و تداخلی رو ایجاد نکردن ببریم رو Origin یا در دایرکتوری‌های مختلف تحویل بگیریم.

$ git push local

یا اگر قصد داشتیم یک کاربر جدید رو راه‌اندازی کنیم:

$ git --work-tree=. --git-dir=.config clone --bare ~/Documents/Projects/LocalRepos/config.git .config
$ git --work-tree=. --git-dir=.config checkout