Vivasoft-logo

৯.২ গিট এবং অন্যান্য সিস্টেম – গিট-এ মাইগ্রেট করা

গিট এ স্থানান্তর করা

আপনার যদি অন্য একটি কোডবেস ভিসিএস -এ থাকে কিন্তু আপনি গিট ব্যবহার শুরু করার সিদ্ধান্ত নেন, তাহলে আপনাকে অবশ্যই আপনার প্রজেক্টটি অবশ্যই স্থানান্তর করতে হবে। এই অধ্যায়ে সাধারণ সিস্টেমের জন্য কিছু ইম্পোর্টার নিয়ে আলোচনা করা হবে এবং তারপর দেখানো হবে কিভাবে আপনার নিজস্ব কাস্টম ইম্পোর্টার তৈরি করতে হয়। আপনি শিখবেন কীভাবে পেশাদারভাবে ব্যবহৃত এসসিএম সিস্টেম থেকে ডাটা ইম্পোর্ট করতে হয়, কারণ তারা বেশিরভাগ ব্যবহারকারী যারা স্থানান্তর করছে এবং তাদের জন্য হাই-কোয়ালিটি টুলস সহজে পাওয়া যায়।

সাবভার্সন

আপনি যদি গিট এসভিএন ব্যবহার সম্পর্কে পূর্ববর্তী সেকশনটি পড়ে থাকেন, তাহলে আপনি সহজেই একটি রিপোজিটোরি গিট এসভিএন ক্লোন করতে সেই নির্দেশাবলী ব্যবহার করতে পারেন। এরপর সাবভার্সন সার্ভার ব্যবহার করা বন্ধ করুন, একটি নতুন গিট সার্ভারে পুশ দিন এবং এটি ব্যবহার করা শুরু করুন। যদি আপনি হিস্টরি চান, তাহলে আপনি যত তাড়াতাড়ি সম্ভব সাবভারসন সার্ভার থেকে ডেটা পুল করে আনতে পারেন (যা কিছু সময় লাগতে পারে)। তবে, ইম্পোর্ট করাটা সঠিক সিধান্ত না, কারণ এটাতে সময় বেশি লাগে। প্রথম সমস্যা অথর এর তথ্য। সাবভার্সনে যাদের সিস্টেমে ইউজার অ্যাকাউন্ট থাকে প্রত্যেকের কমিট রেকর্ড করে রাখা হয়। পূর্ববর্তী সেকশনে উদাহরণগুলি কিছু জায়গায় schacon দেখায়, যেমন ব্লেম আউটপুট এবং git svn log।  আপনি যদি এটিকে আরও ভাল গিট অথর এর ডেটাতে ম্যাপ করতে চান তবে আপনার সাবভার্সন ব্যবহারকারীদের থেকে গিট অথর এর কাছে একটি ম্যাপিং প্রয়োজন। user.txt নামে একটি ফাইল তৈরি করুন যাতে এই ম্যাপিং টি এইরকমের হয়:
				
					schacon = Scott Chacon <schacon@geemail.com>
selse = Someone Else <selse@geemail.com>
				
			

এসভিএন ব্যবহার করে অথর এর নামের একটি তালিকা পেতে, আপনি এটি রান করতে পারেন:

				
					$ svn log --xml --quiet | grep author | sort -u | \
  perl -pe 's/.*>(.*?)<.*/$1 = /'
				
			

এটি XML ফর্ম্যাটে লগ আউটপুট তৈরি করে, তারপর অথর এর তথ্য সহ লাইনগুলি রাখে, ডুপ্লিকেটগুলি বাতিল করে, XML ট্যাগগুলি বের করে দেয় ৷ অবশ্যই এটি শুধুমাত্র গ্রেপ, শর্ট এবং পার্ল ইনস্টল সহ একটি মেশিনে কাজ করে। তারপরে, সেই আউটপুটটিকে আপনার user.txt ফাইলে রিডাইরেক্ট করুন যাতে আপনি প্রতিটি এন্ট্রির পাশে একইরকম গিট ব্যবহারকারী ডেটা যোগ করতে পারেন।

বিঃদ্রঃ

আপনি যদি এটি একটি উইন্ডোজ মেশিনে চেষ্টা করে থাকেন তবে এটি সেই পয়েন্ট যেখানে আপনি সমস্যায় পড়বেন। মাইক্রোসফট কিছু ভাল পরামর্শ এবং নমুনা প্রদান করেছে https://docs.microsoft.com/en-us/azure/devops/repos/git/perform-migration-from-svn-to-git.
আপনি এই ফাইলটি গিট এসভিএন -এ প্রদান করতে পারেন যাতে এটি অথর এর ডেটা আরও সঠিকভাবে ম্যাপ করতে সহায়তা করে। আপনি ক্লোন বা init কমান্ডে –no-metadata পাস করে সাবভার্সন সাধারণত যে মেটাডেটা ইম্পোর্ট করে তা অন্তর্ভুক্ত না করার জন্য আপনি গিট এসভিএন -কে বলতে পারেন। এটি আপনার গিট লগকে ব্লোট করতে পারে এবং এটি কিছুটা অস্পষ্ট করতে পারে।

বিঃদ্রঃ

আপনি যখন গিট রিপোজিটরিতে করা কমিট গুলিকে আসল এসভিএন রিপোজিটরিতে ফিরিয়ে আনতে চান তখন আপনাকে মেটাডেটা  রাখতে হবে। আপনি যদি আপনার কমিট লগে সিঙ্ক্রোনাইজেশন না চান, তাহলে নির্দ্বিধায়  –no-metadata প্যারামিটারটি বাদ দিন।

এটি আপনার ইম্পোর্ট কমান্ডকে এইরকম দেখায়:

				
					$ git svn clone http://my-project.googlecode.com/svn/ \
      --authors-file=users.txt --no-metadata --prefix "" -s my_project
$ cd my_project
				
			

এখন আপনার 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
				
			

অথর ফিল্ড এখন অনেক ভাল দেখায় এবং git-svn-id ও আর নেই। আপনার এখন post-import ক্লিনআপ করা উচিত এবং আপনার অপ্রয়োজনীয় রেফারেন্সগুলি ক্লিনআপ করা উচিত যা গিট এসভিএন সেট আপ করেছে। প্রথমে আপনি ট্যাগগুলি সরান যাতে তারা রিমোট ব্রাঞ্চ গুলির পরিবর্তে প্রকৃত ট্যাগ হয় এবং তারপরে আপনি বাকি ব্রাঞ্চগুলিকে স্থানান্তরিত করবেন যাতে তারা লোকাল হয়।

ট্যাগগুলোকে সরিয়ে সঠিক গিট ট্যাগ তৈরি করতে, এটি রান করতে পারেন:

				
					$ 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/ দিয়ে শুরু হয় এবং সেগুলিকে যথোপযুক্ত আসল (হালকা) ট্যাগ হিসেবে তৈরি করে। 

এরপরে, রেফারেন্স/রিমোটের অধীনে বাকি রেফারেন্সগুলিকে লোকাল ব্রাঞ্চ হতে সরান:

				
					$ 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 দ্বারা suffixed (যেখানে xxx একটি সংখ্যা), যখন সাবভার্সনে আপনি শুধুমাত্র একটি ব্রাঞ্চ দেখতে পাবেন। এটি আসলে “peg-revisions” নামে একটি সাবভার্সন বৈশিষ্ট্য, যা এমন কিছু যার জন্য গিট সহজভাবে কোন সিনট্যাক্টিক্যাল প্রতিরূপ নেই। সুতরাং, গিট এসভিএন ব্রাঞ্চ নামের সাথে এসভিএন সংস্করণ নম্বর যোগ করে ঠিক একইভাবে যেভাবে আপনি এসভিএন তে এটি লিখেছিলেন সেই শাখার “peg-revisions” এর জন্য। আপনার যদি “peg-revisions” কোনো বিষয়ে আর দরকার না পড়ে, তাহলে কেবল সেগুলি সরিয়ে দিন:

				
					for p in $(git for-each-ref --format='%(refname:short)' | grep @); do git branch -D $p; done

				
			

এখন সমস্ত পুরানো ব্রাঞ্চ গুলি আসল গিট ব্রাঞ্চ এবং সমস্ত পুরানো ট্যাগগুলি আসল গিট ট্যাগ।

ক্লিনআপ করার জন্য একটি শেষ জিনিস আছে। দুর্ভাগ্যবশত,গিট এসভিএন ট্রাংক নামে একটি অতিরিক্ত ব্রাঞ্চ তৈরি করে, যা সাবভার্সনের ডিফল্ট ব্রাঞ্চ ম্যাপিং করে, কিন্তু ট্রাংক রেফ মাস্টারের মতো একই জায়গায় নির্দেশ করে। যেহেতু মাস্টারটি আরও গিট রীতিসিদ্ধ, তাই অতিরিক্ত ব্রাঞ্চটি কীভাবে সরিয়ে ফেলা যায় তা এখানে:

				
					$ git branch -d trunk
				
			

শেষ জিনিসটি হল আপনার নতুন গিট সার্ভারটিকে রিমোট হিসাবে যুক্ত করুন এবং এটিতে পুশ  দিন। এখানে একটি রিমোট হিসাবে আপনার সার্ভার যোগ করার একটি উদাহরণঃ

				
					$ git remote add origin git@my-git-server:myrepository.git
				
			
যেহেতু আপনি আপনার সমস্ত ব্রাঞ্চ এবং ট্যাগগুলি উপরে নিতে চান, আপনি এখন এটি রান করতে পারেন:
				
					$ git push origin --all
$ git push origin --tags
				
			

আপনার সমস্ত ব্রাঞ্চ  এবং ট্যাগ একটি সুন্দর, ক্লিন ইম্পোর্ট দিয়ে আপনার নতুন গিট সার্ভারে রাখা উচিত।

মারকিউরিয়াল

মারকিউরিয়াল এবং গিট এর ভার্সন সংরক্ষন করার জন্যে মুটামুটি একই রকম মডেল ব্যবহার করা হয়। মারকিউরিয়াল থেকে গিট একটু বেশি সহজ। মারকিউরিয়াল থেকে গিট এ একটি রিপোজিটরিকে “hg-fast-export” টুলস ব্যবহার করে মুটামুটি সহজে কনভার্ট করা যায়। 

 

এই কাজ করার জন্যে “hg-fast-export” এর একটি কপি আপনার দরকার হবে।

				
					$ git clone https://github.com/frej/fast-export.git


				
			

প্রথম ধাপে একটি মারকিউরিয়াল রিপোজিটরি ক্লোন করা দরকার যেটি আপনি কনভার্ট করতে চানঃ

				
					$ hg clone <remote repo URL> /tmp/hg-repo


				
			

পরবর্তী ধাপ হল একটি অথর ম্যাপিং ফাইল তৈরি করা। মারকিউরিয়াল গিট – এর চেয়ে কিছুটা বেশি ক্ষমাশীল, কি পরিবর্তন করা হবে তা অথর ফিল্ড এ রাখা হবে। সুতরাং ক্লিন হাউজ করার জন্য এটি একটি ভাল সময়। এজন্য ব্যাশ সেল এ এই এক লাইনের কমান্ডটি রান কর।

				
					$ cd /tmp/hg-repo
$ hg log | grep user: | sort | uniq | sed 's/user: *//' > ../authors
				
			

এটি কয়েক সেকেন্ড সময় নিবে, এটা নির্ভর করবে আপনার প্রজেক্টের হিস্টরির উপর। তারপরে  /tmp/authors ফাইলটি এরকম কিছু দেখাবেঃ

				
					bob
bob@localhost
bob <bob@company.com>
bob jones <bob <AT> company <DOT> com>
Bob Jones <bob@company.com>
Joe Smith <joe@company.com>
				
			

এই উদাহরণে, একই  ব্যক্তি (Bob) চারটি ভিন্ন নামের অধীনে পরিবর্তনগুলি তৈরি করেছে, যার মধ্যে একটি আসলে সঠিক দেখাচ্ছে এবং যার মধ্যে একটি গিট কমিটের জন্য সম্পূর্ণরূপে ইনভ্যালিড হবে। hg-fast-export আমাদের প্রতিটি লাইনকে একটি রুল এ পরিণত করে এটি ঠিক করতে দেয়: “<input>”=”<output>”, একটি <input> থেকে একটি <output> এ ম্যাপিং করে। <input> এবং <output> স্ট্রিং এর ভিতরে সকল escape sequences পাইথন এনকোডিং string_escape সাপোর্ট করে। যদি অথর ম্যাপিং ফাইলে কোন <input> মিল না থাকে, তাহলে সেই অথর গিটে আনমডিফাইড পাঠানো হবে। যদি সকল ইউজারনেইম ঠিক দেখায় তাহলে আমাদের এই ফাইলটি দরকার হবে না। এই উদাহরণে, আমরা আমাদের ফাইলটি দেখতে চাই:

				
					"bob"="Bob Jones <bob@company.com>"
"bob@localhost"="Bob Jones <bob@company.com>"
"bob <bob@company.com>"="Bob Jones <bob@company.com>"
"bob jones <bob <AT> company <DOT> com>"="Bob Jones <bob@company.com>"
				
			

একই ধরনের ম্যাপিং ফাইল এর ব্রাঞ্চ এবং ট্যাগের নাম পরিবর্তন করতে ব্যবহার করা যেতে পারে যদি মারকিউরিয়াল নামটি গিট দ্বারা অনুমোদিত না হয়।

 

পরবর্তী ধাপ হল আমাদের নতুন গিট রিপোজিটরি তৈরি করা এবং এক্সপোর্ট স্ক্রিপ্ট চালানো:

				
					$ git init /tmp/converted
$ cd /tmp/converted
$ /tmp/fast-export/hg-fast-export.sh -r /tmp/hg-repo -A /tmp/authors
				
			

-r ফ্ল্যাগটি hg-fast-export কে বলে আমরা যে মারকিউরিয়াল রিপোজিটরি টি কনভার্ট করতে চাই সেটা কোথায় খুজব, এবং -A ফ্ল্যাগটি বলে যে অথর ম্যাপিং ফাইলটি কোথায় পাওয়া যাবে (ব্রাঞ্চ এবং ট্যাগ ম্যাপিং ফাইলগুলি যথাক্রমে -B এবং -T ফ্ল্যাগ দ্বারা নির্দিষ্ট করা হয়)। স্ক্রিপ্টটি মারকিউরিয়াল চেইঞ্জসেট কে পার্স করে এবং সেগুলিকে গিট-এর “fast-import” ফিচার এর জন্য একটি স্ক্রিপ্টে কনভার্ট করে (যা আমরা একটু পরে বিস্তারিত আলোচনা করব)। এটি কিছুটা সময় নেয় (যদিও এটি নেটওয়ার্কের তুলনায় অনেক দ্রুত), এবং আউটপুটটি মোটামুটি এরকম:

				
					$ /tmp/fast-export/hg-fast-export.sh -r /tmp/hg-repo -A /tmp/authors
Loaded 4 authors
master: Exporting full revision 1/22208 with 13/0/0 added/changed/removed files
master: Exporting simple delta revision 2/22208 with 1/1/0 added/changed/removed files
master: Exporting simple delta revision 3/22208 with 0/1/0 added/changed/removed files
[...]
master: Exporting simple delta revision 22206/22208 with 0/4/0 added/changed/removed files
master: Exporting simple delta revision 22207/22208 with 0/2/0 added/changed/removed files
master: Exporting thorough delta revision 22208/22208 with 3/213/0 added/changed/removed files
Exporting tag [0.4c] at [hg r9] [git :10]
Exporting tag [0.4d] at [hg r16] [git :17]
[...]
Exporting tag [3.1-rc] at [hg r21926] [git :21927]
Exporting tag [3.1] at [hg r21973] [git :21974]
Issued 22315 commands
git-fast-import statistics:
---------------------------------------------------------------------
Alloc'd objects:     120000
Total objects:       115032 (    208171 duplicates                  )
      blobs  :        40504 (    205320 duplicates      26117 deltas of      39602 attempts)
      trees  :        52320 (      2851 duplicates      47467 deltas of      47599 attempts)
      commits:        22208 (         0 duplicates          0 deltas of          0 attempts)
      tags   :            0 (         0 duplicates          0 deltas of          0 attempts)
Total branches:         109 (         2 loads     )
      marks:        1048576 (     22208 unique    )
      atoms:           1952
Memory total:          7860 KiB
       pools:          2235 KiB
     objects:          5625 KiB
---------------------------------------------------------------------
pack_report: getpagesize()            =       4096
pack_report: core.packedGitWindowSize = 1073741824
pack_report: core.packedGitLimit      = 8589934592
pack_report: pack_used_ctr            =      90430
pack_report: pack_mmap_calls          =      46771
pack_report: pack_open_windows        =          1 /          1
pack_report: pack_mapped              =  340852700 /  340852700
---------------------------------------------------------------------

$ git shortlog -sn
   369  Bob Jones
   365  Joe Smith


				
			

এটায় প্রায় সবকিছু আছে। সমস্ত মারকিউরিয়াল ট্যাগগুলি গিট ট্যাগে রূপান্তরিত হয়েছে, এবং মারকিউরিয়াল ব্রাঞ্চ এবং বুকমার্কগুলি গিট ব্রাঞ্চ এ কনভার্ট হয়েছে। এখন আপনি রিপোজিটরিটি কে তার নতুন সার্ভার-সাইড এ পুশ করে দিতে প্রস্তুত:

				
					$ git remote add origin git@my-git-server:myrepository.git
$ git push origin --all
				
			
ব্যাজার

ব্যাজার হল অনেকটা গিট-এর মতই এবং এটি একটি ডিভিসিএস (ডিস্ট্রিবিউটেড ভার্সন কন্ট্রোল সিস্টেম) টুল, এবং আমরা একটি গিট রিপোকে খুব সহজেই একটি ব্যাজার গিট-এ রূপান্তর করতে পারি। এটা করার জন্য আমাদের bzr-fastimport প্লাগইন ব্যাবহার করে করতে হবে।

 

কিভাবে আমরা bzr-fastimport প্লাগিন ব্যাবহার করবো

bzr-fastimport প্লাগিন বিভিন্ন অপারেটিং সিস্টেম এর জন্য ভিন্ন ভিন্ন হয়ে থাকে, যেমনঃ লিনাক্স এবং উইন্ডোজ । প্রথম ক্ষেত্রে, সবচেয়ে সহজ হল bzr-fastimport প্যাকেজ ইনস্টল করা যা সমস্ত প্রয়োজনীয় ডিপেডেন্সি ইনস্টল করবে।

 

উদাহরণস্বরূপ, Debian এবং Derived দিয়ে : 

				
					$ sudo apt-get install bzr-fastimport
				
			

RHEL দিয়ে :

				
					$ sudo yum install bzr-fastimport
				
			

ফেডোরা, 22 ভার্সন প্রকাশের পর থেকে, নতুন প্যাকেজ ম্যানেজার হল dnf:

				
					$ sudo dnf install bzr-fastimport
				
			

প্যাকেজ গুলো ইনস্টল  না হলে, আপনি এটি একটি প্লাগইন হিসাবে ইনস্টল করতে পারেন:

				
					$ mkdir --parents ~/.bazaar/plugins     # creates the necessary folders for the plugins
$ cd ~/.bazaar/plugins
$ bzr branch lp:bzr-fastimport fastimport   # imports the fastimport plugin
$ cd fastimport
$ sudo python setup.py install --record=files.txt   # installs the plugin
				
			

এই প্লাগইনটি কাজ করার জন্য, আপনার ফাস্ট ইমপোর্ট পাইথন মডিউলেরও প্রয়োজন হবে। এটি ইনস্টল আছে কিনা তা পরীক্ষা করতে পারেন এবং নিম্নলিখিত কমান্ড দিয়ে এটি ইনস্টল করতে পারেন

				
					$ python -c "import fastimport"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: No module named fastimport
$ pip install fastimport
				
			
যদি এটা হয় তাহলে আপনি সরাসরি এই লিঙ্ক থেকে ডাউনলোড করতে পারেন :  https://pypi.python.org/pypi/fastimport/ এখ্ন আমরা দেখবো কিভাবে ব্যাজার রিপো ইমপোর্ট করে কাজ করতে হয় : 
একটি সিঙ্গেল ব্রাঞ্চ প্রজেক্ট: 
এখন আপনার ব্যাজার রিপো রয়েছে এমন ডিরেক্টরিতে চেইঞ্জ ডিরেক্টরি করুন এবং গিট শুরু করুন:
				
					$ cd /path/to/the/bzr/repository
$ git init
				
			

এখন, আপনি আপনার ব্যাজার রিপোজিটরি এক্সপোর্ট করতে পারেন এবং নিম্নলিখিত কমান্ড ব্যবহার করে এটিকে একটি গিট রিপোজিটরি রূপান্তর করতে পারেন:

				
					$ bzr fast-export --plain . | git fast-import
				
			

এটি সম্পুণ হতে একটু সময় নিতে পারে, এটা প্রোজেক্ট সাইজের উপর নির্ভর করে ।

 

কেইস অফ এ প্রজেক্ট উইথ এ মেইন ব্রাঞ্চ এন্ড এ ওয়ার্কিং ব্রাঞ্চ:

ধরুন আপনার দুটি ব্রাঞ্ছ আছে একটি হল মেইন ব্রাঞ্চ (myProject.trunk) এবং আর একটি হল ওয়ার্কিং ব্রাঞ্চ (myProject.work) যেটাতে আপনি কাজ করছেন

				
					$ ls
myProject.trunk myProject.work
				
			

গিট রিপোজিটরি তৈরি করুন এবং এতে চেইঞ্জ ডিরেক্টরি করুন:

				
					$ git init git-repo
$ cd git-repo
				
			

গিটে মাস্টার ব্রাঞ্চ থেকে পুল নিন:

				
					$ bzr fast-export --export-marks=../marks.bzr ../myProject.trunk | \
git fast-import --export-marks=../marks.git


				
			
গিটে ওয়ার্কিং ব্রাঞ্চ থেকে পুল নিন:
				
					$ bzr fast-export --marks=../marks.bzr --git-branch=work ../myProject.work | \
git fast-import --import-marks=../marks.git --export-marks=../marks.git
				
			

এখ্ন git branch লিখলেই দেখতে পাবো আমাদের দুটি ব্রাঞ্চ দেখাচ্ছে 

marks.bzr এবং marks.git

 
স্টেজিং এরিয়া সিঙ্ক্রোনাইজ করা:

আপনার যতগুলি ব্রাঞ্চ ছিল এবং আপনি যে ইম্পোর্ট পদ্ধতি ব্যবহার করেছেন তা যাই হোক না কেন, আপনার স্টেজিং এরিয়াটি হেড এর সাথে সিঙ্ক্রোনাইজ করা হয় না এবং বেশ কয়েকটি ব্রাঞ্চের ইম্পোর্ট এর সাথে, আপনার কাজের ডিরেক্টরিটিও সিঙ্ক্রোনাইজ করা হয় না। এই পরিস্থিতি সহজেই নিম্নলিখিত কমান্ড দ্বারা সমাধান করা হয়:

				
					$ git reset --hard HEAD
				
			
.bzrignor দিয়ে ফাইলগুলিকে ইগনোর করুন:

এখন ফাইলগুলি লক্ষ করে দেখুন। প্রথমে .bzrignore এর নাম পরিবর্তন করে .gitignore করতে হবে। যদি .bzrignore ফাইলে “!!” অথবা “RE:” দিয়ে শুরু হওয়া এক বা একাধিক লাইন থাকে, আপনাকে এটি পরিবর্তন করতে হবে এবং ব্যাজার ইগনোর করা । ঠিক একই ফাইলগুলিকে ইগনোর করার জন্য সম্ভবত বেশ কয়েকটি .gitignore ফাইল তৈরি করতে হবে৷

 

অবশেষে, আপনাকে একটি কমিট তৈরি করতে হবে মাইগ্রেশনের জন্য

				
					$ git mv .bzrignore .gitignore
$ # modify .gitignore if needed
$ git commit -am 'Migration from Bazaar to Git'


				
			
আপনার রিপোজিটরি কে সার্ভারে পুশ করেন।  
				
					$ git remote add origin git@my-git-server:mygitrepository.git
$ git push origin --all
$ git push origin --tags


				
			
পারফোর্স

পরের যে সিস্টেম থেকে আমরা ইম্পোর্ট করতে পারি তা হল পারফোর্স। উপরোক্ত আলোচনা সাপেক্ষে গিট আর পারফোর্স এর মধ্যে যোগাযোগ এর দুইটা উপায় আছে :

গিট-p4 আর পারফোর্স গিট ফিউশন 

 

পারফোর্স গিট ফিউশন: 

গিট ফিউশন এই কাজটি অনেকাংশে সহজ করে তোলে। এর জন্য প্রজেক্ট সেটিংস, ইউজার ম্যাপিং এবং ব্রাঞ্চ গুলা কনফিগার করতে হবে কনফিগারেশন ফাইল (গিট ফিউশন এ বলা হয়েছে) এর সাথে। এরপর রিপোজিটরি টা ক্লোন করে নিতে হবে। গিট ফিউশন একটা নেটিভ রিপোজিটরি করে দেয় যেটা পরবর্তীতে একটা নেটিভ গিট হোস্ট এ আমরা চাইলে পুশ করতে পারি। এমনকি আমরা পারফোর্স কেও গিট হোস্ট হিসেবে ব্যবহার করতে পারি।

 

গিট-p4: 

গিট-p4 একটি ইম্পোর্ট টুল হিসেবেও কাজ করতে পারে। আমরা পারফোর্স পাবলিক ডিপোট থেকে জ্যাম প্রজেক্ট ইম্পোর্ট করব। ক্লায়েন্ট সেটআপ করতে হলে, অবশ্যই P4PORT এনভায়রনমেন্ট ভ্যারিয়েবল এক্সপোর্ট করতে হবে যেটা পারফোর্স ডিপোট কে পয়েন্ট করবে। 

				
					$ export P4PORT=public.perforce.com:1666
				
			

নোট

ফলো করতে আপনার একটি পারফোর্স ডিপোট লাগবে কানেক্ট করার জন্য। আমরা public.perforce.com এ পাবলিক ডিপোট ব্যবহার করব আমাদের উদাহরণে, কিন্তু আপনি যেকোনো ডিপোট ব্যবহার করতে পারেন যেটায় আপনার অ্যাক্সেস আছে।

জ্যাম প্রজেক্ট কে পারফোর্স server থেকে ইম্পোর্ট করতে git p4 clone কমান্ড টি রান করুন আর এজন্য ডিপোট, প্রজেক্ট পাথ আর যে পাথ – এ প্রজেক্ট টা ইম্পোর্ট করবেন তা সাপ্লাই করতে হবে।

				
					$ git-p4 clone //guest/perforce_software/jam@all p4import
Importing from //guest/perforce_software/jam@all into p4import
Initialized empty Git repository in /private/tmp/p4import/.git/
Import destination: refs/remotes/p4/master
Importing revision 9957 (100%)


				
			

এই প্রজেক্ট এ শুধু একটি ব্রাঞ্চ আছে, কিন্তু আপনার যদি অনেক ব্রাঞ্চ থাকে যেগুলা ব্রাঞ্চ ভিউস (অথবা ডিরেক্টরি সেট) দিয়ে কনফিগার করা হয়েছে, আপনি –detect-branches flag ব্যবহার করে git p4 clone  করতে পারেন যা প্রজেক্ট এর সব ব্রাঞ্চ গুলা ইম্পোর্ট করবে। আরও বিশদ ভাবে জানার জন্য দেখুন 

ব্রাঞ্ছিং 

 

এই পর্যায়ে আপনার কাজটি প্রায় শেষ। যদি আপনি p4import  ডিরেক্টরি তে যান আর রান করেন git log, আপনি আপনার ইম্পোর্ট করা কাজটি দেখবেন :

				
					$ git log -2
commit e5da1c909e5db3036475419f6379f2c73710c4e6
Author: giles <giles@giles@perforce.com>
Date:   Wed Feb 8 03:13:27 2012 -0800

    Correction to line 355; change </UL> to </OL>.

    [git-p4: depot-paths = "//public/jam/src/": change = 8068]

commit aa21359a0a135dda85c50a7f7cf249e4f7b8fd98
Author: kwirth <kwirth@perforce.com>
Date:   Tue Jul 7 01:35:51 2009 -0800

    Fix spelling error on Jam doc page (cummulative -> cumulative).

    [git-p4: depot-paths = "//public/jam/src/": change = 7304]


				
			

আপনি খেয়াল করবেন যে, গিট-p4  প্রতিটা কমিট মেসেজ এ একটা আইডেন্টিফায়ার রেখেছে। এই আইডেন্টিফায়ার টি এখানে রাখা যাবে, পরবর্তীতে আপনার পারফোর্স টি রেফারেন্স করা প্রয়োজন হলে নাম্বার টি পরিবর্তন করতে পারেন। কিন্তু আপনি যদি আইডেন্টিফায়ার টি বদলাতে চান, এখনি করা উচিত – নতুন রিপোজিটরি তে কাজ শুরু করার আগে। আপনি  git filter-branch ব্যবহার করে আইডেন্টিফায়ার এন মেস সরাতে পারেনঃ 



				
					$ git filter-branch --msg-filter 'sed -e "/^\[git-p4:/d"'
Rewrite e5da1c909e5db3036475419f6379f2c73710c4e6 (125/125)
Ref 'refs/heads/master' was rewritten
				
			

যদি আপনি  git log run করেন, আপনি দেখবেন যে কমিট গুলার সব SHA-1 চেকসাম পরিবর্তন হয়েছে, কিন্তু গিট-p4 স্ট্রিং গুলা কমিট মেসেজ এ আর নেই :

				
					$ git log -2
commit b17341801ed838d97f7800a54a6f9b95750839b7
Author: giles <giles@giles@perforce.com>
Date:   Wed Feb 8 03:13:27 2012 -0800

    Correction to line 355; change </UL> to </OL>.

commit 3e68c2e26cd89cb983eb52c024ecdfba1d6b3fff
Author: kwirth <kwirth@perforce.com>
Date:   Tue Jul 7 01:35:51 2009 -0800

    Fix spelling error on Jam doc page (cummulative -> cumulative).
				
			

আপনার ইম্পোর্ট আপনার নতুন গিট সার্ভারে পুশ করার জন্য রেডি।

 

কাস্টম ইম্পোর্টার:

যদি আপনার সিস্টেম উপরের কোনোটিই না হয়ে থাকে, সেক্ষেত্রে আপনাকে একটি অনলাইন ইম্পোর্টার খুঁজতে হবে- এধরনের অনেক ইম্পোর্টার আছে যা সহজলভ্য এবং বিভিন্ন সিস্টেমের জন্য তা পার্ফেক্ট, এসব সিস্টেমের অন্তর্ভুক্ত সিভিএস, ক্লিয়ার কেইস, ভিজুয়াল সোর্স সেফ, এমনকি আর্কাইভ ডিরেক্টরি। যদি এসব টুল বা সিস্টেমের কোনোটাই আপনার না থেকে থাকে, তাহলে আপনার একটি কাস্টম ইম্পোর্টিং প্রসেস অনুসরণ করতে হবে, এজন্য ইউজ করুন 

				
					git fast-import 
				
			

 

এই কমান্ডটি স্পেসিফিক গিট ডাটা রাইট করতে stdin থেকে কিছু সিম্পল ইনস্ট্রাকশনস রিড করে। র-গিট কমান্ডস রান করানোর চেয়ে কিংবা র অবজেক্ট রাইট করার চেয়ে এই উপায়ে গিট অবজেক্ট ক্রিয়েট করা বেশি সহজ।(আরো তথ্য পেতে ক্লিক করুন গিট ইন্টারনালস)। এভাবে আপনি সহজেই একটি ইম্পোর্ট স্ক্রিপ্ট লিখে ফেলতে পারেন যা আপনার সিস্টেম (যা থেকে ইম্পোর্ট করতে হবে) থেকে প্রয়োজনীয় ইনফরমেশন রিড করে আনতে পারে এবং stdout এ সরাসরি ইন্সট্রাকশন হিসেবে প্রিন্ট করে। এরপর আপনি প্রোগ্রামটি রান করতে পারবেন এবং আউটপুটটি  git fast-import এর মাধ্যমে অন্য কমান্ড এর ইনপুট হিসেবে ব্যবহার করতে পারবেন।

 

সহজে বলতে গেলে, আপনি একটি সিম্পল ইম্পোর্টার লিখবেন। মনে করুন আপনি কারেন্ট এ কাজ করছেন, আপনি আপনার প্রজেক্ট মাঝে মাঝে কপি করে একটি time-stamped back_YYYY_MM_DD ব্যাকাপ ডিরেক্টরি তে কপি করে ব্যাকাপ হিসেবে রাখেন, এখন আপনি চাচ্ছেন আপনার প্রজেক্ট কে গিট এ ইম্পোর্ট করতে। আর আপনার ডিরেক্টরির স্ট্রাকচার নিচের মতঃ

				
					$ ls /opt/import_from
back_2014_01_02
back_2014_01_04
back_2014_01_14
back_2014_02_03
current
				
			

একটি গিট ডিরেক্টরি ইম্পোর্ট করতে হলে আগে জানতে হবে গিট কিভাবে এর ডাটা সংরক্ষণ করে। আশা করি আপনার মনে আছে যে, গিট মূলত কমিট অবজেক্ট এর একটি লিঙ্কড লিস্ট যা একটি কন্টেন্ট এর স্ন্যাপশট (সার্ভার রেসপন্সের কপি) কে নির্দেশ করে। আপনাকে যা করতে হবে তা হলো fast-import কে কন্টেন্ট এর স্ন্যাপশট গুলো বলে দেয়া, কোন কমিট ডাটা তাদেরকে নির্দেশ করছে এবং লিস্টে তারা কি অর্ডার মেইনটেইন করছে। আপনার স্ট্রাটেজি হবে প্রতিটি স্ন্যাপশট বিবেচনা করে প্রতিটি ডিরেক্টরির কন্টেন্টে কমিট ক্রিয়েট করা যাতে প্রতিটি কমিট তার পূর্ববর্তী কমিট এর সাথে লিঙ্কড থাকে। 

আমরা দেখেছি একটি গিট-এনফোর্সড পলিসির উদাহরণ, আমরা তা রুবী তে লিখবো, কারণ সাধারণত আমরা রুবী তে কাজ করি কারণ এটি সহজবোধ্য। আপনি চাইলে আপনার পরিচিত যেকোনো ল্যাংগুয়েজে উদাহরণটি করে দেখতে পারেন। এর জন্য দরকার শুধু সঠিক ইনফরমেশন গুলো stdout. এ প্রিন্ট হতে হবে। আর যদি আপনি উইন্ডোজ এ রান করে থাকেন, তার মানে আপনাকে সতর্ক থাকতে হবে যাতে লাইনের শেষে ক্যারিয়েজ রিটার্ন না করে, এক্ষেত্রে  git fast-import খুবই হেল্পফুল কারণ এটি শুধুমাত্র লাইন ফিডস রিটার্ন করে, ক্যারিয়েজ রিটার্ন লাইন ফিডস (CRLF) এ বাধা দেয় যা উইন্ডো ইউজ করে।

 

শুরুতে আপনি টার্গেট ডিরেক্টরিতে পরিবর্তন করবেন এবং প্রতিটি সাবডিরেক্টরি আইডেন্টিফাই করবেন,যার প্রতিটিই হলো সেই স্ন্যাপশট যা আপনি কমিট হিসেবে ইম্পোর্ট করতে চান। আপনি প্রতিটি সাবডিরেক্টরি তে চেঞ্জ করবেন এবং তা এক্সপোর্ট করতে প্রয়োজনীয় কমান্ড গুলো প্রিন্ট করবেন। আপনার ব্যাসিক মেইন লুপটি দেখতে এরকম হবেঃ 

				
					last_mark = nil

# loop through the directories
Dir.chdir(ARGV[0]) do
  Dir.glob("*").each do |dir|
    next if File.file?(dir)

    # move into the target directory
    Dir.chdir(dir) do
      last_mark = print_export(dir, last_mark)
    end
  end
end
				
			

এখানে আপনি প্রতিটি ডিরেক্টরি তে print_export রান করছেন,যা পূর্ববর্তী স্ন্যাপশট এর নির্দেশক এবং মার্ক নিয়ে নেয় এবং তা বর্তমান স্ন্যাপশট এ রিটার্ন করে, যার জন্য এদের মধ্যে ঠিকঠাক ভাবে লিংক তৈরি হয়। মার্ক হচ্ছে একটি আইডেন্টিফায়ারের  fast-import টার্ম যা একটি কমিট ক্রিয়েট এর সাথে সাথেই পাঠানো হয়। অর্থাৎ প্রতিটি কমিট কে একটি করে মার্ক দেয়া হয় যাতে আপনি অন্য কমিট গুলোর সাথে বর্তমান কমিট কে লিঙ্ক করতে পারেন। সুতরাং প্রথমেই print_export মেথড এ ডিরেক্টরির নাম থেকে একটি মার্ক জেনারেট করতে হবে। 

				
					mark = convert_dir_to_mark(dir)
				
			

এজন্য আপনি ডিরেক্টরি গুলো নিয়ে একটি অ্যারে বানাতে পারেন এবং এই অ্যারের ইনডেক্স ভ্যালুকে মার্ক হিসেবে ব্যবহার করতে পারেন, কারণ মার্ক অবশ্যই একটি ইন্টিজার ভ্যালু হতে হবে। আপনার মেথডটি হবে ঠিক এরকমঃ

				
					$marks = []
def convert_dir_to_mark(dir)
  if !$marks.include?(dir)
    $marks << dir
  end
  ($marks.index(dir) + 1).to_s
end
				
			

এখন যেহেতু আপনার কমিট এর একটি ইন্টিজার রিপ্রেজেন্টেশন আছে, আপনার কমিট এর মেটাডাটার জন্য একটি তারিখের প্রয়োজন। কারণ তারিখটি আপনার ডিরেক্টরির নামের সাথে থাকলে আপনার ডাটা পাঠানোর সময় সুবিধা হবে। আপনার print_export ফাইল এর পরবর্তী লাইনটি হবেঃ

				
					date = convert_dir_to_date(dir)
				
			

চলুন দেখি  convert_dir_to_date এ কি আছেঃ

				
					def convert_dir_to_date(dir)
  if dir == 'current'
    return Time.now().to_i
  else
    dir = dir.gsub('back_', '')
    (year, month, day) = dir.split('_')
    return Time.local(year, month, day).to_i
  end
end
				
			

 

এই  convert_dir_to_date প্রতিটি ডিরেক্টরির তারিখের জন্য একটি ইন্টিজার ভ্যালু রিটার্ন করে। সর্বশেষ যে মেটা-ইনফরমেশন টি আপনার দরকার তাহলো প্রতিটি কমিট এর জন্য একটি করে কমিটার ডাটা যা আপনি গ্লোবাল ভ্যারিয়েবল হিসেবে ডিক্লেয়ার করবেনঃ

				
					$author = 'John Doe <john@example.com>'
				
			

এখন আপনি আপনার ইম্পোর্টারের জন্য কমিট ডাটা গুলো প্রিন্ট করতে প্রস্তুত।  ইনিশিয়াল ইনফরমেশন নির্দেশ করে যে, আপনি একটি কমিট অবজেক্ট ডিফাইন করেছেন, অবজেক্টটি কোন ব্রাঞ্চে আছে (এ কাজটি করে আপনার জেনারেট করা মার্ক টি ব্যবহার করে), কমিটার এর ইনফরমেশন এবং কমিট করা ম্যাসেজটি এবং সবশেষে যদি পূর্বের কোনো কমিট থেকে থাকে সেটি। কোডটি দেখতে কিছুটা এরকমঃ

				
					# print the import information
puts 'commit refs/heads/master'
puts 'mark :' + mark
puts "committer #{$author} #{date} -0700"
export_data('imported from ' + dir)
puts 'from :' + last_mark if last_mark
				
			

এক্ষেত্রে সহজ উপায় হচ্ছে টাইম জোন (-০৭০০) কে একদম হার্ডকোড করে দেয়া। যদি আপনি অন্য কোনো সিস্টেম থেকে ইম্পোর্ট করে থাকেন তবে আপনাকে অবশ্যই টাইম জোন কে একটি অফসেট হিসেবে স্পেসিফাই করে দিতে হবে। আর কমিট ম্যাসেজটি অবশ্যই একটি স্পেশাল ফরম্যাট মেইনটেইন করবে। 

				
					data (size)\n(contents)
				
			

এই ফরম্যাট টি ওয়ার্ড ডাটা ( ডাটার সাইজ, একটি নতুন লাইন এবং ফাইনালি ডাটা কন্টেন্ট) কে নির্দেশ করছে। কারণ আপনাকে এই সেইম ফরম্যাটটিই পরবর্তীতে ফাইল কন্টেন্ট এ ব্যবহার করতে হবে এবং সেখানে আপনি একটি সাহায্যকারী মেথড ক্রিয়েট করবেন।

export_data:

				
					def export_data(string)
    print "data #{string.size}\n#{string}"
end
				
			

বাকি থাকলো প্রতিটি স্ন্যাপশট এর জন্য ফাইল কন্টেন্ট স্পেসিফাই করে দেয়া। এটা খুবই সহজ কাজ, কারণ আপনার প্রতিটি ফাইল এইটি ডিরেক্টরি তে আছে। তাই আপনি চাইলেই deleteall কমান্ডটি (ডিরেক্টরির প্রতিটি ফাইলের কন্টেন্ট কে নির্দেশ করে) প্রিন্ট আউট করে দিতে পারেন। এরপর দেখবেন গিট প্রতিটি স্ন্যাপশট ঠিকটঠাকভাবে রেকর্ড করছে।

				
					puts 'deleteall'
Dir.glob("**/*").each do |file|
  next if !File.file?(file)
  inline_data(file)
end
				
			

নোটঃ কারণ অনেক সিস্টেম তাদের পুনরায় ভিজিট করাটাকেই একটি কমিট থেকে অন্যটির চেঞ্জ হিসেবে মনে করে। fast-import কমান্ডের মাধ্যমে বুঝতে পারে প্রতিটি কমিট এ কোন ফাইলগুলো এড করা হয়েছে, মুছে ফেলা হয়েছে অথবা পরিবর্তন করা হয়েছে এবং কোনগুলো নতুন কন্টেন্ট। আপনি স্নাপশট গুলোর মধ্যে পরিবর্তনগুলি ক্যালকুলেট করেও এই ডাটাগুলো পেতে পারতেন কিন্তু সেটা খুবই কঠিন হতো। আপনি চাইলে গিট এ সব ডাটা দিয়ে গিট এর উপরেও এই দায়িত্ব ছেড়ে দিতে পারেন এসব ডাটা খুঁজে বের করার জন্য। 

 

যদি এটা আপনার ডাটার জন্য উপযোগী হয়, তাহলে আপনার ডাটা এই উপায়ে কিভাবে প্রোভাইড করতে হবে এটার ডিটেইলস দেখতে fast-import এর মেইন পেইজ চেক করুন। 

 

নতুন ফাইল কন্টেন্ট এর লিস্ট করতে অথবা নতুন কন্টেন্ট সম্বলিত একটি পরিবর্তিত ফাইল কে স্পেসিফাই করতে ফরম্যাটটি হচ্ছেঃ

				
					M 644 inline path/to/file
data (size)
(file contents)
				
			

এখানে ৬৪৪ হচ্ছে মোড (যদি আপনার কাছে এক্সিকিউটেবল ফাইল থাকে, আপনাকে সেটা ডিটেক্ট করে ৬৪৪ এর পরিবর্তে ৭৫৫কে স্পেসিফাই করে দিতে হবে) এবং ইনলাইন দিয়ে বুঝায় আপনি এই লাইনের পরপর ই কন্টেন্ট গুলোর লিস্ট করবেন। আপনার  inline_data মেথডটি হবে এরকমঃ

				
					def inline_data(file, code = 'M', mode = '644')
  content = File.read(file)
  puts "#{code} #{mode} inline #{file}"
  export_data(content)
end
				
			

আপনি আগে থেকে ডিফাইন করা export_data মেথড কে পুনরায় ব্যবহার করবেন, কারণ এটা করা আর আপনার কমিট ম্যাসেজ ডাটা স্পেসিফাই করার পদ্ধতি একই।

এখন আপনার সর্বশেষ কাজটি হচ্ছে বর্তমান মার্কটিকে রিটার্ন করে দেয়া যাতে এটি পরবর্তী ইটারেশনে পাস হতে পারে।

				
					return mark
				
			

নোটঃ

যদি আপনি ইউন্ডোজ ব্যবহার করে থাকেন তাহলে আপনাকে শিউর হতে হবে যে আপনি একটা এক্সট্রা স্টেপ নিয়েছেন। আগেই উল্লেখ করেছি যে ইউন্ডোজ  নিউ লাইনের জন্যে CRLF ব্যবহার করে, যেখানে গিট fast-import LF এস্পেক্ট করে। আপনাকে রুবিকে CRLF এর পরিবর্তে LF ব্যবহার করতে বলতে হবে।

$stdout.binmode

ব্যাস, এখানেই শেষ। তাহলে আপনার পুরো স্ক্রিপ্ট টা যেটা দাঁড়ালো তা হলোঃ

				
					
#!/usr/bin/env ruby

$stdout.binmode
$author = "John Doe <john@example.com>"

$marks = []
def convert_dir_to_mark(dir)
    if !$marks.include?(dir)
        $marks << dir
    end
    ($marks.index(dir)+1).to_s
end

def convert_dir_to_date(dir)
    if dir == 'current'
        return Time.now().to_i
    else
        dir = dir.gsub('back_', '')
        (year, month, day) = dir.split('_')
        return Time.local(year, month, day).to_i
    end
end

def export_data(string)
    print "data #{string.size}\n#{string}"
end

def inline_data(file, code='M', mode='644')
    content = File.read(file)
    puts "#{code} #{mode} inline #{file}"
    export_data(content)
end

def print_export(dir, last_mark)
    date = convert_dir_to_date(dir)
    mark = convert_dir_to_mark(dir)

    puts 'commit refs/heads/master'
    puts "mark :#{mark}"
    puts "committer #{$author} #{date} -0700"
    export_data("imported from #{dir}")
    puts "from :#{last_mark}" if last_mark

    puts 'deleteall'
    Dir.glob("**/*").each do |file|
        next if !File.file?(file)
        inline_data(file)
    end
    mark
end

# Loop through the directories
last_mark = nil
Dir.chdir(ARGV[0]) do
    Dir.glob("*").each do |dir|
        next if File.file?(dir)

        # move into the target directory
        Dir.chdir(dir) do
            last_mark = print_export(dir, last_mark)
        end
    end
end


				
			

যদি এই স্ক্রিপ্টটি আপনি রান করেন, আপনার কন্টেন্ট টি দেখতে এরকম হবেঃ

				
					$ ruby import.rb /opt/import_from
commit refs/heads/master
mark :1
committer John Doe <john@example.com> 1388649600 -0700
data 29
imported from back_2014_01_02deleteall
M 644 inline README.md
data 28
# Hello

This is my readme.
commit refs/heads/master
mark :2
committer John Doe <john@example.com> 1388822400 -0700
data 29
imported from back_2014_01_04from :1
deleteall
M 644 inline main.rb
data 34
#!/bin/env ruby

puts "Hey there"
M 644 inline README.md
(...)


				
			

এখন ইম্পোর্টারটিকে রান করতে,এই আউটপুট কে পাইপলাইনের মাধ্যমে গিট fast-import এ পাঠান যেই গিট ডিরেক্টরি তে আপনি ইম্পোর্ট করতে চাচ্ছেন। আপনি চাইলে একটি নতুন ডিরেক্টরি ক্রিয়েট করে তারপর এর স্টার্টিং পয়েন্ট এর জন্য git init রান করতে পারেন। এরপর আপনি আপনার স্ক্রিপ্ট টি রান করবেন।

				
					
$ git init
Initialized empty Git repository in /opt/import_to/.git/
$ ruby import.rb /opt/import_from | git fast-import
git-fast-import statistics:
---------------------------------------------------------------------
Alloc'd objects:       5000
Total objects:           13 (         6 duplicates                  )
      blobs  :            5 (         4 duplicates          3 deltas of          5 attempts)
      trees  :            4 (         1 duplicates          0 deltas of          4 attempts)
      commits:            4 (         1 duplicates          0 deltas of          0 attempts)
      tags   :            0 (         0 duplicates          0 deltas of          0 attempts)
Total branches:           1 (         1 loads     )
      marks:           1024 (         5 unique    )
      atoms:              2
Memory total:          2344 KiB
       pools:          2110 KiB
     objects:           234 KiB
---------------------------------------------------------------------
pack_report: getpagesize()            =       4096
pack_report: core.packedGitWindowSize = 1073741824
pack_report: core.packedGitLimit      = 8589934592
pack_report: pack_used_ctr            =         10
pack_report: pack_mmap_calls          =          5
pack_report: pack_open_windows        =          2 /          2
pack_report: pack_mapped              =       1457 /       1457
---------------------------------------------------------------------


				
			

দেখতেই পাচ্ছেন, যখন এটি সফলভাবে সম্পূর্ণ হয়, এটি কি কি কাজ সম্পন্ন করলো সে সংক্রান্ত কিছু স্ট্যাটিসটিক্স আপনাকে দিচ্ছে। এই ক্ষেত্রে আপনি ১৩ টি অবজেক্ট কে টোটাল ৪টি কমিট এর মাধ্যমে একটি ব্রাঞ্চ এ ইম্পোর্ট করেছেন। এখন আপনি git log রান করে আপনার নতুন হিস্টোরি টি দেখতে পাবেন।

				
					$ git log -2
commit 3caa046d4aac682a55867132ccdfbe0d3fdee498
Author: John Doe <john@example.com>
Date:   Tue Jul 29 19:39:04 2014 -0700

    imported from current

commit 4afc2b945d0d3c8cd00556fbe2e8224569dc9def
Author: John Doe <john@example.com>
Date:   Mon Feb 3 01:00:00 2014 -0700

    imported from back_2014_02_03
				
			

ফাইনালি,রেডি হয়ে গেলো একটি সুন্দর এবং ক্লিন গিট রিপোজিটরি। এটা খুবই জরুরি খেয়াল রাখা যাতে কোনো স্টেপ বাদ না পড়ে এবং শুরুতেই যাতে আপনার ওয়ার্কিং ডিরেক্টরি তে কোনো ফাইল না থাকে। যদি থেকে থাকে সেক্ষেত্রে আপনার ব্রাঞ্চ কে রিসেট করে নিতে হবে যেখানে বর্তমানে মাস্টার আছে।

				
					$ ls
$ git reset --hard master
HEAD is now at 3caa046 imported from current
$ ls
README.md main.rb
				
			

আপনি এই  fast-import  টুলটি কাজে লাগিয়ে আরো অনেক কিছুই করতে পারবেন – ডিফারেন্ট মোড  হ্যান্ডেল করা, বাইনারি ডাটা, মাল্টিপল ব্রাঞ্চ এবং তাদের একত্রিত করা (মার্জিং), প্রগ্রেস ইন্ডিকেটর হিসেবে ব্যবহার করা, এবং আরো অনেক কিছু। আরো কমপ্লেক্স সিচুয়েশন সম্বলিত উদাহরণ দেখতে চাইলে গিট সোর্স কোড এর  contrib/fast-import ডিরেক্টরিতে পাবেন।