Vivasoft-logo

২.৪ গিট বেসিক – জিনিসগুলি পূর্বাবস্থায় ফিরিয়ে আনা

পূর্বাবস্থায় ফিরিয়ে আনা

ধরা যাক আপনি এবার আপনার করা কোনো পরিবর্তনকে আগের অবস্থায় নিয়ে যেতে চান। এই পর্বে আমরা সেই সম্পর্কে কিছু ব্যসিক টুল নিয়ে আলোচনা করবো। এখানে একটি গুরুত্বপূর্ণ বিষয় হলো, এই যে আপনি আপনার পরিবর্তনগুলোকে আগের অবস্থায় নিচ্ছেন, সেটা থেকে আবার পরিবর্তনগুলোকে সবসময় ফিরে নাও পেতে পারেন। এই অংশটি হচ্ছে গিটের সেই অংশগুলোর মধ্যে একটি যেখানে ভুল করলে আপনার মূল্যবান কাজগুলো হারিয়ে যেতে পারে। ধরা যাক আপনি প্রয়োজনীয় সব ফাইল অন্তর্ভুক্ত না করেই কমিট করে ফেলেছেন বা আপনার কমিট-ম্যাসেজটি ভুল করেছেন। এখন আপনি চাইছেন আগের কমিটটি পরিবর্তন করতে। তো এর জন্য কী করবেন? প্রথমে যে ফাইলগুলোতে পরিবর্তন করতে ভুলে গেছেন, সেগুলোতে প্রয়োজনীয় পরিবর্তন করুন, তারপর সেগুলোকে স্টেজ করুন এবং সবশেষে –amend অপশনটি যুক্ত করে আবার কমিট করুন।
				
					$ git commit -m 'Initial commit'
$ git add forgotten_file
$ git commit --amend

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

আগের কমিটের সংশোধনের মূল উদ্দেশ্য হচ্ছে সেই কমিটটির কোনো ছোটো উন্নয়ন যাতে “ফাইল অ্যাড করতে ভুলে গিয়েছিলাম” অথবা “লাস্ট কমিটের টাইপো চেঞ্জ” – এই জাতীয় কমিট-ম্যাসেজ দিয়ে রিপোজিটরির হিস্টোরিতে বিশৃঙ্খলা সৃষ্টি না হয়।
নোট

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

স্টেজড ফাইলকে আনস্টেজ করাঃ

আগামী দুটো সেকশনে আমরা দেখবো কীভাবে আমাদের স্টেজিং এবং ওয়ার্কিং ডিরেক্টরি পরিবর্তনগুলো নিয়ে কাজ করতে হয়। মজার ব্যাপার হলো, যেই কমান্ড দিয়ে আপনি ঐ দুটো অংশের অবস্থা জানতে পারেন, সেটিই আপনাকে মনে করিয়ে দেবে কীভাবে আপনি আপনার পরিবর্তনগুলোকে পূর্বাবস্থায় ফিরিয়ে নেবেন। উদাহরণস্বরূপ ধরা যাক আপনি দুটো ফাইল পরিবর্তন করেছেন এবং আলাদাভাবে দুটো কমিট করতে চান। কিন্তু ভুলক্রমে git add * কমান্ড দিয়ে দুটোকেই স্টেজড করে ফেলেছেন। এখন কীভাবে যে কোনো একটিকে আনস্টেজ করবেন? git status কমান্ড সেটাই আপনাকে মনে করিয়ে দেয়ঃ
				
					$ git add *
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    renamed:    README.md -> README
    modified:   CONTRIBUTING.md

				
			
দেখুন, চেঞ্জেস টু বি কমিটেড এর নিচেই বলা হচ্ছে যে আনস্টেজ করার জন্য git reset HEAD ​ কমান্ডটি ব্যবহার করার জন্য। তাই চলুন, সেভাবে CONTRIBUTING.md ফাইলটি আনস্টেজ করি।
				
					$ git reset HEAD CONTRIBUTING.md
Unstaged changes after reset:
M	CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    renamed:    README.md -> README

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   CONTRIBUTING.md

				
			
এই কমান্ডটি একটু অদ্ভূত কিন্তু ঠিকঠাক কাজই করে । CONTRIBUTING.md ফাইলটির পরিবর্তন আগের মতোই আছে কিন্তু এখন এটি আবার আনস্টেজড হয়ে গেছে।
নোট
এটি ঠিক যে git reset একটি বিপদজনক কমান্ড হতে পারে, বিশেষ করে যদি –hard ফ্লাগ দেয়া হয়। যাইহোক, উপরের উদাহরণটিতে আপনার ওয়ার্কিং ডিরেক্টরির ফাইলটিকে ধরা হয়নি, তাই এটি তুলনামূলকভাবে নিরাপদ
আপাতত git reset কমান্ড সম্পর্কে আপনার যা জানা প্রয়োজন তা এতটুকুই। reset কী করে আর কীভাবে এর উপর দক্ষতা এনে বেশ চমকপ্রদ কাজ করা যায় তা সম্পর্কে বিস্তারিত জানা যাবে এখান থেকে রিসেট ডেমেস্টিফাইড।

মডিফাইড ফাইলকে আনমডিফাই করাঃ

এখন আপনার মনে হলো যে, নাহ, CONTRIBUTING.md ফাইলের পরিবর্তনগুলো আপনার আর লাগবে না। এখন কীভাবে সহজেই আপনি শেষ কমিটের সময় (বা ক্লোন করার সময় বা ওয়ার্কিং ডিরেক্টরিতে) ফাইলটি যেরকম ছিলো সেরকম করবেন? আসলে git status এটাও আপনাকে বলে দেয়। আগের উদাহরণে আনস্টেজড অংশটি দেখতে এমন ছিলোঃ
				
					Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   CONTRIBUTING.md

				
			
এটি আপনাকে স্পষ্টভাবে বলে দিচ্ছে কীভাবে আপনি আপনার করা পরিবর্তনগুলোকে বাদ দিবেন। চলুন সেভাবে করে দেখিঃ
				
					$ git checkout -- CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    renamed:    README.md -> README

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

মনে রাখবেন, গিটে কমিট করা প্রায় যে কোন কিছুই পুনরায় ফিরিয়ে আনা সম্ভব। এমনকি ডিলেট করে দেওয়া ব্রাঞ্চে থাকা কমিট বা যেই কমিটগুলো –amend কমিট দ্বারা ওভাররাইট করা হয়েছে, সেগুলোও পুনরুদ্ধার করা সম্ভব (ডেটা পুনরুদ্ধারের জন্য ডাটা রিকোভারি দেখুন)। কিন্তু কমিট না করা কোনো পরিবর্তন যদি আপনি হারিয়ে ফেলেন, তাহলে আর কখনোই সেটা দেখতে পারবেন না।

গিট রিস্টোর দিয়ে জিনিসগুলি পূর্বাবস্থায় ফিরিয়ে আনাঃ

গিট সংস্করণ 2.23.0 তে git restore নামে একটি নতুন কমান্ডকে পরিচয় করানো হয়েছে। এটি মূলত git reset এর একটি বিকল্প। গিট সংস্করণ 2.23.0 থেকে কোনোকিছুকে আগের অবস্থায় নেওয়ার জন্য গিট git reset এর পরিবর্তে git restore ব্যবহার করবে।

এখন আমরা আমাদের পূর্বের কাজগুলো git reset এর পরিবর্তে git restore দিয়ে করব।

গিট রিস্টোর দিয়ে স্টেজড ফাইলকে আনস্টেজ করাঃ

আগামী দুটো সেকশনে আমরা দেখবো কিভাবে আমাদের স্টেজিং অংশ এবং ওয়ার্কিং ডিরেক্টরি পরিবর্তনগুলো নিয়ে git restore দিয়ে কাজ করতে হয়। এখানে একটা মজার বিষয় হচ্ছে যেই কমান্ড দিয়ে আপনি ঐ দুটো অংশের অবস্থা জানতে পারেন, সেটিই আপনাকে মনে করিয়ে দেবে কীভাবে আপনি আপনার পরিবর্তনগুলোকে পূর্বাবস্থায় ফিরিয়ে নেবেন। উদাহরণস্বরূপ ধরা যাক আপনি দুটো ফাইল পরিবর্তন করেছেন এবং আলাদাভাবে দুটো কমিট করতে চান। কিন্তু ভুলক্রমে git add * কমান্ড দিয়ে দুটোকেই স্টেজড করে ফেলেছেন। এখন কীভাবে যে কোনো একটিকে আনস্টেজ করবেন? git status কমান্ড সেটাই আপনাকে মনে করিয়ে দেয়ঃ
				
					$ git add *
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   CONTRIBUTING.md
	renamed:    README.md -> README

				
			
দেখুন, চেঞ্জেস টু বি কমিটেড এর নিচেই বলা হচ্ছে যে আনস্টেজ করার জন্য git restore –staged … কমান্ডটি ব্যবহার করার জন্য। তাই চলুন, সেভাবে CONTRIBUTING.md ফাইলটি আনস্টেজ করি।
				
					$ git restore --staged CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	renamed:    README.md -> README

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   CONTRIBUTING.md

				
			
CONTRIBUTING.md ফাইলটির পরিবর্তন আগের মতোই আছে কিন্তু এখন এটি আবার আনস্টেজড হয়ে গেছে।

গিট রিস্টোর দিয়ে মডিফাইড ফাইলকে আনমডিফাই করাঃ

এখন আপনার মনে হলো যে, নাহ, CONTRIBUTING.md ফাইলের পরিবর্তনগুলো আপনার আর লাগবে না। এখন কীভাবে সহজেই আপনি শেষ কমিটের সময় (বা ক্লোন করার সময় বা ওয়ার্কিং ডিরেক্টরিতে) ফাইলটি যেরকম ছিলো সেরকম করবেন? আসলে git status এটাও আপনাকে বলে দেয়। আগের উদাহরণে আনস্টেজড অংশটি দেখতে এমন ছিলোঃ
				
					Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   CONTRIBUTING.md

				
			
এটি আপনাকে স্পষ্টভাবে বলে দিচ্ছে কীভাবে আপনি আপনার করা পরিবর্তনগুলোকে বাদ দিবেন। চলুন সেভাবে করে দেখিঃ
				
					$ git restore CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	renamed:    README.md -> README

				
			
গুরুত্বপূর্ণঃ

এটি জানা খুবই গুরুত্বপূর্ণ যে git restore <file> একটি বিপদজনক কমান্ড। এর মাধ্যমে গিট ফাইলটিকে তার আগের ভার্সনে নিয়ে যায়, ফলে পরবর্তীতে আপনার করা সব ধরনের লোকাল পরিবর্তন গুলো হারিয়ে যায়। তাই লোকাল পরিবর্তনগুলো আর লাগবে না – এই ব্যাপারে পুরোপুরি নিশ্চিত না হয়ে এই কমান্ডটি ব্যবহার করা কোনোভাবেই উচিত হবে না।