১০.৫ রেফারেন্স স্পেচিফিকেশন (Refspec)
এই বই এ, আমরা কিছু local branch কে কিছু remote branch এর সাথে লিঙ্ক করার সরল ব্যবহার দেখেছি, কিন্তু এই লিঙ্ক গুলা অনেক জটিল হতে পারে। মনে করেন আপনি আগের কয়েকটা অধ্যায় অনুসরণ করে একটি ছোট local গিট repository বানিয়েছেন, এবং এখন এতে remote সার্ভার এর উৎস যুক্ত করবেনঃ
$ git remote add origin https://github.com/schacon/simplegit-progit
উপরের command টি রান করলে এটি .git/config ফাইল এ একটি অংশ যুক্ত করে, যা remote (origin) এর উৎস কে চিনিয়ে দেয় যাতে থাকে। remote repository এর URL এবং refspec এ এটি ব্যবহৃত হবে remote থেকে fetch (repository এর সব content আনা) করার জন্যঃ
[remote "origin"]
url = https://github.com/schacon/simplegit-progit
fetch = +refs/heads/*:refs/remotes/origin/*
refspec এর ফরম্যাট হচ্ছে, প্রথমে একটি ঐচ্ছিক +, এর পরে <src>:<dst>, যেখানে <src> হল remote এর references এর লিঙ্ক প্যাটার্ন এবং <dst> হল যেখানে ওই reference গুল locally ট্র্যাক করা হয় ।
(+) git কে বলে reference গুলো কে আপডেট করতে যদি fast-forward ব্যবহার না হয়।
সাধারণত, git remote add origin কম্যান্ড টি নিজে এ refspec গুল যুক্ত করে, git refs/heads/ এর যত reference আছে সব সার্ভার (এইখানে সার্ভার বলতে remote repository এর host কে বুঝাচ্ছে) থেকে fetch করে locally refs/remotes/origin/ এ নিয়ে আসে। এখন যদি সার্ভার এ একটি master branch থাকে, আপনি সে branch এর log locally দেখতে পারবেন নিচের যে কোন ভাবেঃ
$ git log origin/master
$ git log remotes/origin/master
$ git log refs/remotes/origin/master
উপরের সব কমান্ড গুলো সমার্থক, কারণ git সব গুলোকে সম্প্রসার করে refs/remotes/origin/master করে নেয়।
যদি আপনি চান git প্রত্যেক বার remote সার্ভার থেকে শুধু master কেই pull করবে এবং সে সময়ে বাকি সব branch pull করবে না, সেক্ষেত্রে আপনি fetch এর মান কে পরিবর্তন করে শুধু মাত্র remote এর master কে চিনিয়ে দিতে পারেনঃ
fetch = +refs/heads/master:refs/remotes/origin/master
এইটা এই repository এর জন্য ডিফল্ট refspec যেটা git fetch ব্যবহার করবে। যদি আপনি শুধু একবার এইটা override করে অন্য branch এর কন্টেন্ট master এ নিয়ে আসতে চান, আপনাকে সে নির্দিষ্ট refspec টা cli তে লিখে দেয়া লাগবে। যেমন – remote server এর master কে যদি আপনি আপনার locally origin/mymaster branch এ pull করেতে চান, আপনি এই command টি run করতে পারেনঃ
$ git fetch origin master:refs/remotes/origin/mymaster
আপনি একাধিক refspec ও নির্দিষ্ট করে দিতে পারেন। command line এ আপনি একাধিক branch pull করতে পারেন এভাবেঃ
$ git fetch origin master:refs/remotes/origin/mymaster \
topic:refs/remotes/origin/topic
From git@github.com:schacon/simplegit
! [rejected] master -> origin/mymaster (non fast forward)
* [new branch] topic -> origin/topic
এই ক্ষেত্রে, master এর pull টা rejected হয়েছে, কারণ এইটা fast-forward reference হিসাবে pull করতে বলা হয় নাই। আপনি এইটা override করতে পারেন refspec এর আগে + চিহ্ন বসিয়ে।
আপনি fetch করার জন্য আপনার repository configuration ফাইলে একাধিক refspec ও বলে দিতে পারেন। যদি আপনি master ও experiment branch গুলো origin remote থেকে fetch করতে চান, নিচের দুটি line যুক্ত করেনঃ
[remote "origin"]
url = https://github.com/schacon/simplegit-progit
fetch = +refs/heads/master:refs/remotes/origin/master
fetch = +refs/heads/experiment:refs/remotes/origin/experiment
Git 2.6.0 থেকে একাধিক branch নামের pattern match করার জন্য আপনি partial glob ব্যবহার করতে পারবেন fetch এর value হিসেবে। তাই নিচেরটি কাজ করেঃ
fetch = +refs/heads/qa*:refs/remotes/origin/qa*
আরো চমৎকার ব্যাপার হল, আপনি namespace(বা directory) ব্যবহার করে একই ফল পেতে পারেন এবং এইক্ষেত্রে command টা আরও বোধগম্য হয়। যেমন, যদি আপনার QA টিম কয়েকটা branch এ কাজ করে push করে, আর আপনি চান master branch এবং QA টিম এর branch গুলা পেতে চান এবং আর কিছু না, সেক্ষেত্রে আপনার config কে এইভাবে লিখতে পারেনঃ
[remote "origin"]
url = https://github.com/schacon/simplegit-progit
fetch = +refs/heads/master:refs/remotes/origin/master
fetch = +refs/heads/qa/*:refs/remotes/origin/qa/*
যদি আপনার টিমের workflow জটিল হয় যেটায় একটা QA টিম কিছু branch push করে, ডেভেলপাররা কিছু branch push করে, integration টিম কিছু remote branch এ কাজ করে ও push করে, আপনি সেক্ষেত্রে আপনি সহজে branch গুলা কে এইভাবে namespace দিয়ে আলাদা করতে পারবেন।
Refspecs push করা
উপরে বর্ণিত উপায়ে আপনি namespace ব্যবহার করে reference fetch করতে পারতেসেন, কিন্তু QA তাদের branch গুলা /qa namespace এ প্রথমে কিভাবে দিবে? এইটা করা যাবে push এর জন্য refspec ব্যবহার করে।
যদি QA তাদের master branch কে remote সার্ভার এর qa/master এ push করতে চায়, তারা নিচের কমান্ড চালাতে পারেঃ
$ git push origin master:refs/heads/qa/master
তারা যদি প্রতিবার git push origin রান করলে চায় git নিজ থেকে এই কাজটি করুক, তারা তাদের config ফাইল এ push এর জন্য নিচের মান ব্যবহার করতে পারেঃ
[remote "origin"]
url = https://github.com/schacon/simplegit-progit
fetch = +refs/heads/*:refs/remotes/origin/*
push = refs/heads/master:refs/heads/qa/master
এখন যেটা হবে, git push origin রান করলে, local master branch টি remote এর qa/master branch এ push হবে।
note: আপনি refspec ব্যবহার করে এক repository থেকে অন্য repository তে push করতে পারবেন না। এটি করতে চাইলে উদাহরণ হিসেবে দেখতে পারেন 6.2 Keep your GitHub public repository up-to-date
Reference delete করা
আপনি refspec ব্যবহার করে remote থেকে reference delete করতে পারবেন নিচের command টি রান করেঃ
$ git push origin :topic
যেহেতু refspec হচ্ছে :, উপরের command এ অংশটি খালি রাখাতে এইটা বুঝায় topic branch এর remote এ কিছু যুক্ত নেই, যেইটা remote থেকে এই branch এর reference মুছে ফেলে।
অথবা আপনি নতুন command ব্যবহার করতে পারেন (Git v1.7.0 থেকে অন্তর্ভুক্ত)
$ git push origin --delete topic