Vivasoft-logo

৭.৭ গিট টুলস – রিসেট এর রহস্য উন্মোচন 

রিসেট এর রহস্য উন্মোচন

আরও বিশেষ সরঞ্জামগুলিতে যাওয়ার আগে, আসুন গিট reset এবং checkout কমান্ড সম্পর্কে কথা বলি। আপনি যখন প্রথম তাদের মুখোমুখি হন তখন এই কমান্ডগুলি গিটের সবচেয়ে বিভ্রান্তিকর দুটি অংশ। তারা এমন অনেক কাজ করে যে আসলে তাদের বুঝতে এবং তাদের সঠিকভাবে নিয়োগ করা আশাহীন বলে মনে হয়। এই জন্য, আমরা একটি সহজ রূপক উপস্থাপন করবো।

তিনটি ট্রি

reset এবং checkout সম্পর্কে চিন্তা করার একটি সহজ উপায় হল গিট এর মেন্টাল ফ্রেম এর মধ্য দিয়ে তিনটি ভিন্ন ট্রির কন্টেন্ট ম্যানেজার। এখানে “ট্রি” দ্বারা, বিশেষত ডেটা স্ট্রাকচার নয় বরং আমরা সত্যিই “ফাইলের সংগ্রহ” বুঝিয়েছি। এমন কিছু ক্ষেত্র  রয়েছে, যেখানে সূচীটি ঠিক একটি ট্রি-র মতো কাজ করে না, কিন্তু আমাদের উদ্দেশ্যেগুলোর জন্য, আপাতত এভাবে চিন্তা করাই সহজ।।

একটি সিস্টেম হিসাবে গিট তার স্বাভাবিক ক্রিয়াকলাপে তিনটি ট্রি পরিচালনা করে:

tree- role

হেড 

HEAD হল বর্তমান ব্রাঞ্চের রেফারেন্সের পয়েন্টার, যা সেই ব্রাঞ্চে করা শেষ কমিটের একটি পয়েন্টার। এর মানে HEAD হবে তৈরি করা পরবর্তী কমিটের প্যারেন্ট। সেই ব্রাঞ্চে আপনার শেষ কমিটের স্ন্যাপশট হিসাবে HEAD কে ভাবা সাধারণত সহজ।

আসলে, সেই স্ন্যাপশটটি দেখতে কেমন তা দেখা বেশ সহজ। এখানে HEAD স্ন্যাপশটে প্রতিটি ফাইলের জন্য প্রকৃত ডিরেক্টরি তালিকা এবং SHA-1 চেকসাম পাওয়ার একটি উদাহরণ রয়েছে:

				
					$ git cat-file -p HEAD
tree cfda3bf379e4f8dba8717dee55aab78aef7f4daf
author Scott Chacon  1301511835 -0700
committer Scott Chacon  1301511835 -0700

initial commit

$ git ls-tree -r HEAD
100644 blob a906cb2a4a904a152...   README
100644 blob 8f94139338f9404f2...   Rakefile
040000 tree 99f1a6d12cb4b6f19...   lib
				
			

গিট cat-file এবং ls-tree কমান্ডগুলি হল “প্লাম্বিং” কমান্ড যা নিম্ন স্তরের জিনিসগুলির জন্য ব্যবহৃত হয় এবং প্রকৃতপক্ষে প্রতিদিনের কাজে ব্যবহৃত হয় না, তবে তারা আমাদের এখানে কী ঘটছে তা দেখতে সাহায্য করে।

ইনডেক্স

index টি আপনার প্রস্তাবিত পরবর্তী কমিট। আমরা এই ধারণাটিকে গিটের “স্টেজিং এরিয়া” হিসাবে উল্লেখ করেছি কারণ আপনি যখন git commit কমান্ডটি চালান তখন গিট এটিই দেখে।

যে ফাইলগুলি আপনার ওয়ার্কিং ডিরেক্টরিতে শেষবার চেক আউট করা হয়েছিল এবং যখন সেগুলি প্রথমে চেক আউট করা হয়েছিল তখন সেগুলি কেমন ছিল, গিট সে সমস্ত ফাইলের সেই বিষয়বস্তুগুলোর একটি তালিকা দিয়ে এই সূচীটি তৈরী করে। তারপরে আপনি সেই ফাইলগুলিকে কিছু নতুন সংস্করণ দিয়ে প্রতিস্থাপন করুন এবং git commit কমান্ডটি সেটিকে ট্রি-এর একটি নতুন কমিটে রূপান্তরিত করে।

				
					$ git ls-files -s
100644 a906cb2a4a904a152e80877d4088654daad0c859 0	README
100644 8f94139338f9404f26296befa88755fc2598c289 0	Rakefile
100644 47c6340d6459e05787f644c2447d2595f5d3a54b 0	lib/simplegit.rb
				
			

আবার, এখানে আমরা git ls-files কমান্ডটি ব্যবহার করছি, যা পর্দার আড়ালে একটি কমান্ড, যা আপনার index টি বর্তমানে কেমন দেখাচ্ছে, তা দেখায়।

ইনডেক্সটি প্রযুক্তিগতভাবে একটি ট্রি-র কাঠামো নয় —-এটি আসলে একটি ফ্ল্যাটেন্ড ম্যানিফেস্ট হিসেবে প্রয়োগ করা হয়েছে —কিন্তু আমাদের উদ্দেশ্যের জন্যে, এটি যথেষ্ট কাছাকাছি।

ওয়ার্কিং ডিরেক্টরী 

অবশেষে, আপনার কাছে আপনার ওয়ার্কিং ডিরেক্টরি রয়েছে (সাধারণত “ওয়ার্কিং ট্রি” হিসাবেও উল্লেখ করা হয়)। অন্য দুটি ট্রি তাদের বিষয়বস্তু .git ফোল্ডারের ভিতরে একটি দক্ষ কিন্তু সুবিধাজনক নয় এমন একটি পদ্ধতিতে সংরক্ষণ করে। ওয়ার্কিং ডিরেক্টরি তাদের প্রকৃত ফাইলগুলিতে আনপ্যাক করে, ফলে সেগুলি সম্পাদনা করা আপনার জন্য আরও সহজ হয়। ওয়ার্কিং ডিরেক্টরিটিকে একটি sandbox হিসাবে ভাবুন, যেখানে আপনি প্রথমে স্টেজিং এরিয়া (index) এবং তারপরে ইতিহাসে (history) কমিট করার আগে আপনার পরিবর্তনগুলো ঘটানোর চেষ্টা করেন । 

				
					$ tree
.
├── README
├── Rakefile
└── lib
    └── simplegit.rb

1 directory, 3 files
				
			

ওয়ার্কফ্লো

গিট-এর সাধারণ ওয়ার্কফ্লো হল এই তিনটি ট্রি-কে ম্যানিপুলেট করে ক্রমাগত ভালো অবস্থায় আপনার প্রজেক্টের স্ন্যাপশট রেকর্ড করা।

reset-workflow

আসুন এই প্রক্রিয়াটি ভালো করে বুঝার চেষ্টা করি: মনে করুন, আপনি একটি নতুন ডিরেক্টরিতে গিয়েছেন যেখানে একটি মাত্র ফাইল রয়েছে। আমরা এটিকে ফাইলটির v1 বলে ডাকবো। এবং আমরা এটি নীল রঙে নির্দেশ করব। এখন আমরা git init চালাই, যা একটি HEAD রেফারেন্স সহ একটি গিট রিপোজিটরি তৈরি করবে যা এখনও তৈরী হয়নি এমন  একটি  master ব্রাঞ্চের দিকে নির্দেশ করে।

reset-ex1

এই মুহুর্তে, শুধুমাত্র ওয়ার্কিং ডিরেক্টরি ট্রিতে যেকোন কন্টেন্ট আছে।


এখন আমরা এই ফাইলটি কমিট করতে চাই, তাই আমরা ওয়ার্কিং ডিরেক্টরিতে বিষয়বস্তু নেওয়ার জন্য git add কমান্ডটি ব্যবহার করি এবং এটিকে index-এ অনুলিপি করি।

reset-ex2

তারপরে আমরা git commit চালাই, যা index-এর বিষয়বস্তু নেয় এবং এটিকে একটি স্থায়ী স্ন্যাপশট হিসাবে সংরক্ষণ করে, একটি কমিট অবজেক্ট তৈরি করে যা সেই স্ন্যাপশটের দিকে নির্দেশ করে এবং সেই কমিট-এর দিকে নির্দেশ করার জন্য master আপডেট করে।

reset-ex3

যদি আমরা git status চালাই, আমরা কোন পরিবর্তন দেখতে পাব না, কারণ তিনটি ট্রি-ই একই। 

এখন আমরা সেই ফাইলটিতে একটি পরিবর্তন করতে চাই এবং এটি কমিট করতে চাই। আমরা একই প্রক্রিয়ার মধ্য দিয়ে যাব; প্রথমত, আমরা আমাদের ওয়ার্কিং ডিরেক্টরিতে ফাইলটি পরিবর্তন করি। চলুন, এটিকে ফাইলটির v2 বলে ডাকবো এবং এটিকে লাল রঙে নির্দেশ করি।

reset-ex4

 যদি আমরা এখনই git status চালাই, আমরা ফাইলটিকে “Changes not staged for commit” হিসেবে লাল রঙে দেখতে পাব , কারণ সেই  এন্ট্রিটি ইনডেক্স এবং ওয়ার্কিং ডিরেক্টরির মধ্যে আলাদা। এর পরে আমরা এটিকে আমাদের ইনডেক্স-এ স্টেজ করার জন্য এখানে git add চালাই।

reset-ex5

এই মুহুর্তে, যদি আমরা git status চালাই, আমরা ফাইলটিকে সবুজ রঙে দেখতে পাব “Changes to be committed” এর অধীনে , কারণ ইনডেক্স এবং HEAD আলাদা–অর্থাৎ, আমাদের প্রস্তাবিত পরবর্তী কমিট এখন আমাদের শেষ কমিট থেকে আলাদা। অবশেষে, আমরা কমিট চূড়ান্ত করতে git commit চালাই।

reset-ex6

এখন git status আমাদের কোন আউটপুট দেবে না, কারণ তিনটি ট্রিই আবার একই।

ব্রাঞ্চ পরিবর্তন বা ক্লোনিং একই প্রক্রিয়ার মধ্য দিয়ে যায়। আপনি যখন একটি ব্রাঞ্চ থেকে চেকআউট করেন, তখন এটি নতুন ব্রাঞ্চে রেফ-এর দিকে নির্দেশ করার জন্য HEAD পরিবর্তন করে, সেই কমিটের স্ন্যাপশট দিয়ে আপনার index পূরণ করে, তারপরে আপনার ওয়ার্কিং ডিরেক্টরিতেindex-এর বিষয়বস্তু অনুলিপি করে।

RESET এর ভূমিকা 

উপরের দৃশ্যপটের সাহায্যে reset কমান্ডটি আরওবোধগম্য হবে। 

এই উদাহরণগুলির উদ্দেশ্যে, ধরা যাক যে আমরা আবার file.txt সংশোধন করেছি এবং এটি তৃতীয়বার কমিট করেছি৷ সুতরাং এখন আমাদের ইতিহাস এরকম দেখায়:

reset-start

আপনি reset কমান্ডটি execute করার সময় reset-টি ঠিক কী করে তা এখন জেনে নেওয়া যাক। এটি একটি সহজ এবং অনুমানযোগ্য উপায়ে এই তিনটি ট্রিকে সরাসরি ম্যানিপুলেট করে। এটি তিনটি মৌলিক অপারেশন সম্পাদন করে।

 

ধাপ ১: HEAD কে সরানো

reset করার প্রথম কাজটি হ’ল HEAD যা নির্দেশ করে তা সরানো৷ এটি HEAD নিজেকে যেভাবে পরিবর্তন করে তেমনটি নয় (যেটি মূলত checkout যা করে); HEAD যে ব্রাঞ্চের দিকে নির্দেশ করছে reset সেটিকে সরিয়ে দেয়। এর মানে হল HEAD যদি master ব্রাঞ্চে সেট করা থাকে (অর্থাৎ আপনি বর্তমানে master ব্রাঞ্চে আছেন), git reset 9e5e6a4 কমান্ডটি master কে 9e5e6a4 তে পয়েন্ট করে রাখবে:

আপনি একটি কমিট দিয়ে reset যে কোন ভাবে কল করুন না কেন, এটিই প্রথম জিনিস যা reset কমান্ডটি সবসময় করার চেষ্টা করে। reset –soft কমান্ডের মাধ্যমে এটি কেবল সেখানে থামবে। 

 

এখন দ্বিতীয় ডায়াগ্রামটির দিকে লক্ষ্য করুন , এবং বুঝার চেষ্টা করুন কি ঘটতে চলছে; এটি মূলত শেষ  git commit কমান্ডটি বাতিল করে। আপনি যখন git commit চালান, গিট একটি নতুন কমিট তৈরি করে এবং HEAD যে পর্যন্ত পয়েন্ট করে আছে , ব্রাঞ্চটিকে সেই পর্যন্ত নিয়ে যায়। 

 

আপনি যখন HEAD ~ (HEAD এর parent) এ reset করেন, তখন আপনি ইনডেক্স বা ওয়ার্কিং ডিরেক্টরি পরিবর্তন না করেই ব্রাঞ্চটিকে যেখানে ছিল সেখানে নিয়ে যাচ্ছেন। আপনি এখন ইনডেক্স আপডেট করতে পারেন এবং git commit –amend সম্পন্ন করতে আবার git commit  চালাতে পারেন (শেষ কমিট পরিবর্তন করা দেখুন)।

 

ধাপ ২: Index (–mixed) আপডেট করা

মনে রাখবেন যে আপনি যদি এখন git status চালান তাহলে আপনি সবুজ রঙে ইনডেক্স এবং নতুন HEAD এর মধ্যে পার্থক্য দেখতে পাবেন।

 

reset করার পরের কাজটি হ’ল স্ন্যাপশট HEAD এখন যা নির্দেশ করে তার বিষয়বস্তু সহ ইনডেক্স কে আপডেট করা।

reset-mixed

 আপনি যদি –mixed অপশনটি উল্লেখ করেন , তাহলে reset এই পয়েন্টে থেমে যাবে। এটিও ডিফল্ট, তাই আপনি যদি কোনও অপশন উল্লেখ না করেন (শুধু git reset HEAD~ এই ক্ষেত্রে), এখানেই কমান্ডটি থামবে। 

এখন সেই ডায়াগ্রামে আরেকবার নজর দিন এবং বুঝুন কী ঘটেছে: এটি এখনও আপনার শেষ কমিট বাতিল করেছে, কিন্তু সবকিছুকেও আনস্টেজ করেছে। আপনার সমস্ত git add এবং git commit কমান্ড চালানোর আগের অবস্থায় আপনি ফিরে এসেছেন।

ধাপ ৩: Working Directory (–hard) আপডেট করা

তৃতীয় ধাপ, যা reset করবে তা হল ওয়ার্কিং ডিরেক্টরিটিকে ইনডেক্স-এর মতো দেখাবে। আপনি যদি “–hard” অপশনটি ব্যবহার করেন তবে এটি এই পর্যায়ে চলতে থাকবে। 

reset-hard

তো চলুন ভেবে দেখি কি ঘটেছে। আপনি আপনার শেষ কমিট, git add এবং git commit এবং আপনার ওয়ার্কিং ডিরেক্টরিতে আপনি যে সমস্ত কাজ করেছেন তা বাতিল করেছেন।

 

এটি লক্ষ করা গুরুত্বপূর্ণ যে এই ফ্ল্যাগ (–hardreset কমান্ডকে বিপজ্জনক করার একমাত্র উপায় এবং খুব কম ক্ষেত্রের মধ্যে একটি যেখানে গিট আসলে ডেটা ধ্বংস করবে। reset এর অন্য যেকোন এক্সেকিউশন খুব সহজেই পূর্বাবস্থায় ফিরিয়ে আনা যায়, কিন্তু –hard অপশনটি পারে না, কারণ এটি ওয়ার্কিং ডিরেক্টরির ফাইলগুলিকে জোরপূর্বক ওভাররাইট করে। বিশেষত এই ক্ষেত্রে, আমাদের কাছে এখনও, গিট ডাটাবেইজ-এর , একটি কমিটের মধ্যে আমাদের ফাইলটির v3 ভার্সন আছে। আমরা আমাদের reflog দেখে এটি ফিরে পেতে পারি, কিন্তু যদি আমরা এটি ইতিমধ্যে কমিট না করে থাকি তবে গিট যদি তখনও ফাইলটি ওভাররাইট করত তাহলে , এটি পুনঃউদ্ধার করা সম্ভব হতো না।

সংক্ষেপে

reset কমান্ড এই তিনটি ট্রি-কে একটি নির্দিষ্ট ক্রমে ওভাররাইট করে, যখন আপনি এটিকে বলবেন তখন থামবে: 

  1. ব্রাঞ্চের HEAD পয়েন্টগুলিকে সরান (–soft অপশনসহ হলে , এখানে থামুন)
  2. ইনডেক্সটিকে HEAD-র মতো দেখান (–hard অপশন না হলে,  এখানে থামুন)
  3. ওয়ার্কিং ডিরেক্টরিটিকে ইনডেক্সের মতো দেখান।

 

একটি path দিয়ে রিসেট করুন

reset এর মৌলিক ব্যবহার সম্পর্কে আলোচনা করা হল,  তবে আপনি এটিতে কাজ করার জন্য এর সাথে path ও দিয়ে দিতে পারেন। যদি আপনি একটি পাথ নির্দিষ্ট করেন, reset ধাপ ১ (ধাপ ১: HEAD কে সরানো) এড়িয়ে যাবে, এবং একটি নির্দিষ্ট ফাইল বা ফাইলের সেটে এর অবশিষ্ট ধাপগুলি সীমাবদ্ধ করবে। এটি প্রকৃতপক্ষে অর্থবহ করে তোলে — HEAD শুধুমাত্র একটি পয়েন্টার, এবং আপনি একটি কমিটের অংশ এবং অন্য কমিটের অংশ নির্দেশ করতে পারবেন না, এ ব্যাপারগুলোকে অর্থবহ করে তোলে। কিন্তু ইনডেক্স এবং ওয়ার্কিং ডিরেক্টরি আংশিকভাবে আপডেট করা যেতে পারে, তাই reset-এর ২ এবং ৩ ধাপের সাথে এগিয়ে যান।

সুতরাং, ধরে নিই আমরা git reset file.txt চালাচ্ছি। এই ফর্মটি git reset –mixed HEAD file.txt -এর সংক্ষিপ্ত বিবরণ হবে  (যেহেতু আপনি একটি কমিট SHA-1 বা ব্রাঞ্চ নির্দিষ্ট করেননি, এবং আপনি –soft বা –hard উল্লেখ করেননি):

  1. ব্রাঞ্চের HEAD পয়েন্টগুলিকে সরান (এড়িয়ে যান)
  2. ইনডেক্স কে HEAD এর মতো দেখান (এখানে থামুন)

 

তাই এটি মূলত শুধুমাত্র file.txt কে HEAD থেকে ইনডেক্স-এ কপি করে। 

reset-path1

এটি ফাইলটি আনস্টেজ করার কার্যকর প্রভাব রয়েছে। আমরা যদি , কমান্ডের ডায়াগ্রামের দিকে লক্ষ্য করি , এবং  git add যা করেন, তারা ঠিক বিপরীত কাজ করে। 

reset-path2

এ কারণেই git status কমান্ডের আউটপুট পরামর্শ দেয় যে আপনি একটি ফাইল আনস্টেজ করতে এটি চালান (এ সম্পর্কে আরও জানতে একটি স্টেজড ফাইল আনস্টেজ করা দেখুন)।

আমরা সহজেই গিটকে অনুমান করতে দিতে পারি না যে আমরা “pull the data from HEAD” বলতে একটি নির্দিষ্ট কমিট নির্দিষ্ট করে সেই ফাইল সংস্করণটি পুল করতে চাইছি। আমরা শুধু git reset eb43bf file.txt এর মত কিছু রান করব।

reset-path3

এটি কার্যকরভাবে একই কাজ করে যেমন আমরা ফাইলের বিষয়বস্তুকে ওয়ার্কিং ডাইরেক্টরিতে v1 তে ফিরিয়ে দিয়েছি, এটিতে git add  চালিয়েছি, তারপর এটিকে আবার v3 তে ফিরিয়ে দিয়েছি (আসলে এই সমস্ত পদক্ষেপগুলি না করে)। যদি আমরা এখন git commit চালাই, তবে এটি এমন একটি পরিবর্তন রেকর্ড করবে যা সেই ফাইলটিকে v1 -এ ফিরিয়ে দেয়, যদিও আমাদের ওয়ার্কিং ডিরেক্টরিতে এটি আর কখনও ছিল না। এটি লক্ষ্য করাও আকর্ষণীয় যে git add-এর মতো, reset কমান্ড হাঙ্ক-বাই-হাঙ্ক  ভিত্তিতে বিষয়বস্তু আনস্টেজ করার জন্য একটি –patch অপশন গ্রহণ করবে। 

স্কোয়াশিং

স্কোয়াশিং কমিট – নতুন পাওয়া এই শক্তি দিয়ে কীভাবে আকর্ষণীয় কিছু করা যায় তা দেখা যাক।

মনে করুন, আপনার কাছে “oops.”, “WIP” এবং “forgot this file” এর মতো বার্তাগুলির সাথে একটি কমিটের সিরিজ রয়েছে। আপনি দ্রুত এবং সহজে একটি একক কমিট-এ স্কোয়াশ করতে reset ব্যবহার করতে পারেন যা আপনাকে সত্যিই স্মার্ট করবে। Squashing Commits এটি করার আরেকটি উপায় দেখায়, কিন্তু এই উদাহরণে reset ব্যবহার করাই সহজ।

ধরা যাক আপনার কাছে একটি প্রজেক্ট আছে যেখানে প্রথম কমিটের একটি ফাইল রয়েছে, দ্বিতীয় কমিট একটি নতুন ফাইল যুক্ত করেছে এবং প্রথমটি পরিবর্তন করেছে এবং তৃতীয় কমিটটি আবার প্রথম ফাইলটি পরিবর্তন করেছে। দ্বিতীয় কমিটটি একটি কাজ-এ চলমান ছিল এবং আপনি এটি স্কোয়াশ করতে চান।

reset-squash-r1

আপনি HEAD ব্রাঞ্চটিকে একটি পুরানো কমিটে ফিরিয়ে নিতে git reset –soft HEAD~2 কমান্ডটি চালাতে পারেন (সবচেয়ে সাম্প্রতিক যে কমিটটি আপনি রাখতে চান):

reset-squash-r2

এবং তারপরে আবার git commit চালান:

reset-squash-r3

এখন আপনি দেখতে পাচ্ছেন যে আপনার পৌঁছানোযোগ্য ইতিহাস, আপনি যে ইতিহাসটি পুশ করে দেবেন, এখন মনে হচ্ছে আপনি file-a.txt v1 সহ একটি কমিট দিয়েছেন, তারপর ২য় কমিটে উভয়ই file-a.txt কে v3 তে পরিবর্তিত করে এবং file-b.txt যোগ করে। ফাইলের v2 সংস্করণের সাথে কমিটটি আর ইতিহাসে নেই।

এটা দেখুন

অবশেষে, আপনি ভাবতে পারেন checkout এবং reset -এর মধ্যে পার্থক্য কী। reset -এর মতো, checkout তিনটি ট্রি-কে ম্যানিপুলেট করে এবং আপনি কমান্ডটিকে একটি ফাইল পাথ দেন কি না তার উপর নির্ভর করে এটি কিছুটা আলাদা।

পাথ ছাড়া

git checkout [branch] চালানো হচ্ছে git reset –hard [branch] চালানোর মতই যে এটি আপনার [branch] -এর মত দেখতে তিনটি ট্রিই আপডেট করে, কিন্তু এখানে দুটি গুরুত্বপূর্ণ পার্থক্য রয়েছে।

প্রথমত, এই reset –hard এর বিপরীতে, checkout কমান্ডটি ওয়ার্কিং-ডিরেক্টরির জন্য নিরাপদ; এটি নিশ্চিত করতে চেক করবে যে এটি তাদের পরিবর্তন করা ফাইলগুলিকে সরিয়ে দিচ্ছে কি না। প্রকৃতপক্ষে, এটি তার চেয়ে কিছুটা স্মার্ট — এটি ওয়ার্কিং ডিরেক্টরিতে একটি তুচ্ছ মার্জ করার চেষ্টা করে, তাই আপনি যে ফাইলগুলি পরিবর্তন করেননি সেগুলি আপডেট করা হবে৷ অন্য দিকে, reset –hard কমান্ডটি পরীক্ষা না করেই বোর্ড জুড়ে সবকিছু প্রতিস্থাপন করবে।

দ্বিতীয় গুরুত্বপূর্ণ পার্থক্য হল checkout কিভাবে HEAD আপডেট করে। যেখানে, HEAD যে ব্রাঞ্চটিকে নির্দেশ করে, reset সেই ব্রাঞ্চটিকে সরিয়ে দেবে, checkout অন্য ব্রাঞ্চ নির্দেশ করতে HEAD কে নিজেই সরিয়ে দিবে।

উদাহরণস্বরূপ, ধরা যাক আমাদের কাছে master এবং develop ব্রাঞ্চ রয়েছে যা বিভিন্ন কমিটের দিকে নির্দেশ করে এবং আমরা বর্তমানে develop ব্রাঞ্চে আছি (তাই HEAD এটির দিকে নির্দেশ করে)। যদি আমরা git reset master কমান্ড চালাই, develop নিজেই এখন সেই একই কমিট নির্দেশ করবে যা master করে। আমরা যদি এর পরিবর্তে  git checkout master কমান্ড চালাই, develop নড়াচড়া করে না, HEAD নিজেই করে। HEAD এখন master -এর দিকে নির্দেশ করবে।

সুতরাং, উভয় ক্ষেত্রেই আমরা commit A নির্দেশ করার জন্য HEAD কে সরিয়ে নিচ্ছি , কিন্তু আমরা কীভাবে তা করি তা খুব আলাদা। reset , HEAD এর নির্দেশ করা ব্রাঞ্চকে সরাবে, checkout নিজেই হেডকে সরিয়ে দিবে।

reset-checkout

পাথ সহ

checkout চালানোর অন্য উপায় হল একটি ফাইল পাথ সাথে দিয়ে দেয়া, যা reset -এর মতো, HEAD কে সরায় না। এটি git reset [branch] file কমান্ডের মতো যে এটি সেই কমিট-এর সেই ফাইলের সাথে ইনডেক্স আপডেট করে, তবে এটি ওয়ার্কিং-ডিরেক্টরিতে ফাইলটিকে ওভাররাইট ও করে। এটি হুবহু git reset –hard [branch] file কমান্ডের মতো হবে (যদি reset আপনাকে এটি চালাতে দেয়) এটি ওয়ার্কিং-ডিরেক্টরির জন্য নিরাপদ নয় এবং এটি কখনই HEAD কে সরায় না।

এছাড়াও, git reset এবং git add -এর মতো, checkout একটি –patch ফ্ল্যাগ গ্রহণ করে যা আপনাকে বেছে বেছে ফাইলের বিষয়বস্তু হাঙ্ক-বাই-হাঙ্ক ভিত্তিতে আগের অবস্থায় ফিরিয়ে আনার অনুমতি দেয়।

সারসংক্ষেপ 

আশা করি এখন আপনি reset কমান্ডটি বুঝতে পেরেছেন এবং আরও স্বাচ্ছন্দ্য বোধ করছেন, তবে সম্ভবত এখনও এটি checkout থেকে ঠিক কীভাবে আলাদা তা নিয়ে আপনি কিছুটা বিভ্রান্ত এবং সম্ভবত বিভিন্ন এক্সেকিউশনের সমস্ত নিয়ম মনে রাখতে সম্ভবপর হয়ে উঠবে না ।

কোন কমান্ড কোন ট্রি-কে প্রভাবিত করবে, তার একটি চিট-শিট এখানে দেয়া হল। “HEAD” কলামটি “REF” পড়ে, যদি এটি নিজেই HEAD-কে সরায়, যদি সেই কমান্ডটি “HEAD” এবং HEAD নির্দেশিত রেফারেন্স (শাখা) স্থানান্তরিত করে। নিচের টেবিলের “WD Safe?” কলামের দিকে একটু মনোযোগ দিয়ে লক্ষ্য করুন — যদি কলামটির ভ্যালু “NO” হয়, সেই কমান্ডটি চালানোর আগে চিন্তা করার জন্য এক সেকেন্ড সময় নিন।