اگر بخش قبلی درباره استفاده از git svn را خوانده باشید، میتوانید بهراحتی از همان دستورالعملها برای انجام git svn clone یک مخزن استفاده کنید؛ سپس استفاده از سرور Subversion را متوقف کرده، به یک سرور Git جدید منتقل شوید و شروع به استفاده از آن کنید. اگر میخواهید تاریخچهی تغییرات حفظ شود، میتوانید این کار را به سرعتی انجام دهید که دادهها را از سرور Subversion بیرون بکشید (که ممکن است مدتی طول بکشد).
با این حال، واردسازی کامل نیست؛ و چون این کار طول میکشد، بهتر است آن را درست انجام دهید. اولین مشکل مربوط به اطلاعات نویسنده است. در Subversion، هر کسی که کامیت میکند، یک کاربر روی سیستم دارد که در اطلاعات کامیت ثبت میشود. مثالهای بخش قبلی، schacon را در برخی مکانها نشان میدهند، مانند خروجی blame و git svn log. اگر میخواهید این اطلاعات به دادههای نویسندهی بهتر در Git نگاشت شود، نیاز به یک نگاشت از کاربران Subversion به نویسندگان Git دارید. یک فایل به نام users.txt ایجاد کنید که این نگاشت را با فرمت زیر داشته باشد:
schacon = Scott Chacon <schacon@geemail.com>
selse = Someo Nelse <selse@geemail.com>برای دریافت فهرستی از نام نویسندگانی که SVN استفاده میکند، میتوانید این را اجرا کنید:
$ svn log --xml --quiet | grep author | sort -u | \
perl -pe 's/.*>(.*?)<.*/$1 = /'این خروجی را در قالب XML تولید میکند، سپس فقط خطوط حاوی اطلاعات نویسنده را نگه میدارد، تکراریها را حذف میکند و تگهای XML را پاک میکند.
واضح است که این تنها روی سیستمی کار میکند که grep، sort و perl نصب باشند.
سپس خروجی را به فایل users.txt هدایت کنید تا بتوانید داده معادل کاربر Git را در کنار هر ورودی اضافه کنید.
|
Note
|
اگر این را روی یک ماشین ویندوزی امتحان میکنید، در این نقطه با مشکل مواجه خواهید شد. مایکروسافت راهنماییها و نمونههای خوبی را در https://learn.microsoft.com/en-us/azure/devops/repos/git/perform-migration-from-svn-to-git ارائه کرده است. |
میتوانید این فایل را به git svn بدهید تا در نگاشت دقیقتر دادههای نویسنده کمک کند.
همچنین میتوانید به git svn بگویید متادیتایی را که Subversion معمولاً وارد میکند، شامل نکند، با ارسال --no-metadata به دستور clone یا init.
متادیتا شامل git-svn-id در هر پیام کمیت است که Git هنگام واردسازی تولید میکند.
این میتواند لاگ Git شما را حجیم کند و کمی نامشخص سازد.
|
Note
|
نیاز دارید متادیتا را نگه دارید وقتی میخواهید کمیتهایی را که در مخزن Git انجام شدهاند، به مخزن SVN اصلی بازآینه (mirror) کنید.
اگر نمیخواهید همگامسازی در لاگ کمیت شما ظاهر شود، میتوانید پارامتر |
این باعث میشود دستور import شما به این شکل باشد:
$ git svn clone http://my-project.googlecode.com/svn/ \
--authors-file=users.txt --no-metadata --prefix "" -s my_project
$ cd my_projectحالا باید یک واردسازی Subversion مرتبتر در پوشه my_project داشته باشید.
بهجای کمیتهایی که به این شکل بودند:
commit 37efa680e8473b615de980fa935944215428a35a
Author: schacon <schacon@4c93b258-373f-11de-be05-5f7a86268029>
Date: Sun May 3 00:12:22 2009 +0000
fixed install - go to trunk
git-svn-id: https://my-project.googlecode.com/svn/trunk@94 4c93b258-373f-11de-
be05-5f7a86268029آنها اینگونه به نظر میرسند:
commit 03a8785f44c8ea5cdb0e8834b7c8e6c469be2ff2
Author: Scott Chacon <schacon@geemail.com>
Date: Sun May 3 00:12:22 2009 +0000
fixed install - go to trunkنه تنها فیلد Author بسیار بهتر است، بلکه git-svn-id هم دیگر وجود ندارد.
همچنین باید کمی پاکسازی پس از واردسازی انجام دهید.
برای یک مورد، باید ارجاعات عجیبوغریب را که git svn تنظیم کرده پاک کنید.
ابتدا تگها را جابهجا میکنید تا تگهای واقعی Git شوند نه شاخههای راهدور عجیب، و سپس مابقی شاخهها را طوری جابهجا میکنید که محلی شوند.
برای منتقل کردن تگها به تگهای واقعی Git، اجرا کنید:
$ for t in $(git for-each-ref --format='%(refname:short)' refs/remotes/tags); do git tag ${t/tags\//} $t && git branch -D -r $t; doneاین دستور، ارجاعهایی را که شاخههای ریموت بودند و با refs/remotes/tags/ شروع میشدند، گرفته و آنها را به تگهای واقعی (سبک/lightweight) تبدیل میکند.
سپس، بقیهی ارجاعها زیر refs/remotes را به شاخههای محلی منتقل کنید:
$ for b in $(git for-each-ref --format='%(refname:short)' refs/remotes); do git branch $b refs/remotes/$b && git branch -D -r $b; doneممکن است پیش بیاید که برخی شاخههای اضافه ببینید که با @xxx ختم شدهاند (که xxx یک عدد است)، در حالی که در Subversion تنها یک شاخه مشاهده میکنید. این در واقع یک ویژگی Subversion به نام "peg-revisions" است، که معادلی نحوی (syntax) در Git ندارد. بنابراین، git svn به سادگی شماره نسخه SVN را به نام شاخه اضافه میکند، درست همانطور که اگر در SVN میخواستید به peg-revision آن شاخه اشاره کنید، مینوشتید. اگر دیگر نیازی به peg-revisions ندارید، به سادگی آنها را حذف کنید:
$ for p in $(git for-each-ref --format='%(refname:short)' | grep @); do git branch -D $p; doneاکنون همهی شاخههای قدیمی، شاخههای واقعی Git هستند و همهی تگهای قدیمی، تگهای واقعی Git شدهاند.
یک نکتهی آخر برای پاکسازی باقی مانده است.
متأسفانه، git svn یک شاخهی اضافه به نام trunk ایجاد میکند که به شاخهی پیشفرض Subversion نگاشت میشود، اما ارجاع trunk به همان مکانی اشاره میکند که master اشاره دارد.
از آنجا که master بیشتر با سبک Git همخوانی دارد، روش حذف این شاخهی اضافه به صورت زیر است:
$ git branch -d trunkآخرین کاری که باید انجام دهید، اضافه کردن سرور Git جدید خود به عنوان یک ریموت و انجام push به آن است. در اینجا یک مثال برای اضافه کردن سرور به عنوان ریموت آورده شده است:
$ git remote add origin git@my-git-server:myrepository.gitاز آنجا که میخواهید تمام شاخهها و تگهای خود را به سرور منتقل کنید، اکنون میتوانید این دستور را اجرا کنید:
$ git push origin --all
$ git push origin --tagsتمام شاخهها و تگهای شما باید در سرور Git جدیدتان قرار داشته باشند، بهطوری که واردسازی بهصورت مرتب و تمیز انجام شده باشد.