سلام، من محمد اربابی هستم. در این نوشتار قصد دارم تجربه خودم درباره مهاجرت از svn به git را با شما به اشتراک بگذارم.
شاید برای شما هم پیش آمده باشد، روی پروژه ای کار کرده باشید که چندین سال روی svn بوده و تصمیم بر این گرفته بشود که سورس پروژه به git منتقل شود.
انتقال دادن پروژه به git از دو روش ممکن است. و نوع مهاجرت شما، بستگی به این دارد که به سابقه تغییرات پروژه خود روی git احتیاج دارید یا نه!
با توجه به اینکه احتمالا مخزن svn خود را بعد از مهاجرت به git حذف نخواهید کرد و تاریخچه تغییرات بر روی svn وجود خواهد داشت؛ همچنین با در نظر گرفتن این نکته که نحوه نگهداشت تغییرات و تاریخچه آنها در این دو سیستم کنترل نسخه کاملا متفاوت است، انتقال تاریخچه svn به git هیچ وقت با دقت کامل صورت نخواهد گرفت. لذا پیشنهاد شخصی من مهاجرت بدون انتقال تاریخچه تغییرات است.
در این روش شما آخرین وضعیت پروژه را به git انتقال خواهید داد. برای این کار:
1. با استفاده از دستور git clone یک کپی از مخزن سرور خود بر روی سیستم خود ایجاد کنید:
git clone http://git.yourdomain.com/yourRepository
2. در حال حاضر شما داخل شاخه master هستید که معادل شاخه trunk در svn است. کافی است تمام فایل های مربوط به trunk را در مسیر پروژه git کپی، سپس آنها را ذخیره کنید:
git add .
git commit -m “your message”
git push
بهتر است در اولین کامیت، مسیر دسترسی به مخزن svn را به عنوان پیغام ثبت کنید تا در آینده همکارانی که تازه کار هستند یا به تازگی به تیم شما اضافه شده اند بتوانند به سابقه تغییرات پروژه شما دسترسی داشته باشند.
3. بعد از شاخه master نوبت میرسد به اینکه تمام شاخه های دیگر svn را در git ایجاد و فایل های مربوطه را در مسیر مذکور ذخیره کنید. به طور مثال در نظر بگیرید شاخه ای با نام release_1.0.0 در svn دارید:
git checkout -b release_1.0.0
با اجرای این دستور یک شاخه از master با نام release_1.0.0 برای شما ایجاد خواهد شد؛ که تمام فایل های مربوط به شاخه master درون آن وجود دارد. در ابتدا فایل های مذکور را پاک کنید، سپس فایل های شاخه release_1.0.0 در svn را در مسیر مربوط به git کپی و ذخیره کنید:
git add .
git commit -m “your message”
git push origin release_1.0.0
این کار را برای تمام شاخه های پروژه تان انجام دهید.
خب، حالا شما تمام شاخه هایی را که در svn داشتید بر روی git دارید و هر زمانی که به سابقه تغییرات احتیاج داشته باشید، می توانید به راحتی به مسیر svn مراجعه کنید. در انتهای کار لازم است که دسترسی نوشتاری تمامی کاربرانتان بروی svn را به دسترسی خواندنی تبدیل کنید تا مطمئن باشید تغییری روی مخزن مذکور نخواهید داشت.
روش دیگر مهاجرت به git انتقال اطلاعات مخزن svn با تاریخچه تغییرات هست. قبل از اینکه به صحبت درباره نحوه انجام کار بپردازیم نیاز هست که شما ابزار git-svn را بر روی سیستم خود نصب کنید. حالا به سراغ مراحل مهاجرت با انتقال تاریخچه تغییرات می رویم:
1. در ابتدا به یک فایل متنی شامل نگاشت اطلاعات کاربران svn به git (به عنوان مثال users.txt) ایجاد کنید:
User1 = First Last Name <email@address.com>
User2 = First Last Name <email@address.com>
اگر اطلاعات کاربران svn را ندارید؛ می توانید با استفاده از دستور زیر یک فایل با نام users.txt با اطلاعات مذکور ایجاد کنید:
svn log -q http://svn.yourdomain.com/yourRepository | awk -F '|' '/^r/ {gsub(/ /, "", $2); sub(" $", "", $2); print $2" = "$2" <"$2">"}' | sort -u > users.txt
اگر در فایل ایجاد شده ایمیل کاربران مانند مثال بالا وجود نداشت، آنها را به فایل اضافه کنید.
2. حالا با استفاده از دستور زیر اطلاعات مخزن svn را دریافت و به یک مخزن محلی git منتقل کنید:
git svn clone --stdlayout --no-metadata --authors-file=users.txt http://svn.yourdomain.com/yourRepository dest_dir-tmp
دستور فوق برای شما یک مخزن git در پوشه dest_dir-tmp ایجاد کرده و اطلاعات مخزن svn را در آن قرار می دهد. توجه داشته باشید که قرار دادن پرچم stdlayout-- بیانگر این است که مخزن svn شما دارای ساختار استاندارد (trunk, branches, tags) است. در غیر این صورت می توانید مسیر جایگزین پوشه های فوق را با استفاده از پرچم T- برای trunk، پرچم b- برای branches و پرچم t- برای tags مشخص کنید:
git svn clone --no-metadata --authors-file=users.txt http://svn.yourdomain.com/yourRepository dest_dir-tmp -T main/project -b others -t tags
همانطور که در مثال بالا میبینید مسیر اصلی پروژه بهجای trunk، مسیر main/project است. همچنین شاخه های دیگر پروژه در مسیر others قرار دارد و با پرچم -b مشخص شده است. و tag های ایجاد شده نیز در پوشه پیشفرض tags قرار گرفته است.
توجه داشته باشید حذف پرچم no-metadata-- باعث خواهد شد که git اطلاعات ویرایش svn مربوطه را در کنار پیغام تغییرات قرار دهد:
git-svn-id: http://svn.yourdomain.com/yourRepository/<branchname/trunk> @<RevisionNumber> <Repository UUID>
که در بسیاری از موارد نیازی به آنها نخواهیم داشت.
اگر در روال clone کردن به مشکی برخوردید وارد پوشه dest_dir-temp شوید و با اجرای دستور git svn fetch کار را ادامه دهید:
cd dest_dir-temp
git svn fetch
اگر روی پروژه بزرگی کار می کنید احتمالا چندین بار احتیاج خواهید داشت از دستور git svn fetch استفاده کنید. و انتقال اطلاعات زمان بر خواهد بود.
3.حالا وقت آن رسیده است که تمام شاخه هایی که به آن ها احتیاج خواهید داشت (به غیر از master) را یکی یکی به صورت محلی ایجاد کنید:
git branch -r
دستور بالا لیست تمام شاخه هایی که روی svn داشتید رو به شما نمایش خواهد داد.
git checkout -b local_branch remote_branch
4. زمانی که از دستور git branches -r استفاده می کنید متوجه خواهید شد که tag های svn به عنوان یک شاخه به پروژه اضافه شده است، لذا احتیاج خواهید داشت ابتدا آنها را به عنوان یک شاخه محلی به گیت اضافه نموده، سپس از آنها tag بسازید و شاخه محلی مربوطه را حذف کنید:
git checkout -b tag_v1 remotes/tags/v1
git checkout master
git tag v1 tag_v1
git branch -D tag_v1
5. در حال حاضر مخزن git شما همان چیزی است که احتیاج داشتید؛ با این تفاوت که همچنان با مخزن svn شما در ارتباط است. کاری که احتیاج دارید انجام بدهید این است که از این مخزن git محلی تان clone بگیرید و مخزن فعلی رو پاک کنید:
cd ..
git clone dest_dir-tmp dest_dir
rm -rf dest_dir-tmp
cd dest_dir
6. و در نهایت باید مخزن git محلی را به سرور متصل کنید:
git remote add origin http://git.yourdomain.com/yourRepository
تبریک میگم مخزن svn شما با موفقیت به سرور git شما انتقال پیدا کرد.