Menu
৩.১:গিট ব্রাঞ্চিং – ব্রাঞ্চ সমূহের সারসংক্ষেপ
প্রায় প্রতিটি ভার্সন কন্ট্রোল সিস্টেমেই কিছু ব্রাঞ্চিং সমর্থন রয়েছে। ব্রাঞ্চিং বলতে মূলত আপনার ডেভেলাপমেন্ট এর প্রধান লাইন থেকে সরে আসা এবং সেই প্রধান লাইনের সাথে কোনরূপ ঝামেলা না করে কাজ চলমান রাখাকে বোঝায়। অধিকাংশ ভার্সন কন্ট্রোল সিস্টেম টুল এ, এটি একটি সময়সাপেক্ষ প্রক্রিয়া যেখানে প্রায়ই আপনাকে সোর্স কোড ডিরেক্টরীর একটি নতুন কপি তৈরী করতে হয়, যা বড় প্রজেক্টগুলোতে অনেক বেশী সময় নিতে পারে।
অনেকেই গিট এর ব্রাঞ্চিং মডেলটিকে একটি “অনন্য বৈশিষ্ট্য” হিসেবে উল্লেখ করেন এবং এই বৈশিষ্ট্যই সত্যিকার অর্থে ভার্সন কন্ট্রোল সিস্টেমগুলোর মাঝে গিট-কে আলাদা করে তুলেছে। এর বিশেষত্ব কি? গিট ব্রাঞ্চিং করার পদ্ধতি অত্যন্ত সহজ, ব্রাঞ্চিং অপারেশানগুলো তাৎক্ষনিকভাবে তৈরী করা যায় এবং এক ব্রাঞ্চ থেকে অন্য ব্রাঞ্চে সহজে পরিবর্তন করা যায়। অন্যান্য ভার্সন কন্ট্রোল সিস্টেমগুলোর মত না হয়ে, গিট বরং একদিনে একাধিকবার ব্রাঞ্চিং এবং মার্জ করাকে উৎসাহিত করে। অনন্য এই ফিচারটি সঠিকভাবে বুঝতে ও এতে দক্ষতা অর্জন করতে পারলে, এটি আপনার জন্যে একটি গুরুত্বপূর্ন এবং অনন্য টুল হতে পারে, যা আপনার ডেভেলাপ করার প্রক্রিয়াতেও পুরোপুরি পরিবর্তন আনতে সক্ষম। গিট নিজে থেকে আপনার কমান্ড অনুমান করে না যদি আপনি সেটি আংশিক টাইপ করেন। যদি আপনি গিট কমান্ডের সম্পুর্ণ অংশ নিজে টাইপ করতে না চান, তাহলে আপনি খুব সহজেই প্রতিটি নির্দেশনার জন্য এলিয়াস সেট আপ করে নিতে পারেন git config ব্যবহার করে। এখানে কিছু উদাহরণ দিয়ে দেয়া হল যেটা আপনি সেট আপ করতে চাইবেন:
অনেকেই গিট এর ব্রাঞ্চিং মডেলটিকে একটি “অনন্য বৈশিষ্ট্য” হিসেবে উল্লেখ করেন এবং এই বৈশিষ্ট্যই সত্যিকার অর্থে ভার্সন কন্ট্রোল সিস্টেমগুলোর মাঝে গিট-কে আলাদা করে তুলেছে। এর বিশেষত্ব কি? গিট ব্রাঞ্চিং করার পদ্ধতি অত্যন্ত সহজ, ব্রাঞ্চিং অপারেশানগুলো তাৎক্ষনিকভাবে তৈরী করা যায় এবং এক ব্রাঞ্চ থেকে অন্য ব্রাঞ্চে সহজে পরিবর্তন করা যায়। অন্যান্য ভার্সন কন্ট্রোল সিস্টেমগুলোর মত না হয়ে, গিট বরং একদিনে একাধিকবার ব্রাঞ্চিং এবং মার্জ করাকে উৎসাহিত করে। অনন্য এই ফিচারটি সঠিকভাবে বুঝতে ও এতে দক্ষতা অর্জন করতে পারলে, এটি আপনার জন্যে একটি গুরুত্বপূর্ন এবং অনন্য টুল হতে পারে, যা আপনার ডেভেলাপ করার প্রক্রিয়াতেও পুরোপুরি পরিবর্তন আনতে সক্ষম। গিট নিজে থেকে আপনার কমান্ড অনুমান করে না যদি আপনি সেটি আংশিক টাইপ করেন। যদি আপনি গিট কমান্ডের সম্পুর্ণ অংশ নিজে টাইপ করতে না চান, তাহলে আপনি খুব সহজেই প্রতিটি নির্দেশনার জন্য এলিয়াস সেট আপ করে নিতে পারেন git config ব্যবহার করে। এখানে কিছু উদাহরণ দিয়ে দেয়া হল যেটা আপনি সেট আপ করতে চাইবেন:
ব্রাঞ্চ সমূহের সারসংক্ষেপ
সত্যিকারভাবে গিট কিভাবে তার ব্রাঞ্চিং করে, তা জানতে হলে আমাদেরকে এক ধাপ পেছনে গিয়ে কিভাবে গিট তার ডেটা সংরক্ষণ করে তা জানতে হবে।(গিট কি?) থেকে আপনারা নিশ্চয়ই জানেন, পরিবর্তন কিংবা পার্থক্যের ধারা হিসেবে সংরক্ষনের পরিবর্তে গিট ডেটাকে স্ন্যাপশট – এর একটি ধারা হিসেবে সংরক্ষন করে।
যখনই আপনি একটি কমিট তৈরী করেন, গিট একটি কমিট অবজেক্ট সংরক্ষণ করে, যেখানে আপনার স্টেজ করা কন্টেন্টটির স্ন্যাপশটের একটি পয়েন্টার থাকে। এই অব্জেক্টটিতে লেখকের নাম, ইমেইল এড্রেস, আপনার টাইপ করা মেসেজ, এবং পূর্ববর্তী কমিটগুলো থেকে সরাসরি আগত কমিট অথবা কমিটগুলোর পয়েন্টারগুলো থাকে (এর প্যারেন্ট/প্যারেন্টস)ঃ প্রাথমিক কমিটের জন্য কোন প্যারেন্ট থাকে না, একটি সাধারণ কমিটের জন্যে একটি প্যারেন্ট, এবং যে কমিট দুই বা ততোধিক ব্রাঞ্চ থেকে একটি মার্জ এর মাধ্যমে এসেছে, তার ক্ষেত্রে একাধিক প্যারেন্ট থাকে।
এটি বোঝার জন্যে ধরে নিন, আপনার একটি ডিরেক্টরী রয়েছে যাতে তিনটি ফাইল আছে, এবং আপনি সবগুলো ফাইলকে কমিট করে স্টেজ করলেন। ফাইলগুলোকে স্টেজ করার ফলে প্রতিটি ফাইলের জন্যে checksum প্রক্রিয়া করে, গিট এর সেই ভার্সনটি Git repository(গিট তাদের blobs বলে) তে সংরক্ষণ করে, এবং সেই checksum গুলোকে স্টেজ এর জায়গায় সংযুক্ত করে।
$ git add README test.rb LICENSE
$ git commit -m 'Initial commit'
যখন আপনি git commit রান করার মাধ্যমে গিট কমিট তৈরী করেন, গিট প্রতিটি সাব-ডিরেক্টরীর চেকসাম করে নেয়(এক্ষেত্রে শুধু রুট প্রজেক্ট ডিরেক্টরী) এবং এদেরকে গিট রিপোজিটরীতে একটি ট্রি অবজেক্ট হিসেবে সংরক্ষণ করে। এরপর গিট একটি কমিট অবজেক্ট তৈরী করে যাতে মেটাডেটা এবং রুট প্রজেক্ট ট্রি এর একটি পয়েন্টার থাকে, যাতে প্রয়োজন হলেই ঐ স্ন্যাপশটটি পুনরায় তৈরী করা যায়।
আপনার গিট রিপোজিটরীতে বর্তমানে ৫ টি অবজেক্ট রয়েছেঃ ৩ টি blobs(প্রতিটিই তিনটী ফাইলের কন্টেন্ট উপস্থাপন করে ), একটি tree যা ডিরেক্টরীর কন্টেন্টগুলিকে তালিকাবদ্ধ করে এবং কোন ফাইলটি কোন ব্লবে সংরক্ষিত আছে তা নির্দিষ্ট করে, এবং একটি commit এর সাথে রুট ট্রি এর একটি পয়েন্টার এবং কমিটের সকল মেটাডেটা।
আপনার গিট রিপোজিটরীতে বর্তমানে ৫ টি অবজেক্ট রয়েছেঃ ৩ টি blobs(প্রতিটিই তিনটী ফাইলের কন্টেন্ট উপস্থাপন করে ), একটি tree যা ডিরেক্টরীর কন্টেন্টগুলিকে তালিকাবদ্ধ করে এবং কোন ফাইলটি কোন ব্লবে সংরক্ষিত আছে তা নির্দিষ্ট করে, এবং একটি commit এর সাথে রুট ট্রি এর একটি পয়েন্টার এবং কমিটের সকল মেটাডেটা।
যদি আপনি কিছু পরিবর্তন করেন এবং পুনরায় কমিট করেন, পরবর্তী কমিটটি তার আগে আসা এই কমিটটির জন্যে একটি পয়েন্টার সংরক্ষণ করে।
একটি ব্রাঞ্চ মূলত গিটের কমিটগুলোর জন্যে একটি সহজ সচল পয়েন্টার। গিটের ডিফল্ট ব্রাঞ্চটির নাম হল মাস্টার। আপনি কমিট করা শুরু করার সাথে সাথে সেগুলো মাস্টার ব্রাঞ্চ এ দেওয়া আপনার শেষ কমিটকে নির্দেশ করে। প্রতিবার আপনি কমিট করলে, মাস্টার ব্রাঞ্চ পয়েন্টার স্বয়ংক্রিয়ভাবে সামনের দিকে এগিয়ে যায়
নোট
গিটের “master” ব্রাঞ্চটি একটি বিশেষ ব্রাঞ্চ নয়। এটি অন্যান্য ব্রাঞ্চের মতোই। প্রায় প্রতিটি রিপোজিটিতে এটি থাকে তার একমাত্র কারণ হল git init কমান্ড এটিকে ডিফল্টরূপে তৈরি করে এবং সাধারণত বেশিরভাগ লোকেরা এটি পরিবর্তন করে না।
একটি নতুন ব্রাঞ্চ তৈরী করা
যখন আপনি একটু নতুন ব্রাঞ্চ তৈরি করেন, তখন কি ঘটে? নতুন ব্রাঞ্চ মূলত আপনার জন্যে নতুন একটি পয়েন্টার তৈরি করে। ধরা যাক, আপনি একটি নতুন ব্রাঞ্চ তৈরী করতে চাইছেন, যার নাম হল “testing”। সহজেই আপনি এই গিট কমান্ডটি ব্যবহার করে তা করতে পারেনঃ
$ git branch testing
এটি মূলত আপনি যে কমিটটিতে আছেন, তাতেই একটি নতুন পয়েন্টার তৈরি করে।
আপনি বর্তমানে কোন ব্রাঞ্চে আছেন, গিট তা কিভাবে বুঝতে পারে? এটি একটি বিশেষ পয়েন্টার রাখে যাকে বলা হয় HEAD। মনে রাখতে হবে, এই HEAD এর ধারণাটি আপনার পরিচিত অন্যান্য VCSs এর তুলনায় অনেকাংশেই ভিন্ন, যেমন Subversion অথবা CVS। গিটের ক্ষেত্রে, এটি আপনি বর্তমানে যেই ব্রাঞ্চে আছেন, সে লোকাল ব্রাঞ্চের একটি পয়েন্টার। এক্ষেত্রে, আপনি এখনও master এই আছেন। গিট এর নতুন ব্রাঞ্চ খোলার জন্যে ব্যবহৃত কমান্ডটি আপনাকে শুধু একটি নতুন ব্রাঞ্চ-ই created তথা তৈরী করে দিয়েছে, সেই ব্রাঞ্চে সুইচ অর্থাৎ পরিবর্তন করে দেয়নি।
আপনি সহজেই git log কমান্ড ব্যবহার করে দেখতে পারেন ব্রাঞ্চের পয়েন্টারটি আপনাকে কোথায় নির্দেশ করছে। অপশানটিকে বলা হয় –decorate
$ git log --oneline --decorate
f30ab (HEAD -> master, testing) Add feature
#32 - ability to add new formats to the central interface
34ac2 Fix bug #1328 - stack overflow under certain conditions
98ca9 Initial commit
আপনি master এবং testing ব্রাঞ্চকে f30ab কমিটের পাশেই দেখতে পারেন।
ব্রাঞ্চ পরিবর্তন
অস্তিত্বসম্পন্ন একটি ব্রাঞ্চে পরিবর্তন করতে git checkout কমান্ডটি রান করতে পারেন। নতুন testing ব্রাঞ্চে পরিবর্তন করা যাক।
$ git checkout testing
এটি HEAD কে নিয়ে testing ব্রাঞ্চের দিকে নির্দেশ করে।
এটির গুরুত্ব কি? যাই হোক, এবার আরেকটি কমিট করা যাকঃ
$ vim test.rb
$ git commit -a -m 'made a change'
এটি মজার, কারণ এখন আপনার testing ব্রাঞ্চটি সামনের দিকে এগিয়ে গেছে, কিন্তু আপনার master ব্রাঞ্চটি এখনও সেই কমিটকেই নির্দেশ করছে, যে কমিটটিতে আপনি ব্রাঞ্চ পরিবর্তন করার জন্যে git checkout কমান্ডটি রান করেছিলেন। এবার master ব্রাঞ্চে পুনরায় ফিরে যাওয়া যাকঃ
$ git checkout master
নোট
git log সবসময় সব ব্রাঞ্চ দেখায় না।
আপনি যদি এখনই git log চালাতে চান তবে আপনি ভেবে অবাক হতে পারেন যে আপনার তৈরি করা “testing” ব্রাঞ্চটি কোথায় গেছে, কারণ এটি আউটপুটে প্রদর্শিত হবে না।
ব্রাঞ্চটি অদৃশ্য হয়নি; গিট শুধু জানে না যে আপনি ঐ ব্রাঞ্চে আগ্রহী এবং এটি যেটা আপনি আগ্রহী বলে মনে করে তাই দেখানোর চেষ্টা করছে। অন্য কথায়, ডিফল্টরূপে, গিট লগ শুধুমাত্র আপনার চেক আউট করা ব্রাঞ্চগুলোর কমিট history দেখাবে।
আপনার পছন্দসই ব্রাঞ্চের কমিটের history দেখাতে হলে আপনাকে স্পষ্টভাবে এটির নাম নির্দিষ্ট করতে হবে: git log testing। সমস্ত ব্রাঞ্চএর লগ দেখাতে,আপনার git log কমান্ডে –all যোগ করুন।
আপনি যদি এখনই git log চালাতে চান তবে আপনি ভেবে অবাক হতে পারেন যে আপনার তৈরি করা “testing” ব্রাঞ্চটি কোথায় গেছে, কারণ এটি আউটপুটে প্রদর্শিত হবে না।
ব্রাঞ্চটি অদৃশ্য হয়নি; গিট শুধু জানে না যে আপনি ঐ ব্রাঞ্চে আগ্রহী এবং এটি যেটা আপনি আগ্রহী বলে মনে করে তাই দেখানোর চেষ্টা করছে। অন্য কথায়, ডিফল্টরূপে, গিট লগ শুধুমাত্র আপনার চেক আউট করা ব্রাঞ্চগুলোর কমিট history দেখাবে।
আপনার পছন্দসই ব্রাঞ্চের কমিটের history দেখাতে হলে আপনাকে স্পষ্টভাবে এটির নাম নির্দিষ্ট করতে হবে: git log testing। সমস্ত ব্রাঞ্চএর লগ দেখাতে,আপনার git log কমান্ডে –all যোগ করুন।
ওই কমান্ডটি দুটো কাজ করেছে। এটি HEAD পয়েন্টারটিকে পুনরায় master ব্রাঞ্চকে নির্দেশ করতে নিয়ে যায়, এবং এটি ফাইলগুলোকে আপনার working directory থেকে পুনরায় ঐ master এর নির্দেশ করা snapshot এর কাছে ফিরিয়ে দেয়। এর মানে হল, আপনি এই পয়েন্ট থেকে সামনের দিকে যে পরিবর্তনগুলো করবেন, তা প্রজেক্টটির পুরনো ভার্সন থেকে ভিন্ন হতে থাকবে। এটি মূলত আপনার testing ব্রাঞ্চে আপনার করা কাজগুলিকে গুটিয়ে নেয় যাতে আপনি অন্য দিকে যেতে পারেন।:
নোট
ব্রাঞ্চ পরিবর্তন করলে তা আপনার কাজের ডিরেক্টরিতে ফাইল পরিবর্তন করে
এটি লক্ষ্য করা গুরুত্বপূর্ণ যে আপনি যখন Git-এ ব্রাঞ্চগুলি পরিবর্তন করবেন, আপনার কার্যকারী ডিরেক্টরির ফাইলগুলি পরিবর্তন হবে। আপনি যদি একটি পুরানো ব্রাঞ্চে স্যুইচ করেন, তাহলে আপনার কার্যনির্বাহী ডিরেক্টরিটি সেই ব্রাঞ্চে শেষবার কমিট করার পর যেমনটি ছিল তেমনটিই দেখাবে। যদি গিট পরিষ্কারভাবে এটি করতে না পারে তবে এটি আপনাকে মোটেও স্যুইচ করতে দেবে না।
এটি লক্ষ্য করা গুরুত্বপূর্ণ যে আপনি যখন Git-এ ব্রাঞ্চগুলি পরিবর্তন করবেন, আপনার কার্যকারী ডিরেক্টরির ফাইলগুলি পরিবর্তন হবে। আপনি যদি একটি পুরানো ব্রাঞ্চে স্যুইচ করেন, তাহলে আপনার কার্যনির্বাহী ডিরেক্টরিটি সেই ব্রাঞ্চে শেষবার কমিট করার পর যেমনটি ছিল তেমনটিই দেখাবে। যদি গিট পরিষ্কারভাবে এটি করতে না পারে তবে এটি আপনাকে মোটেও স্যুইচ করতে দেবে না।
আবার কিছু পরিবর্তন এবং কমিট করা যাকঃ
$ vim test.rb
$ git commit -a -m 'made other changes'
এখন আপনার প্রজেক্ট এর history ভিন্ন হয়ে গেছে(দেখুন ডাইভার্জেন্ট history)। আপনি একটি ব্রাঞ্চ তৈরি করে তাতে পরিবর্তন করলেন, এই ব্রাঞ্চে কিছু কাজ করলেন, এবং পুনরায় আপনার main বা প্রধান ব্রাঞ্চে পরিবর্তন করলেন এবং অন্য কিছু কাজ করলেন। উভয় পরিবর্তন ই আলাদা ব্রাঞ্চে বিচ্ছিন্নভাবে রয়েছেঃ আপনি ব্রাঞ্চগুলির মধ্যে সামনে পিছনে পরিবর্তন করতে পারেন এবং প্রস্তুতি শেষে, সেগুলিকে merge বা একত্রিত করতে পারেন৷ এবনফ এই সবকিছুই আপনি সাধারণ branch, checkout, এবং commit কমান্ডের মাধ্যমে করেছেন।
আপনি git log কমান্ডের মাধ্যমে এটি সহজেই দেখতে পারেন। যদি আপনি git log –oneline –decorate –graph –all কমান্ডটি রান করেন, এটি আপনার কমিটের ইতিহাস প্রিন্ট করবে, আপনার ব্রাঞ্চ পয়েন্টারগুলি কোথায় এবং আপনার history কীভাবে পরিবর্তিত হয়েছে, তা দেখাবে।
$ git log --oneline --decorate --graph --all
* c2b9e (HEAD, master) Made other changes
| * 87ab2 (testing) Made a change
|/
* f30ab Add feature #32 - ability to add new formats to the central interface
* 34ac2 Fix bug #1328 - stack overflow under certain conditions
* 98ca9 initial commit of my project
কারণ গিট এ, একটি ব্রাঞ্চ মূলত একটা সাধারণ ফাইল যা কমিটটির দিকে নির্দেশ করা ৪০ ক্যারেক্টার SHA-1 চেকসাম ধারণ করে, ব্রাঞ্চগুলো সহজেই করা এবং ধ্বংস করা যায়। একটি নতুন ব্রাঞ্চ তৈরি করা একটি ফাইলে 41 বাইট লেখার মতো দ্রুত এবং সহজ (40 ক্যারেক্টার এবং একটি নতুন লাইন)
এটি বেশিরভাগ পুরানো VCS টুলস গুলোর ব্রাঞ্চের সম্পূর্ণ বিপরীত, যার মধ্যে প্রজেক্টের সমস্ত ফাইল একটি দ্বিতীয় ডিরেক্টরিতে কপি করা থাকে। এটি প্রজেক্টের আকারের উপর নির্ভর করে কয়েক সেকেন্ড বা এমনকি মিনিট সময় নিতে পারে, যেখানে গিট-এ প্রক্রিয়াটি সর্বদা তাৎক্ষনিক হয়। এছাড়াও, যেহেতু আপরা যখনই কমিট করি, তখনই প্যারেন্ট গুলোকে রেকর্ড করি, তাই মার্জ করার জন্য একটি সঠিক মার্জ বেস খুঁজে পাওয়া আমাদের জন্য স্বয়ংক্রিয়ভাবে সম্পন্ন হয় এবং সাধারণত এটি করা খুব সহজ। এই বৈশিষ্ট্যগুলি ডেভেলাপারদের প্রায়শই ব্রাঞ্চ তৈরি করতে এবং ব্যবহার করতে উৎসাহিত করতে সহায়তা করে।
চলুন দেখি, কেন আপনার এটি করা উচিত।
এটি বেশিরভাগ পুরানো VCS টুলস গুলোর ব্রাঞ্চের সম্পূর্ণ বিপরীত, যার মধ্যে প্রজেক্টের সমস্ত ফাইল একটি দ্বিতীয় ডিরেক্টরিতে কপি করা থাকে। এটি প্রজেক্টের আকারের উপর নির্ভর করে কয়েক সেকেন্ড বা এমনকি মিনিট সময় নিতে পারে, যেখানে গিট-এ প্রক্রিয়াটি সর্বদা তাৎক্ষনিক হয়। এছাড়াও, যেহেতু আপরা যখনই কমিট করি, তখনই প্যারেন্ট গুলোকে রেকর্ড করি, তাই মার্জ করার জন্য একটি সঠিক মার্জ বেস খুঁজে পাওয়া আমাদের জন্য স্বয়ংক্রিয়ভাবে সম্পন্ন হয় এবং সাধারণত এটি করা খুব সহজ। এই বৈশিষ্ট্যগুলি ডেভেলাপারদের প্রায়শই ব্রাঞ্চ তৈরি করতে এবং ব্যবহার করতে উৎসাহিত করতে সহায়তা করে।
চলুন দেখি, কেন আপনার এটি করা উচিত।
নোট
একটি নতুন ব্রাঞ্চ তৈরি করা এবং একই সময়ে তাতে সুইচ করা
একটি নতুন ব্রাঞ্চ তৈরি করা এবং একই সময়ে সেই নতুন শাখায় যেতে চাওয়া খুবই সাধারণ — এটি git checkout -b -এর মাধ্যমে একটি অপারেশনে করা যেতে পারে।
একটি নতুন ব্রাঞ্চ তৈরি করা এবং একই সময়ে সেই নতুন শাখায় যেতে চাওয়া খুবই সাধারণ — এটি git checkout -b
নোট
গিট সংস্করণ 2.23 থেকে আপনি গিট চেকআউটের পরিবর্তে গিট সুইচ ব্যবহার করতে পারেন:
- একটি existing ব্রাঞ্চে স্যুইচ করুন: git switch testing-branch.
- একটি নতুন ব্রাঞ্চ তৈরি করুন এবং এতে স্যুইচ করুন: git switch -c new-branch। -c পতাকা তৈরির জন্য দাঁড়ায়, আপনি সম্পূর্ণ পতাকাও ব্যবহার করতে পারেন: –create।
- আপনার পূর্বের ব্রাঞ্চে চেক আউট করে ফিরে যান: git switch -.