بناء نظام فعال للتحكم في الإصدارات دون تكرار الملفات
إن تخزين نسخ كاملة من الملفات لكل إصدار أو فرع (fork) يؤدي إلى هدر المساحة. فإذا قمت بتغيير سطر واحد في مشروع يتكون من عشرة ملفات، فلا ينبغي عليك حفظ الملفات العشرة كاملة مرة أخرى.
واجهت هذه المشكلة أثناء بناء مشروعي LaTeX Writer. كنت بحاجة إلى طريقة لإدارة التحكم في الإصدارات وتفرع المشاريع (forking) دون تكبد تكاليف تخزين عالية.
بحثت في كيفية عمل GitHub. لا يقوم GitHub بتخزين مستودع (repository) كامل في كل مرة تجري فيها تغييراً، بل يقوم بتخزين المحتوى بشكل منفصل ويستخدم المراجع لربط الملفات والالتزامات (commits).
لقد بنيت نظامي باستخدام ثلاثة مكونات رئيسية:
- البيانات الوصفية (Metadata): تُخزن فيها المعرفات (IDs) الخاصة بالمشاريع والمالكين والمجلدات.
- سجلات الملفات (File Records): تُخزن فيها أسماء الملفات والروابط المؤدية إلى المحتوى.
- الكتل (Blobs): هذا هو المكان الذي يُخزن فيه المحتوى الفعلي.
يعمل النظام من خلال تقنية "تجزئة المحتوى" (content hashing). فعندما تقوم بحفظ ملف، يقوم النظام بإنشاء معرف فريد بناءً على المحتوى. وإذا كان المحتوى موجوداً بالفعل، يعيد النظام استخدام الـ Blob الموجود ولا ينشئ واحداً جديداً.
يجعل هذا النهج عملية التفرع (forking) سهلة وغير مكلفة. فعندما تقوم بتفرع مشروع ما:
- ينشئ النظام معرف مشروع (Project ID) جديداً.
- ينشئ بيانات وصفية (metadata) جديدة للملفات والمجلدات.
- يوجه البيانات الوصفية الجديدة إلى الـ Blobs الموجودة مسبقاً.
لا يتم نسخ أي محتوى فعلي للملف أثناء عملية التفرع؛ فأنت تقوم فقط بتكرار سجلات البيانات الوصفية الصغيرة.
عندما تقوم بتعديل فرع ما، تظل العملية فعالة:
- تقوم بتغيير المحتوى.
- يقوم النظام بعمل تجزئة (hashing) للمحتوى الجديد.
- ينشئ Blob جديداً فقط إذا لم يكن هذا المحتوى بالتحديد موجوداً.
- تشير البيانات الوصفية لفرعك إلى الـ Blob الجديد.
- يظل المشروع الأصلي يشير إلى الـ Blob القديم.
توفر هذه الطريقة عدة فوائد:
- توفير مساحات هائلة من خلال إزالة تكرار المحتوى (Content deduplication).
- تتم عملية التفرع (Forking) فوراً.
- تظل إدارة الإصدارات منظمة.
- يظل نمو قاعدة البيانات بطيئاً.
ستحصل على وظائف مشابهة لـ GitHub دون أعباء التخزين الثقيلة.