Vivasoft-logo

১০.৩ গিট রেফারেন্সেস

গিট রেফারেন্সেস (Git References)

“যেহেতু আপনি 1a410e commit থেকে প্রাপ্ত রিপোজিটোরি history দেখতে আগ্রহী হয়েছেন, তাহলে আপনি git log 1a410e এই ধরনের কিছু করতে পারেন, কিন্তু আপনাকে 1a410e তে সেট করার জন্য স্টার্টিং পয়েন্ট হিসেবে ব্যবহৃত হওয়া কমিটের নাম মনে রাখতে হবে। কিন্তু, আপনার কাছে যদি এমন একটি ফাইল থাকে, তাহলে সেটাতে  আপনি একটি সাধারণ নামে সেই SHA-1 মানটি সংরক্ষণ করতে পারেন যাতে আপনি raw SHA-1 মানের পরিবর্তে সেই সাধারণ নামটি ব্যবহার করতে পারেন। Git এ এই সহজ নামগুলোকে বলা হয় “references” বা “refs”; আপনি সেই SHA-1 মানের ধারণকারী ফাইলগুলো পাবেন .git/refs ডিরেক্টরিতে। বর্তমান project এ, এই ডিরেক্টরিতে কোন ফাইল নেই, কিন্তু এখানে একটি সহজ স্ট্রাকচার আছে:
				
					$ find .git/refs
.git/refs
.git/refs/heads
.git/refs/tags
$ find .git/refs -type f
				
			

একটি reference তৈরি করতে নিচের এটি করতে পারেন, যা আপনার সর্বশেষ commit কোথায় আছে তা মনে রাখতে সাহায্য করবে:

				
					$ echo 1a410efbd13591db07496601ebc7a059dd55cfe9 > .git/refs/heads/master
				
			

এখন, আপনি আপনার গিট কমান্ডগুলিতে SHA-1 এর পরিবর্তে তৈরি করা head reference ব্যবহার করতে পারেন:

				
					$ git log --pretty=oneline master
1a410efbd13591db07496601ebc7a059dd55cfe9 Third commit
cac0cab538b970a37ea1e769cbbde608743bc96d Second commit
fdf4fc3344e67ab068f836878b6c4951e3b15f3d First commit
				
			

আপনাকে সরাসরি রেফারেন্স ফাইল সম্পাদনা করতে উত্সাহিত করা হয় না; তার পরিবর্তে, আপনি যদি একটি রেফারেন্স আপডেট করতে চান তবে git এটি করার জন্য একটি নিরাপদ কমান্ড git update-ref প্রদান করে:

				
					$ git update-ref refs/heads/master 1a410efbd13591db07496601ebc7a059dd55cfe9
				
			

মূলত গিটের একটি branch হল একটি সাধারণ পয়েন্টার বা আপনার কমিটের head রেফারেন্স। দ্বিতীয় commit এ একটি branch তৈরি করতে, আপনি এটি করতে পারেন:

				
					$ git update-ref refs/heads/test cac0ca
				
			

আপনার শাখায় সেই commit থেকেই কাজ থাকবে:

				
					$ git log --pretty=oneline test
cac0cab538b970a37ea1e769cbbde608743bc96d Second commit
fdf4fc3344e67ab068f836878b6c4951e3b15f3d First commit
				
			

এখন, আপনার গিট ডাটাবেস এরকম কিছু দেখায়:

data-model-4
চিত্র 150. শাখা প্রধান রেফারেন্স সহ গিট ডিরেক্টরি object অন্তর্ভুক্ত

আপনি যখন git branch <branch> এর মতো কমান্ড চালান, তখন আপনি যে নতুন রেফারেন্স তৈরি করতে চান তার শেষ কমিটের SHA-1 যোগ করতে Git মূলত সেই update-ref কমান্ডটি চালায়।

দ্যা হেড (The HEAD)

এখন প্রশ্ন হল, আপনি যখন git branch <branch> চালান, গিট কীভাবে শেষ কমিটের SHA-1 জানে ? উত্তর হল HEAD ফাইল।

সাধারণত HEAD ফাইলটি আপনি বর্তমানে যে শাখায় আছেন তার একটি প্রতীকী রেফারেন্স। সাংকেতিক রেফারেন্স দ্বারা, বোঝানো হচ্ছে যে,  একটি সাধারণ রেফারেন্সের বিপরীতে, এটি অন্য রেফারেন্সের জন্য একটি পয়েন্টার ধারণ করে।

তবে কিছু বিরল ক্ষেত্রে HEAD ফাইলটিতে একটি গিট অবজেক্টের SHA-1 মান থাকতে পারে। এটি ঘটে যখন আপনি একটি ট্যাগ, কমিট বা দূরবর্তী শাখা চেকআউট করেন, যা আপনার সংগ্রহস্থলকে “detached HEAD” অবস্থায় রাখে।

আপনি যদি ফাইলটি দেখেন তবে আপনি সাধারণত এরকম কিছু দেখতে পাবেন:

				
					$ cat .git/HEAD
ref: refs/heads/master
				
			

আপনি যদি git checkout test চালান, গিট ফাইলটিকে এইরকম দেখতে আপডেট করে:

				
					$ cat .git/HEAD
ref: refs/heads/test
				
			

আপনি যখন git commit চালান, তখন এটি কমিট অবজেক্ট তৈরি করে, সেই কমিট অবজেক্টের প্যারেন্টকে নির্দিষ্ট করে যা SHA-1 HEAD-এ রেফারেন্স নির্দেশ করে।

 

আপনি নিজেও এই ফাইলটি সম্পাদনা করতে পারেন, তবে এটি করার জন্য একটি নিরাপদ কমান্ড আছে: git symbolic-ref. আপনি এই কমান্ডের মাধ্যমে আপনার HEAD মান পড়তে পারেন:



				
					$ git symbolic-ref HEAD
refs/heads/master
				
			

আপনি একই কমান্ড ব্যবহার করে HEAD এর মান সেট করতে পারেন:

				
					$ git symbolic-ref HEAD refs/heads/test
$ cat .git/HEAD
ref: refs/heads/test
				
			

আপনি refs style বাইরে কোন প্রতীকী রেফারেন্স সেট করতে পারবেন না:

				
					$ git symbolic-ref HEAD test
fatal: Refusing to point HEAD outside of refs/
				
			

ট্যাগস (Tags)

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

 

Git Basics-এ যেমন আলোচনা করা হয়েছে, ট্যাগ দুই ধরনের: এনোট্যাটেড (annotated) এবং লাইটওয়েট (lightweight)। আপনি নিচের কমান্ডটি রান করে লাইটওয়েট (lightweight) ট্যাগ করতে পারেন:

				
					$ git update-ref refs/tags/v1.0 cac0cab538b970a37ea1e769cbbde608743bc96d
				
			

এটি হল একটি লাইটওয়েট (lightweight) ট্যাগ – কখনই সরে না এমন একটি রেফারেন্স। যদিও একটি এনোট্যাটেড (annotated) ট্যাগ আরও জটিল। আপনি যদি একটি এনোট্যাটেড (annotated) ট্যাগ তৈরি করেন, তাহলে গিট একটি ট্যাগ অবজেক্ট তৈরি করে এবং তারপরে সরাসরি কমিটের পরিবর্তে এটিকে পয়েন্ট করার জন্য একটি রেফারেন্স তৈরি করে। আপনি একটি এনোট্যাটেড (annotated) ট্যাগ তৈরি করে তা সহজেই দেখতে পারেন (-a অপশনটি ব্যবহার করে):

				
					$ git tag -a v1.1 1a410efbd13591db07496601ebc7a059dd55cfe9 -m 'Test tag'
				
			

তৈরিকৃত SHA-1 অবজেক্ট এর ভ্যালুটি হচ্ছে:

				
					$ cat .git/refs/tags/v1.1
9585191f37f7b0fb9444f35a9bf50de191beadc2
				
			

এখন, সেই SHA-1 ভ্যালুর উপর  git cat-file -p চালান:

				
					$ git cat-file -p 9585191f37f7b0fb9444f35a9bf50de191beadc2
object 1a410efbd13591db07496601ebc7a059dd55cfe9
type commit
tag v1.1
tagger Scott Chacon <schacon@gmail.com> Sat May 23 16:48:58 2009 -0700

Test tag

				
			

লক্ষ্য করুন যে অবজেক্ট এন্ট্রি (entry) আপনার ট্যাগ করা কমিট SHA-1 ভ্যালুকে পয়েন্ট করে। আরো লক্ষ করুন যে – শুধু একটি কমিট পয়েন্ট করার প্রয়োজন নেই; আপনি চাইলে  যেকোন গিট অবজেক্ট ট্যাগ করতে পারেন। উদাহরণস্বরূপ, গিট সোর্স কোডে মেইন্টেইনার (maintainer) তাদের GPG public key ব্লব অবজেক্ট হিসেবে যুক্ত করেছে এবং ট্যাগ করেছে। । আপনি গিট রিপোজিটরির ক্লোনটিতে নিচের কমান্ডটি চালিয়ে পাবলিক (public) key দেখতে পারেন:

				
					$ git cat-file blob junio-gpg-pub
				
			

লিনাক্স কার্নেল রিপোজিটরিতেও একটি নন-কমিট-পয়েন্টিং ট্যাগ অবজেক্ট রয়েছে — প্রথম ট্যাগটি সোর্স কোডের ইম্পোর্ট (import) করা প্রথম ট্রিতে পয়েন্ট করে।

 

রিমোটস (Remotes)

তৃতীয় ধরণের রেফারেন্স যা আপনি দেখতে পাবেন তা হল একটি রিমোট রেফারেন্স। আপনি যদি একটি রিমোট যোগ করেন এবং এটিতে পুশ করেন, তাহলে গিট প্রতিটি ব্রাঞ্চের জন্য আপনি শেষবার সেই রিমোটে পুশ করেছিলেন refs/remotes ডিরেক্টরিতে সেই মানটি সংরক্ষণ করে। উদাহরণস্বরূপ, আপনি origin নামে একটি রিমোট যোগ করতে পারেন এবং এটিতে আপনার master ব্রাঞ্চকে পুশ করতে পারেন:

				
					$ git remote add origin git@github.com:schacon/simplegit-progit.git
$ git push origin master
Counting objects: 11, done.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (7/7), 716 bytes, done.
Total 7 (delta 2), reused 4 (delta 1)
To git@github.com:schacon/simplegit-progit.git
  a11bef0..ca82a6d  master -> master
				
			

শেষবার সার্ভারের সাথে কমিউনিকেট করার সময়  master ব্রাঞ্চ origin রিমোটে কেমন ছিল তা দেখার জন্য আপনি refs/remotes/origin/master ফাইলটি চেক করে দেখতে পারেন।

				
					$ cat .git/refs/remotes/origin/master
ca82a6dff817ec66f44342007202690a93763949
				
			

রিমোট রেফারেন্সগুলি (refs/heads রেফারেন্স) ব্রাঞ্চগুলো থেকে আলাদা হয় কারণ সেগুলো শুধুমাত্র রিড-অনলি হিসাবে বিবেচনা করা হয়। আপনি রিমোট রেফারেন্সে  git checkout করে দেখতে পারেন, তবে গিট প্রতীকীভাবে HEAD এর সাথে রেফারেন্স করবে না, তাই আপনি এটিকে কখনই একটি commit কমান্ড দিয়ে আপডেট করতে পারবেন না। Git সেগুলিকে বুকমার্ক হিসাবে ম্যানেজ করে তার সর্বশেষ স্টেটে, যেখানে সেই সার্ভারগুলিতে সেই ব্রাঞ্চগুলো ছিল।