৭.১২ গিট টুলস – বান্ডলিং
বান্ডলিং ( Bundling )
যদিও আমরা একটি নেটওয়ার্কের (HTTP, SSH, ইত্যাদি) মাধ্যমে গিট ডেটা স্থানান্তর করার সাধারণ উপায়গুলি কভার করেছি, তবে আসলে এটি করার আরও একটি উপায় রয়েছে যা সাধারণত ব্যবহৃত হয় না এবং এটি বেশ কার্যকর হতে পারে।
গিট আপনার ডেটা একটি একক ফাইলে “bundling” করতে পারে। এটি বিভিন্ন পরিস্থিতিতে কার্যকর হতে পারে। সম্ভবত আপনার নেটওয়ার্ক বন্ধ হয়ে গেছে এবং আপনি আপনার সহকর্মীদের সাথে পরিবর্তনগুলি জানাতে চান৷ আরো হতে পারে আপনি অন্য কোথাও কাজ করেন এবং নিরাপত্তার কারণে স্থানীয় নেটওয়ার্কে আপনার অ্যাক্সেস নেই।
এটাও সম্ভব যে আপনার ওয়্যারলেস বা নেটওয়ার্ক কার্ড সবেমাত্র ভেঙে গেছে। সম্ভবত আপনার বর্তমানে একটি শেয়ার্ড সার্ভারে অ্যাক্সেস নেই, কাউকে আপডেট ইমেল করতে চান এবং format-patch এর মাধ্যমে ৪০ টি কমিট করতে চান না।
এখানেই git bundle কমান্ডটি কাজে আসতে পারে। bundle কমান্ডটি এমন সবকিছু প্যাকেজ করবে যা সাধারণত একটি git push কমান্ডের সাহায্যে একটি বাইনারি ফাইলের উপরে পুশ করা হয় যা আপনি কাউকে ইমেল করতে পারেন বা ফ্ল্যাশ ড্রাইভে রাখতে পারেন, তারপর অন্য সংগ্রহস্থলে আনবান্ডেল করতে পারেন।
এর একটি সহজ উদাহরণ দেখা যাক। ধরা যাক আপনার কাছে দুটি কমিট সহ একটি repository রয়েছে:
$ git log
commit 9a466c572fe88b195efd356c3f2bbeccdb504102
Author: Scott Chacon
Date: Wed Mar 10 07:34:10 2010 -0800
Second commit
commit b1ec3248f39900d2a406049d762aa68e9641be25
Author: Scott Chacon
Date: Wed Mar 10 07:34:01 2010 -0800
First commit
আপনি যদি এই repository টি কারও কাছে push করতে চান, কিন্তু push করার জন্য repository অ্যাক্সেস না পান, বা এটি সেট আপ করতে চান না, আপনি git bundle create এর সাথে এটি বান্ডিল করতে পারেন।
$ git bundle create repo.bundle HEAD master
Counting objects: 6, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (6/6), 441 bytes, done.
Total 6 (delta 0), reused 0 (delta 0)
আপনার কাছে এখন repo.bundle নামে একটি ফাইল রয়েছে যাতে repository এর master শাখা পুনরায় তৈরি করার জন্য প্রয়োজনীয় সমস্ত ডেটা রয়েছে। bundle কমান্ডের জন্য আপনাকে প্রতিটি লিঙ্ক বা কমিটের একটি নির্দিষ্ট সেট তালিকাভুক্ত করতে হবে যা আপনি অন্তর্ভুক্ত করতে চান।
আপনি যদি এটি অন্য কোথাও ক্লোন করার পরিকল্পনা করেন, তাহলে আপনাকে একটি রেফারেন্স হিসাবে HEAD যোগ করতে হবে, যেমন আমরা এখানে করেছি।
আপনি এই repo.bundle ফাইলটি অন্য কাউকে পাঠাতে পারেন, অথবা এটি একটি USB ড্রাইভ এ নিয়ে কাজ মিটাতে পারেন।
অন্যদিকে, ধরা যাক আপনি এই repo.bundle ফাইলটি পেয়েছেন এবং এটার উপরে কাজ করতে চান। আপনি বাইনারি ফাইল থেকে একটি ডিরেক্টরিতে ক্লোন করতে পারেন, যেমন আপনি একটি URL থেকে করেন।
$ git clone repo.bundle repo
Cloning into 'repo'...
...
$ cd repo
$ git log --oneline
9a466c5 Second commit
b1ec324 First commit
আপনি যদি রেফারেন্সগুলিতে HEAD অন্তর্ভুক্ত না করেন তবে আপনাকে -b master বা যে কোন branch এ অন্তর্ভুক্ত করা হয়েছে তাও উল্লেখ করতে হবে কারণ অন্যথায় কোন branch চেক আউট করতে হবে তা এটি জানবে না।
এখন ধরা যাক আপনি এটিতে তিনটি কমিট করেছেন এবং একটি USB স্টিক বা ইমেলের বান্ডিলের মাধ্যমে নতুন কমিটগুলি ফেরত পাঠাতে চান।
$ git log --oneline
71b84da Last commit - second repo
c99cf5b Fourth commit - second repo
7011d3d Third commit - second repo
9a466c5 Second commit
b1ec324 First commit
প্রথমত, আমরা যে প্যাকেজে অন্তর্ভুক্ত করতে চাই সেটার কমিটের পরিসীমা নির্ধারণ করতে হবে। নেটওয়ার্ক প্রোটোকলের বিপরীতে, যা নেটওয়ার্কের মাধ্যমে প্রেরণ করা ডেটার ন্যূনতম সেট সংজ্ঞায়িত করে, আমাদের এটি ম্যানুয়ালি সংজ্ঞায়িত করতে হবে। এখন আপনি একই কাজ করতে পারেন এবং সম্পূর্ণ রিপোজিটরি একত্রিত করতে পারেন যেটা কাজ করবে, তবে পার্থক্যগুলিকে একত্রিত করা ভাল- শুধুমাত্র তিনটি কমিট আমরা স্থানীয়ভাবে তৈরি করেছি।
এটি করার জন্য, আপনাকে পার্থক্য গণনা করতে হবে। আমাদের মাস্টার ব্রাঞ্চে যে তিনটি কমিট আছে যা আমরা মূলত ক্লোন করেছিলাম সেই শাখায় ছিল না, আমরা origin/master..master or master ^origin/master এর মত কিছু ব্যবহার করতে পারি। আপনি log কমান্ড দিয়ে এটি টেস্ট করে দেখতে পারেন।
$ git log --oneline master ^origin/master
71b84da Last commit - second repo
c99cf5b Fourth commit - second repo
7011d3d Third commit - second repo
তাই এখন আমাদের কাছে কমিটের একটি তালিকা রয়েছে যা আমরা list করতে চাই, আসুন তাদের বান্ডেল করি। আমরা git bundle create কমান্ড দিয়ে এটি করি, এটিকে ফাইলের নামে নাম দিয়ে দিই যা আমরা আমাদের bundle করতে চাই এবং কমিটের পরিসীমা আমরা এখানে রাখতে চাই।
$ git bundle create commits.bundle master ^9a466c5
Counting objects: 11, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (9/9), 775 bytes, done.
Total 9 (delta 0), reused 0 (delta 0)
এখন আমাদের ডিরেক্টরিতে একটি commits.bundle ফাইল আছে। যদি আমরা এটিকে আমাদের সাথে নিয়ে যাই এবং আমাদের অংশীদারের কাছে পাঠাই, তবে তিনি এটিকে original repository তে ইম্পোর্ট করতে সক্ষম হবেন, যদিও এর মধ্যে অতিরিক্ত কাজ করা হয়ে থাকে।
আপনি যখন একটি bundle চেকআউট করেন, তখন আপনি এটিকে আপনার repository ইম্পোর্ট করার আগে ভিতরে কী আছে তা দেখতে পারেন। প্রথম কমান্ডটি bundle verify কমান্ড, যা নিশ্চিত করে যে ফাইলটি প্রকৃতপক্ষে একটি বৈধ গিট প্যাকেজ।
$ git bundle verify ../commits.bundle
The bundle contains 1 ref
71b84daaf49abed142a373b6e5c59a22dc6560dc refs/heads/master
The bundle requires these 1 ref
9a466c572fe88b195efd356c3f2bbeccdb504102 second commit
../commits.bundle is okay
যদি packer তিনটির পরিবর্তে শুধুমাত্র শেষ দুটি কমিট একত্রিত করে থাকে, তবে মূল repository এটি আমদানি করতে সক্ষম হবে না কারণ এতে প্রয়োজনীয় ইতিহাসের অভাব রয়েছে। পরিবর্তে, verify কমান্ডটি দেখতে এইরকম হবে:
$ git bundle verify ../commits-bad.bundle
error: Repository lacks these prerequisite commits:
error: 7011d3d8fc200abe0ad561c011c3852a4b7bbe95 Third commit - second repo
যাইহোক, আমাদের প্রথম বান্ডেল valid, তাই আমরা এটি থেকে কমিট আনতে পারি। আপনি যদি দেখতে চান যে বান্ডেলে কোন branch থেকে import করা যেতে পারে, তবে শুধুমাত্র প্রধান গুলি তালিকাভুক্ত করার জন্য একটি কমান্ড রয়েছে:
$ git bundle list-heads ../commits.bundle
71b84daaf49abed142a373b6e5c59a22dc6560dc refs/heads/master
verify সাবকমান্ড আপনাকে head গুলির কথা বলবে। পয়েন্টটি হল কী pull করা যায় তা দেখা যাতে আপনি সেই প্যাকেজ থেকে কমিট ইম্পোর্ট করতে fetch বা pull কমান্ড ব্যবহার করতে পারেন। এখানে আমরা প্যাকেজের master branch টিকে আমাদের repository এর other-master নামে একটি branch এ fetch করতে যাচ্ছি:
$ git fetch ../commits.bundle master:other-master
From ../commits.bundle
* [new branch] master -> other-master
এখন আমরা দেখতে পাচ্ছি যে আমাদের other-master branch এ import করা কমিট রয়েছে এবং সেইসাথে আমাদের নিজস্ব master branch এ আমরা যে কোনো কমিট করেছি।
$ git log --oneline --decorate --graph --all
* 8255d41 (HEAD, master) Third commit - first repo
| * 71b84da (other-master) Last commit - second repo
| * c99cf5b Fourth commit - second repo
| * 7011d3d Third commit - second repo
|/
* 9a466c5 Second commit
* b1ec324 First commit
সুতরাং, যখন আপনার কাছে সঠিক নেটওয়ার্ক বা shared repository না থাকে তখন, git bundle নেটওয়ার্ক-টাইপ অপারেশনগুলি করার জন্য সত্যই কার্যকর হতে পারে।