৩.২: গিট ব্রাঞ্চিং – মৌলিক ব্রাঞ্চিং এবং মার্জিং

মৌলিক ব্রাঞ্চিং এবং মার্জিং

চলুন, আপনি বাস্তব জগতে ব্যবহার করতে পারেন এমন একটি কর্মপ্রবাহের সাথে ব্রাঞ্চিং এবং মার্জিং তথা একত্রিত করার একটি সাধারণ উদাহরণ দেখা যাক।  আপনি এই পদক্ষেপগুলি অনুসরণ করবেনঃ

  1. একটি ওয়েবসাইটে কিছু কাজ করুন। 
  2. একটি নতুন user story এর জন্য আপনি যেখানে কাজ করছিলেন, সেখানে একটি ব্রাঞ্চ তৈরি করুন।
  3. সেই ব্রাঞ্চে কিছু কাজ করুন।

 

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

  1. আপনার প্রোডাকশান ব্রাঞ্চে পরিবর্তন করুন।
  2. হটফিক্সটি সংযুক্ত করার জন্যে নতুন একটি ব্রাঞ্চ তৈরী করুন।
  3. এটি পরিক্ষিত হওয়ার পর, হটফিক্স ব্রাঞ্চটিকে একত্রিত করুন এবং প্রোডাকশানে পুশ করুন।
  4. পুনরায় আপনার অরিজিনাল user story তে ফিরে আসুন এবং কাজ চালিয়ে যান।

মৌলিক ব্রাঞ্চিং

প্রথমত, ধরুন আপনি আপনার প্রজেক্টে কাজ করছেন এবং master ব্রাঞ্চে ইতিমধ্যেই কয়েকটি কমিট রয়েছে।
basic branching 1 Basic Branching and Merging
চিত্র ১৮ঃ একটি সাধারণ commit history
আপনি সিদ্ধান্ত নিলেন আপনার কোম্পানী যে ইস্যু-ট্র্যাকিং সিস্টেম ব্যবহার করে তাতে আপনি #53 ইস্যুতে কাজ করতে যাচ্ছেন। একইসমইয়ে একটি নতুন ব্রাঞ্চ তৈরী করা এবং তাতে পরিবর্তন করার জন্যে, আপনি git checkout কমান্ডটি -b সুইচের সাথে ব্যবহার করতে পারেনঃ
				
					$ git checkout -b iss53
Switched to a new branch "iss53" 
				
			
এর সংক্ষিপ্ত বিবরণঃ
				
					$ git branch iss53
$ git checkout iss53
				
			
basic branching 2 Basic Branching and Merging
চিত্র ১৯ঃ একটি নতুন ব্রাঞ্চ পয়েন্টার তৈরি করা
আপনি আপনার ওয়েবসাইটে কিছু কাজ করলেন এবং কিছু কমিট দিলেন। এটি করার ফলে iss53 ব্রাঞ্চটি এগিয়ে যায়, কারণ আপনি এটি চেক আউট করেছেন (অর্থাৎ, আপনার HEAD এটির দিকে নির্দেশ করছে)ঃ
				
					$ vim index.html
$ git commit -a -m 'Create new footer [issue 53]'
				
			
basic branching 3 Basic Branching and Merging
চিত্র ২০ঃ iss53 ব্রাঞ্চটি আপনার কাজ নিয়ে সামনে দিকে এগিয়ে গেছে
এখন আপনি কল পাবেন যে ওয়েবসাইটে একটি সমস্যা আছে এবং আপনাকে অবিলম্বে এটি ঠিক করতে হবে। গিট-এর সাহায্যে, আপনি যে iss53 পরিবর্তনগুলি করেছেন তার সাথে আপনাকে আপনার ফিক্স স্থাপন করতে হবে না, এবং প্রোডাকশনে যা আছে তাতে আপনার ফিক্স প্রয়োগ করার জন্য কাজ করার আগে, আপনাকে সেই পরিবর্তনগুলিকে ফিরিয়ে আনার জন্য খুব বেশি পরিশ্রম করতে হবে না। আপনাকে যা করতে হবে, তা হল master ব্রাঞ্চে পুনরায় পরিবর্তন করে ফিরে যেতে হবে।

যাই হোক, এটি করার আগে, মনে রাখবেন যে, যদি আপনার কাজের ডিরেক্টরি বা স্টেজিং এরিয়াতে কমিট না করা পরিবর্তনগুলি থাকে, যা আপনি যে ব্রাঞ্চটিতে চেকআউট করছেন তার সাথে বিরোধপূর্ণ হয়, তাহলে গিট আপনাকে ওই ব্রাঞ্চে সুইচ করতে দেবে না। এটির থেকে পরিত্রাণের উপায় রয়েছে (যেমন, স্ট্যাশিং এবং কমিট সংশোধন করা) যা আমরা (স্ট্যাশিং এবং ক্লিনিংয়ে) পরে কভার করব। আপাতত, ধরে নিন আপনি আপনার সবগুলো পরিবর্তন কমিট করেছেন, যাতে আপনি পুনরায় আপনার master শাখায় সুইচ করতে পারেনঃ
				
					$ git checkout master
Switched to branch 'master'
				
			
এই মুহুর্তে, আপনার প্রজেক্ট ওয়ার্কিং ডিরেক্টরি আপনি #53 ইস্যুতে কাজ শুরু করার আগে ঠিক যেভাবে ছিল সেভাবেই আছে, এবং আপনি এখন আপনার হটফিক্সে মনোনিবেশ করতে পারেন। এখানে একটি গুরুত্বপূর্ণ বিষয় মনে রাখতে হবেঃ আপনি যখন ব্রাঞ্চগুলিতে সুইচ বা পরিবর্তন করেন, তখন গিট আপনার ওয়ার্কিং ডিরেক্টরিকে পুনরায় এমনভাবে সেট করে যেন আপনি শেষবার ওই ব্রাঞ্চে কমিট করার সময় তা যেরকম ছিল, সেরকমটাই দেখায়। এটি আপনার ওয়ার্কিং কপিটিকে আপনার সর্বশেষ কমিটের ক্ষেত্রে ব্রাঞ্চটি কেমন ছিল তা নিশ্চিত করার জন্য ফাইলগুলিকে স্বয়ংক্রিয়ভাবে যুক্ত করে, অপসারণ করে এবং সংশোধন করে।

এবার, আপনাকে একটি হটফিক্স তৈরী করতে হবে। আসুন একটি hotfix ব্রাঞ্চ তৈরি করি যাতে এটি সম্পূর্ণ না হওয়া পর্যন্ত কাজ করতে হবেঃ
				
					$ git checkout -b hotfix
Switched to a new branch 'hotfix'
$ vim index.html
$ git commit -a -m 'Fix broken email address'
[hotfix 1fb7853] Fix broken email address
 1 file changed, 2 insertions(+)
				
			
basic branching 4 Basic Branching and Merging
চিত্র ২১ঃ master এর উপর ভিত্তি করা hotfix ব্রাঞ্চ
আপনি আপনার টেস্টগুলি রান করতে পারেন, হটফিক্সটিতে আপনি যা চান তা নিশ্চিত করুন এবং অবশেষে হটফিক্স ব্রাঞ্চটিকে আপনার master ব্রাঞ্চে পুনরায় মার্জ বা একত্রিত করুন যাতে এটি production এ স্থাপন করা যায়ঃ
				
					$ git checkout master
$ git merge hotfix
Updating f42c576..3a0874c
Fast-forward
 index.html | 2 ++
 1 file changed, 2 insertions(+)
				
			
আপনি সেই মার্জের ক্ষেত্রে “fast-forward” বাক্যাংশটি লক্ষ্য করবেন। কারণ আপনি যে ব্রাঞ্চ হটফিক্সে মার্জ করেছেন তার দ্বারা নির্দেশিত কমিট C4-টি আপনি যে কমিট C2-তে আছেন তাথেকে সরাসরি এগিয়ে ছিল, গিট কেবল পয়েন্টারটিকে এগিয়ে নিয়ে যায়। অন্যভাবে বলতে গেলে, আপনি যখন একটি কমিটকে আরেকটি কমিটের সাথে মার্জ বা একত্রিত করার চেষ্টা করেন, যেখানে পরের কমিটটিতে প্রথম কমিটের history অনুসরণ করে পৌঁছানো যেতে পারে, তখন গিট পয়েন্টারটিকে এগিয়ে নিয়ে যাওয়ার মাধ্যমে জিনিসগুলিকে সহজ করে কারণ সেখানে একসাথে মার্জ বা একত্রিত করার জন্য কোন divergent বা ভিন্ন কোন কাজ নেই — এটিকেই “fast-forward” বলা হয়।

আপনার পরিবর্তন এখন master ব্রাঞ্চ দ্বারা নির্দেশিত কমিটের স্ন্যাপশটে রয়েছে, এবং আপনি ফিক্সটই deploy করতে পারেন।
basic branching 5 Basic Branching and Merging
চিত্র ২২ঃ master, hotfix ব্রাঞ্চের দিকে fast-forwarded হয়েছে


আপনার অতি-গুরুত্বপূর্ণ ফিক্স ডিপ্লয় হওয়ার পরে, বাধাপ্রাপ্ত হওয়ার আগে আপনি যে কাজটি করছিলেন তাতে ফিরে যেতে প্রস্তুত। যাইহোক, প্রথমে আপনি হটফিক্স ব্রাঞ্চটি মুছে ফেলবেন, কারণ আপনার আর এটির প্রয়োজন নেই — একই জায়গায় master ব্রাঞ্চটি নির্দেশ করে। আপনি এটি  git branch কমান্ডে -d অপশান ব্যবহার করে মুছে ফেলতে পারেনঃ

				
					$ git branch -d hotfix
Deleted branch hotfix (3a0874c).
				
			
এখন আপনি পুনরায় আপনার work-in-progress ব্রাঞ্চটির issue #53 তে সুইচ করতে পারেন এবং কাজ চালিয়ে যেতে পারেন।
				
					$ git checkout iss53
Switched to branch "iss53"
$ vim index.html
$ git commit -a -m 'Finish the new footer [issue 53]'
[iss53 ad82d7a] Finish the new footer [issue 53]
1 file changed, 1 insertion(+)
				
			
basic branching 6 Basic Branching and Merging
চিত্র ২৩ঃ iss53 তে কাজ চলমান
এখানে লক্ষণীয় যে আপনি আপনার hotfix ব্রাঞ্চটিতে কাজটি করেছেন তা আপনার iss53 ব্রাঞ্চের ফাইলগুলিতে নেই। আপনি যদি এটিকে pull করতে চান, আপনি git merge master চালিয়ে আপনার master ব্রাঞ্চটিকে আপনার iss53 ব্রাঞ্চে মার্জ করতে পারেন, অথবা আপনি এই পরিবর্তনগুলিকে একীভূত করার জন্য অপেক্ষা করতে পারেন যতক্ষণ না আপনি iss53 ব্রাঞ্চটিকে পরে master এ pull নেওয়ার সিদ্ধান্ত নেন।

মৌলিক মার্জিং

ধরুন আপনি সিদ্ধান্ত নিয়েছেন যে আপনার issue #53 কাজ সম্পূর্ণ হয়েছে এবং আপনার master ব্রাঞ্চে মার্জিং হওয়ার জন্য প্রস্তুত। এটি করার জন্য, আপনি আপনার iss53 ব্রাঞ্চটিকে master এ মার্জ করবেন, যেমন আপনি আগে আপনার hotfix ব্রাঞ্চ মার্জ করেছেন। আপনাকে যা করতে হবে তা হল আপনি যে ব্রাঞ্চে মার্জ করতে চান তাতে চেকাউট করুন এবং তারপর git merg কমান্ডটি চালানঃ
				
					$ git checkout master
Switched to branch 'master'
$ git merge iss53
Merge made by the 'recursive' strategy.
index.html |    1 +
1 file changed, 1 insertion(+)
				
			
এটি আপনার আগে করা hotfix মার্জ থেকে কিছুটা আলাদা। এক্ষেত্রে, আপনার development history কিছু পুরানো পয়েন্ট থেকে ভিন্ন। কারণ আপনি যে ব্রাঞ্চে আছেন তার কমিটটি আপনি যে ব্রাঞ্চে মার্জ করছেন তার সরাসরি পূর্বপুরুষ নয়, গিটের কিছু কাজ করতে হবে। এক্ষেত্রে, গিট তার ব্রাঞ্চের টিপস দ্বারা নির্দেশিত দুটি স্ন্যাপশটকে ব্যবহার করে এবং দুটির সাধারণ পূর্বপুরুষ ব্যবহার করে একটি সাধারণ ত্রিমুখী মার্জ করে।
basic merging 1 Basic Branching and Merging
চিত্র ২৪ঃ একটি সাধারণ মার্জে ব্যবহৃত তিনটি স্ন্যাপশট
শুধু ব্রাঞ্চ পয়েন্টারকে এগিয়ে নিয়ে যাওয়ার পরিবর্তে, গিট একটি নতুন স্ন্যাপশট তৈরি করে যা মূলত এই ত্রিমুখী মার্জ হওয়ার ফল এবং স্বয়ংক্রিয়ভাবে একটি নতুন কমিট তৈরি করে যা এটিকে নির্দেশ করে। এটিকে merge commit হিসাবে উল্লেখ করা হয় এবং এটি বিশেষ কারণ এটির একাধিক parent রয়েছে৷
basic merging 2 Basic Branching and Merging
চিত্র ২৫ঃ একটি মার্জ কমিট
এখন যেহেতু আপনার কাজ মার্জ হয়েছে, আপনার আর iss53 ব্রাঞ্চের প্রয়োজন নেই। আপনি আপনার issue-tracking system এ এই ইস্যুটি বন্ধ করে দিতে পারেন এবং এই ব্রাঞ্চটি মুছে দিতে পারেনঃ
				
					$ git branch -d iss53
				
			

মৌলিক মার্জ কনফ্লিক্ট

মাঝে মাঝে, এই প্রক্রিয়াটি সহজভাবে হয় না। আপনি যে দুটি ব্রাঞ্চে মার্জ করছেন, যদি আপনি সেখানকার একই ফাইলের একই অংশ ভিন্নভাবে পরিবর্তন করেন, গিট তাদের পরিষ্কারভাবে মার্জ করতে সক্ষম হবে না। যদি issue #53 তে আপনার সমস্যার সমাধান hotfix ব্রাঞ্চের মতো একটি ফাইলের একই অংশ পরিবর্তন করে, তাহলে আপনি একটি মার্জ কনফ্লিক্ট বা বিরোধ পাবেন যা দেখতে এরকম হবেঃ
				
					$ git merge iss53
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.
				
			
গিট স্বয়ংক্রিয়ভাবে একটি নতুন মার্জ কমিট তৈরি করেনি। আপনি কনফ্লিক্টের সমাধান করার সময় এটি মার্জের প্রক্রিয়াটিকে বিরতি দিয়েছে। যদি আপনি দেখতে চান যে কোন ফাইলগুলি মার্জ কনফ্লিক্টের কারণে আনমার্জ হয়েছে, আপনি git status কমান্ডটি চালাতে পারেনঃ
				
					$ git status
On branch master
You have unmerged paths.
  (fix conflicts and run "git commit")

Unmerged paths:
  (use "git add <file>..." to mark resolution)

    both modified:      index.html

no changes added to commit (use "git add" and/or "git commit -a")
				
			
যে কোনো কিছু যাতে মার্জ কনফ্লিক্ট রয়েছে এবং এর সমাধান করা হয়নি তা আনমার্জড হিসেবে তালিকাভুক্ত করা হয়েছে। গিট যে ফাইলগুলিতে কনফ্লিক্ট রয়েছে, সেগুলোতে স্ট্যান্ডার্ড conflict-resolution চিহ্নিতকারী সংযুক্ত করে, যাতে আপনি সেগুলি ম্যানুয়ালি খুলতে পারেন এবং সেগুলো সমাধান করতে পারেন। আপনার ফাইলে একটি বিভাগ রয়েছে যা দেখতে এরকমঃ
				
					<<<<<<< HEAD:index.html
<div id="footer">contact : email.support@github.com</div>
=======
<div id="footer">
 please contact us at support@github.com
</div>
>>>>>>> iss53:index.html
				
			
এর মানে হল HEAD-এর ভার্সন (আপনার master ব্রাঞ্চ, কারণ আপনি যখন আপনার মার্জ কমান্ডটি চালান তখন আপনি এটিতে চেক আউট করেছিলেন) হল সেই ব্লকের উপরের অংশ (======= এর উপরে সবকিছু), যখন আপনার iss53 ব্রাঞ্চের ভার্সনটি নীচের অংশটির মতো দেখায়। কনফ্লিক্ট সমাধান করার জন্য, আপনাকে হয় এক পক্ষ বা অন্য দিক বেছে নিতে হবে অথবা বিষয়বস্তুগুলিকে একত্রিত করতে হবে। উদাহরণস্বরূপ, আপনি এটির সাথে পুরো ব্লকটি প্রতিস্থাপন করে এই বিরোধের সমাধান করতে পারেনঃ
				
					<div id="footer">
please contact us at email.support@github.com
</div>
				
			
এই সমাধানে প্রতিটি বিভাগের সামান্য কিছু আছে, এবং <<<<<<<, =======, এবং >>>>>>> লাইনগুলি সম্পূর্ণ মুছে ফেলা হয়েছে। আপনি প্রতিটি কনফ্লিকেটেড ফাইলের এই বিভাগগুলির প্রতিটি সমাধান করার পরে, এটিকে সমাধান করা হিসাবে চিহ্নিত করতে প্রতিটি ফাইলে git add চালান। ফাইলটি স্টেজ করার ফলে এটিকে গিট সমাধান হওয়া ফাইল হিসাবে চিহ্নিত করে।

আপনি যদি এই সমস্যাগুলি সমাধান করার জন্য একটি গ্রাফিকাল টুল ব্যবহার করতে চান তবে আপনি  git mergetool কমান্ডটি চালাতে পারেন, যা একটি উপযুক্ত ভিজ্যুয়াল মার্জ টুল চালু করে এবং আপনাকে কনফ্লিক্টগুলোর মধ্য দিয়ে নিয়ে যায়ঃ

				
					$ git mergetool

This message is displayed because 'merge.tool' is not configured.
See 'git mergetool --tool-help' or 'git help config' for more details.
'git mergetool' will now attempt to use one of the following tools:
opendiff kdiff3 tkdiff xxdiff meld tortoisemerge gvimdiff diffuse diffmerge
ecmerge p4merge araxis bc3 codecompare vimdiff emerge
Merging:
index.html

Normal merge conflict for 'index.html':
  {local}: modified file
  {remote}: modified file
Hit return to start merge resolution tool (opendiff):
				
			
আপনি যদি ডিফল্ট ব্যতীত অন্য একটি মার্জ টুল ব্যবহার করতে চান (গিট এই ক্ষেত্রে opendiff বেছে নিয়েছে কারণ কমান্ডটি ম্যাকে চালানো হয়েছিল), আপনি “নিম্নলিখিত টুলগুলির মধ্যে একটির পরে শীর্ষে তালিকাভুক্ত” সমস্ত সমর্থিত টুলগুলি দেখতে পারেন। আপনি যে টুলটি ব্যবহার করতে চান তার নাম টাইপ করুন।
নোট
যদি আপনি আরও এডভান্সড মার্জিং টুল চান যার মাধ্যমে কৌশলী মার্জ কনফ্লিক্ট বা বিরোধগুলো সমাধান করা যাবে, তাহলে সেটা আমরা (এডভান্সড মার্জিং) এ কাভার করব
আপনি মার্জ টুল থেকে প্রস্থান করার পরে, গিট আপনাকে জিজ্ঞাসা করে যে মার্জ সফল হয়েছে কিনা। আপনি যদি স্ক্রিপ্টটিকে বলেন যে এটি ছিল, এটি ফাইলটিকে আপনার জন্য সমাধান করা হিসাবে চিহ্নিত করার জন্য ধাপে ধাপে দেয়। সমস্ত দ্বন্দ্ব সমাধান করা হয়েছে তা যাচাই করতে আপনি আবার গিট স্ট্যাটাস চালাতে পারেনঃ
				
					$ git status
On branch master
All conflicts fixed but you are still merging.
  (use "git commit" to conclude merge)

Changes to be committed:

    modified:   index.html
				
			
আপনি যদি এতে সন্তুষ্ট হন এবং আপনি যাচাই করেন যে সমস্ত কিছুর মধ্যে কনফ্লিক্ট ছিল সেগুলো স্টেজ করা হয়েছে, আপনি মার্জ কমিট চূড়ান্ত করতে git commit টাইপ করতে পারেন। ডিফল্টরূপে কমিট মেসেজ বা বার্তাটি এরকম কিছু দেখায়:
				
					Merge branch 'iss53'

Conflicts:
    index.html
#
# It looks like you may be committing a merge.
# If this is not correct, please remove the file
#	.git/MERGE_HEAD
# and try again.


# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# All conflicts fixed but you are still merging.
#
# Changes to be committed:
#	modified:   index.html
#
				
			
আপনি যদি মনে করেন যে এটি ভবিষ্যতে এই মার্জ দেখলে অন্যদের জন্য তা সহায়ক হবে, তাহলে আপনি কীভাবে মার্জটি সমাধান করেছেন সে সম্পর্কে বিশদ বিবরণ সহ এই কমিটটি মেসেজটি পরিবর্তন করতে পারেন এবং যদি তা স্পষ্ট না হয়, তাহলে আপনি যে পরিবর্তনগুলি করেছেনসেগুলো ব্যাখ্যা করতে পারেন।