paint-brush
আত্মবিশ্বাসের সাথে গিট ইতিহাস পুনর্লিখন: একটি গাইডদ্বারা@omerosenbaum
2,014 পড়া
2,014 পড়া

আত্মবিশ্বাসের সাথে গিট ইতিহাস পুনর্লিখন: একটি গাইড

দ্বারা Omer Rosenbaum18m2023/04/27
Read on Terminal Reader
Read this story w/o Javascript

অতিদীর্ঘ; পড়তে

Git হল একটি সিস্টেম যা সময়মতো ফাইল সিস্টেমের স্ন্যাপশট রেকর্ড করার জন্য। একটি গিট রিপোজিটরিতে তিনটি "স্টেট" বা "ট্রি" থাকে: সূচক, স্টেজিং এরিয়া এবং ওয়ার্কিং ট্রি। একটি ওয়ার্কিং ডির(ইক্টোরি) হল আমাদের ফাইল সিস্টেমের যেকোন ডিরেক্টরি যার সাথে একটি গিট রেপো যুক্ত আছে।
featured image - আত্মবিশ্বাসের সাথে গিট ইতিহাস পুনর্লিখন: একটি গাইড
Omer Rosenbaum HackerNoon profile picture

একজন বিকাশকারী হিসাবে, আপনি সব সময় Git এর সাথে কাজ করেন।


আপনি কি কখনও এমন একটি বিন্দুতে পৌঁছেছেন যেখানে আপনি বলেছিলেন: "উহ-ওহ, আমি কি করেছি?"

যখন জিটের সাথে কিছু ভুল হয়ে যায়, তখন অনেক প্রকৌশলী অসহায় বোধ করেন (উৎস: XKCD)


এই পোস্টটি আপনাকে আত্মবিশ্বাসের সাথে ইতিহাস পুনর্লিখন করার সরঞ্জাম দেবে।

আমরা শুরু করার আগে নোট

  1. আমি এই পোস্টের বিষয়বস্তু কভার একটি লাইভ বক্তৃতা দিয়েছি. আপনি যদি একটি ভিডিও পছন্দ করেন (বা পড়ার পাশাপাশি এটি দেখতে চান) - আপনি এটি খুঁজে পেতে পারেন এখানে .


  2. আমি গিট সম্পর্কে একটি বই কাজ করছি! আপনি কি প্রাথমিক সংস্করণ পড়তে এবং প্রতিক্রিয়া প্রদান করতে আগ্রহী? আমাকে একটি ইমেল পাঠান: [email protected]

Git এ পরিবর্তন রেকর্ডিং

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


সময়মত একটি ফাইল সিস্টেমের স্ন্যাপশট রেকর্ড করার জন্য একটি সিস্টেম হিসাবে গিট সম্পর্কে চিন্তা করা খুব দরকারী। একটি গিট সংগ্রহস্থল বিবেচনা করে, এটির তিনটি "রাষ্ট্র" বা "গাছ" রয়েছে:

একটি গিট রেপোর তিনটি "গাছ" (উৎস: https://youtu.be/ozA1V00GIT8)


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


এটিতে আমাদের প্রকল্পের ফোল্ডার এবং ফাইল রয়েছে এবং .git নামে একটি ডিরেক্টরিও রয়েছে। আমি .git ফোল্ডারের বিষয়বস্তু আরও বিস্তারিতভাবে বর্ণনা করেছি আগের একটি পোস্ট .


আপনি কিছু পরিবর্তন করার পরে, আপনি সেগুলি আপনার সংগ্রহস্থলে রেকর্ড করতে চাইতে পারেন। একটি রিপোজিটরি (সংক্ষেপে: repo ) হল কমিটগুলির একটি সংগ্রহ, যার প্রত্যেকটি একটি আর্কাইভ যা প্রকল্পের কার্যকারী গাছটি অতীতের তারিখে কেমন ছিল, তা আপনার মেশিনে হোক বা অন্য কারও।


একটি সংগ্রহস্থলে আমাদের কোড ফাইলগুলি ছাড়াও অন্যান্য জিনিসগুলিও অন্তর্ভুক্ত থাকে, যেমন HEAD , শাখা ইত্যাদি।


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


যখন আমরা git commit ব্যবহার করি, কমিট তৈরি করা হয় সূচকের অবস্থার উপর ভিত্তি করে।


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


হাত পেতে সময় 🙌🏻


একটি নতুন সংগ্রহস্থল শুরু করতে git init ব্যবহার করুন। 1.txt নামে একটি ফাইলে কিছু পাঠ্য লিখুন:

একটি নতুন রেপো শুরু করা এবং এটিতে প্রথম ফাইল তৈরি করা (সূত্র: https://youtu.be/ozA1V00GIT8)


উপরে বর্ণিত তিনটি ট্রি স্টেটের মধ্যে 1.txt এখন কোথায়?


কাজের গাছে, যেহেতু এটি এখনও সূচকে প্রবর্তিত হয়নি।

ফাইল `1.txt` এখন শুধুমাত্র কাজের ডির এর একটি অংশ (সূত্র: https://youtu.be/ozA1V00GIT8)


এটিকে স্টেজ করার জন্য, সূচীতে যোগ করতে, git add 1.txt ব্যবহার করুন।

'গিট অ্যাড' ব্যবহার করা ফাইলটিকে পর্যায়ভুক্ত করে তাই এটি এখন সূচীতেও রয়েছে (সূত্র: https://youtu.be/ozA1V00GIT8)


এখন, আমরা রিপোজিটরিতে আমাদের পরিবর্তনগুলি কমিট করতে git commit ব্যবহার করতে পারি।

`গিট কমিট` ব্যবহার করা রিপোজিটরিতে একটি কমিট অবজেক্ট তৈরি করে (সূত্র: https://youtu.be/ozA1V00GIT8)


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


গিটের বস্তু সম্পর্কে আরও তথ্যের জন্য (যেমন কমিট এবং গাছ), আমার আগের পোস্ট দেখুন .


(হ্যাঁ, "চেক আউট", শ্লেষ উদ্দেশ্য 😇)


গিট আমাদের এই কমিট অবজেক্টের SHA-1 মানও বলে। আমার ক্ষেত্রে, এটি ছিল c49f4ba (যা SHA-1 মানের প্রথম 7টি অক্ষর, কিছু স্থান বাঁচাতে)।


আপনি যদি আপনার মেশিনে এই কমান্ডটি চালান, আপনি একটি ভিন্ন SHA-1 মান পাবেন, কারণ আপনি একজন ভিন্ন লেখক; এছাড়াও, আপনি একটি ভিন্ন টাইমস্ট্যাম্পে কমিট তৈরি করবেন।


যখন আমরা রেপো শুরু করি, গিট একটি নতুন শাখা তৈরি করে (ডিফল্টরূপে main নামকরণ করা হয়)। এবং গিটের একটি শাখা একটি প্রতিশ্রুতির একটি নাম উল্লেখ করা হয়েছে . তাই ডিফল্টরূপে, আপনি শুধুমাত্র main শাখা আছে. আপনার একাধিক শাখা থাকলে কি হবে? কিভাবে গিট জানে যে কোন শাখা সক্রিয় শাখা?


গিট-এর HEAD নামক আরেকটি পয়েন্টার রয়েছে, যা একটি শাখার দিকে নির্দেশ করে (সাধারণত) যা একটি কমিটের দিকে নির্দেশ করে। যাইহোক, ফণা অধীনে, HEAD শুধু একটি ফাইল। এটি কিছু উপসর্গ সহ শাখার নাম অন্তর্ভুক্ত করে।


রেপোতে আরও পরিবর্তন প্রবর্তনের সময়!


এখন, আমি আরেকটি তৈরি করতে চাই। তো চলুন একটি নতুন ফাইল তৈরি করি এবং সূচীতে যোগ করি, আগের মতো:

ফাইল `2.txt` কাজ করার ডির এবং সূচীতে আছে `git add` দিয়ে স্টেজ করার পর (সূত্র: https://youtu.be/ozA1V00GIT8)


এখন, git commit ব্যবহার করার সময়। গুরুত্বপূর্ণভাবে, git commit দুটি জিনিস করে:


প্রথমত, এটি একটি কমিট অবজেক্ট তৈরি করে, তাই গিটের অভ্যন্তরীণ অবজেক্ট ডাটাবেসের মধ্যে একটি অনুরূপ SHA-1 মান সহ একটি অবজেক্ট রয়েছে। এই নতুন কমিট অবজেক্টটি প্যারেন্ট কমিটের দিকেও নির্দেশ করে। এটি সেই প্রতিশ্রুতি যা HEAD নির্দেশ করেছিল যখন আপনি git commit কমান্ড লিখেছিলেন।

একটি নতুন কমিট অবজেক্ট তৈরি করা হয়েছে, প্রথমে — `প্রধান` এখনও আগের প্রতিশ্রুতির দিকে নির্দেশ করে (সূত্র: https://youtu.be/ozA1V00GIT8)


দ্বিতীয়ত, git commit সক্রিয় শাখার পয়েন্টারকে স্থানান্তরিত করে — আমাদের ক্ষেত্রে, এটি main হবে, নতুন তৈরি কমিট অবজেক্টের দিকে নির্দেশ করতে।

`গিট কমিট` সদ্য তৈরি কমিট অবজেক্টের দিকে নির্দেশ করতে সক্রিয় শাখাকেও আপডেট করে (সূত্র: https://youtu.be/ozA1V00GIT8)


পরিবর্তন পূর্বাবস্থায়

ইতিহাস পুনর্লিখনের জন্য, আসুন একটি প্রতিশ্রুতি প্রবর্তনের প্রক্রিয়াটিকে পূর্বাবস্থায় ফিরিয়ে নিয়ে শুরু করি। এর জন্য, আমরা git reset কমান্ডটি জানব, একটি সুপার পাওয়ারফুল টুল।

git reset --soft

সুতরাং আপনি আগে যে শেষ ধাপটি করেছিলেন তা ছিল git commit , যার অর্থ আসলে দুটি জিনিস — গিট একটি কমিট অবজেক্ট তৈরি করেছে এবং main , সক্রিয় শাখাকে সরিয়ে নিয়েছে। এই ধাপটিকে পূর্বাবস্থায় ফেরাতে, কমান্ডটি ব্যবহার করুন git reset --soft HEAD~1


সিনট্যাক্স HEAD~1 HEAD এর প্রথম প্যারেন্টকে বোঝায়। আমার যদি কমিট-গ্রাফে একাধিক কমিট থাকে, তাহলে বলুন "কমিট 3" নির্দেশ করে "কমিট 2" এর দিকে নির্দেশ করে, যেটি পরিবর্তে, "কমিট 1" এর দিকে নির্দেশ করে।


এবং বলুন HEAD "কমিট 3" এর দিকে ইশারা করছিল। আপনি "কমিট 2" উল্লেখ করতে HEAD~1 ব্যবহার করতে পারেন, এবং HEAD~2 "কমিট 1" উল্লেখ করবে।


সুতরাং, কমান্ডে ফিরে যান: git reset --soft HEAD~1


এই কমান্ডটি গিটকে HEAD যা নির্দেশ করছে তা পরিবর্তন করতে বলে। (দ্রষ্টব্য: নীচের চিত্রগুলিতে, আমি " HEAD যা নির্দেশ করছে" এর জন্য *HEAD ব্যবহার করি)। আমাদের উদাহরণে, HEAD main নির্দেশ করছে। তাই গিট শুধুমাত্র main পয়েন্টার পরিবর্তন করে HEAD~1 নির্দেশ করবে। অর্থাৎ, main "কমিট 1" নির্দেশ করবে।


যাইহোক, এই আদেশটি সূচকের অবস্থা বা কার্যকারী গাছকে প্রভাবিত করেনি । সুতরাং আপনি যদি git status ব্যবহার করেন তবে আপনি দেখতে পাবেন যে 2.txt মঞ্চস্থ হয়েছে, ঠিক যেমন আপনি git commit চালানোর আগে।

'প্রধান' রিসেট করা হচ্ছে "কমিট 1" (সূত্র: https://youtu.be/ozA1V00GIT8)


git log? এটি HEAD থেকে শুরু হবে, main যাবেন এবং তারপর "কমিট 1" এ যাবে। লক্ষ্য করুন যে এর অর্থ হল "কমিট 2" আমাদের ইতিহাস থেকে আর পৌঁছানো যায় না।


এর মানে কি "কমিট 2" এর কমিট অবজেক্ট মুছে ফেলা হয়েছে? 🤔


না, এটা মুছে ফেলা হয় নি. এটি এখনও অবজেক্টের গিট এর অভ্যন্তরীণ অবজেক্ট ডাটাবেসের মধ্যে থাকে।


আপনি যদি বর্তমান ইতিহাসকে এখনই ধাক্কা দেন, git push ব্যবহার করে, গিট রিমোট সার্ভারে "কমিট 2" পুশ করবে না, তবে কমিট অবজেক্টটি আপনার সংগ্রহস্থলের স্থানীয় অনুলিপিতে এখনও বিদ্যমান রয়েছে।


এখন, আবার কমিট করুন — এবং মূল "কমিট 2" থেকে এই নতুন অবজেক্টটিকে আলাদা করতে "কমিট 2.1" এর কমিট মেসেজ ব্যবহার করুন:

একটি নতুন প্রতিশ্রুতি তৈরি করা হচ্ছে (সূত্র: https://youtu.be/ozA1V00GIT8)


কেন "কমিট 2" এবং "কমিট 2.1" আলাদা? এমনকি যদি আমরা একই প্রতিশ্রুতি বার্তা ব্যবহার করে, এবং যদিও তারা নির্দেশ করে একই গাছ বস্তু ( 1.txt এবং 2.txt সমন্বিত রুট ফোল্ডারের), তাদের এখনও বিভিন্ন টাইমস্ট্যাম্প রয়েছে, কারণ সেগুলি বিভিন্ন সময়ে তৈরি করা হয়েছিল।


উপরের অঙ্কনে, আমি আপনাকে মনে করিয়ে দেওয়ার জন্য "কমিট 2" রেখেছি যে এটি এখনও গিটের অভ্যন্তরীণ অবজেক্ট ডাটাবেসে বিদ্যমান। "কমিট 2" এবং "কমিট 2.1" উভয়ই এখন "কমিট 1" নির্দেশ করে, কিন্তু শুধুমাত্র "কমিট 2.1" HEAD থেকে পৌঁছানো যায়।

গিট রিসেট --মিশ্রিত

এটি এমনকি পিছিয়ে যাওয়ার এবং আরও পূর্বাবস্থায় যাওয়ার সময়। এইবার, git reset --mixed HEAD~1 (দ্রষ্টব্য: --mixed হল git reset জন্য ডিফল্ট সুইচ)।


এই কমান্ডটি git reset --soft HEAD~1 । অর্থাত্ HEAD এখন যেটি নির্দেশ করছে তার পয়েন্টার নেয়, যা main শাখা, এবং এটিকে HEAD~1 এ সেট করে, আমাদের উদাহরণে - "কমিট 1"।

`git reset --mixed`-এর প্রথম ধাপটি `git reset --soft` (সূত্র: https://youtu.be/ozA1V00GIT8) এর মতোই।


এরপরে, গিট আরও এগিয়ে যায়, কার্যকরভাবে আমরা সূচীতে করা পরিবর্তনগুলিকে পূর্বাবস্থায় ফিরিয়ে আনে। অর্থাৎ, সূচক পরিবর্তন করা যাতে এটি বর্তমান HEAD এর সাথে মিলে যায়, প্রথম ধাপে সেট করার পরে নতুন HEAD


যদি আমরা git reset --mixed HEAD~1 , এর মানে হল HEAD HEAD~1 ("কমিট 1") এ সেট করা হবে, এবং তারপর গিট "কমিট 1" এর অবস্থার সাথে সূচকের সাথে মিলবে — এই ক্ষেত্রে, এটি মানে 2.txt আর সূচকের অংশ হবে না।

'গিট রিসেট --মিক্সড'-এর দ্বিতীয় ধাপ হল নতুন 'HEAD'-এর সাথে সূচী মেলানো (সূত্র: https://youtu.be/ozA1V00GIT8)


মূল "কমিট 2" এর অবস্থার সাথে একটি নতুন প্রতিশ্রুতি তৈরি করার সময় এসেছে৷ এইবার আমাদের এটি তৈরি করার আগে আবার 2.txt স্টেজ করতে হবে:

"কমিট 2.2" তৈরি করা হচ্ছে (উৎস: https://youtu.be/ozA1V00GIT8)


গিট রিসেট -- হার্ড

চালিয়ে যান, আরও পূর্বাবস্থায় ফেরান!


এগিয়ে যান এবং git reset --hard HEAD~1


আবার, গিট --soft পর্যায় দিয়ে শুরু হয়, যা কিছু HEAD নির্দেশ করে ( main ), HEAD~1 ("Commit 1") এর দিকে সেটিং করে।

`গিট রিসেট --হার্ড` এর প্রথম ধাপটি `গিট রিসেট --সফট` এর মতোই (সূত্র: https://youtu.be/ozA1V00GIT8)


এ পর্যন্ত সব ঠিকই.


এর পরে, HEAD এর সাথে সূচকের সাথে মিল রেখে --mixed পর্যায়ে চলে যান। অর্থাৎ, গিট 2.txt এর স্টেজিং পূর্বাবস্থায় ফিরিয়ে আনে।

`git reset --hard`-এর দ্বিতীয় ধাপটি `git reset --mixed` (সূত্র: https://youtu.be/ozA1V00GIT8) এর মতোই।


এটা --hard পদক্ষেপের সময় যেখানে গিট আরও এগিয়ে যায় এবং সূচকের পর্যায়ের সাথে কাজের ডিরকে মেলে। এই ক্ষেত্রে, এর অর্থ হল ওয়ার্কিং ডির থেকে 2.txt মুছে ফেলা।

`গিট রিসেট --হার্ড`-এর তৃতীয় ধাপটি সূচকের সাথে কাজের ডির-এর অবস্থার সাথে মিলে যায় (সূত্র: https://youtu.be/ozA1V00GIT8)


(** দ্রষ্টব্য: এই নির্দিষ্ট ক্ষেত্রে, ফাইলটি আনট্র্যাক করা হয়েছে, তাই এটি ফাইল সিস্টেম থেকে মুছে ফেলা হবে না; যদিও git reset বোঝার জন্য এটি সত্যিই গুরুত্বপূর্ণ নয়)।


তাই গিটে একটি পরিবর্তন প্রবর্তন করতে, আপনার তিনটি ধাপ আছে। আপনি কাজের ডাইর, ইনডেক্স বা স্টেজিং এরিয়া পরিবর্তন করেন এবং তারপর আপনি সেই পরিবর্তনগুলির সাথে একটি নতুন স্ন্যাপশট করেন। এই পরিবর্তনগুলি পূর্বাবস্থায় ফেরাতে :


  • যদি আমরা git reset --soft ব্যবহার করি, তাহলে আমরা কমিট ধাপকে পূর্বাবস্থায় ফিরিয়ে আনব।


  • যদি আমরা git reset --mixed ব্যবহার করি, তাহলে আমরা স্টেজিং ধাপকে পূর্বাবস্থায় ফিরিয়ে আনব।


  • যদি আমরা git reset --hard ব্যবহার করি, তাহলে আমরা কাজের ডির-এ পরিবর্তনগুলি পূর্বাবস্থায় ফিরিয়ে আনব।

বাস্তব জীবনের দৃশ্যকল্প!

দৃশ্যপট 1

তাই একটি বাস্তব-জীবনের দৃশ্যে, একটি ফাইলে "আমি গিটকে ভালোবাসি" লিখুন ( love.txt ), যেমন আমরা সবাই গিটকে ভালোবাসি 😍। এগিয়ে যান, স্টেজ করুন এবং এটিও কমিট করুন:

"কমিট 2.3" তৈরি করা হচ্ছে (উৎস: https://youtu.be/ozA1V00GIT8)


ওহ, উফ!


আসলে, আমি চাইনি তুমি এটা কর।


আমি আসলে আপনাকে যা করতে চেয়েছিলাম তা হল এই ফাইলটিতে এটি করার আগে আরও কিছু প্রেমের শব্দ লিখুন।

আপনি কি করতে পারেন?


ঠিক আছে, এটি কাটিয়ে ওঠার একটি উপায় হ'ল git reset --mixed HEAD~1 ব্যবহার করা, আপনার নেওয়া কমিটিং এবং স্টেজিং অ্যাকশন উভয়কেই কার্যকরভাবে পূর্বাবস্থায় ফিরিয়ে আনা:

স্টেজিং এবং প্রতিশ্রুতিবদ্ধ পদক্ষেপগুলি পূর্বাবস্থায় ফেরানো (সূত্র: https://youtu.be/ozA1V00GIT8)


তাই আবার "কমিট 1" এর main পয়েন্ট, এবং love.txt আর সূচকের অংশ নয়। যাইহোক, ফাইলটি কর্মরত ডিরে রয়ে গেছে। আপনি এখন এগিয়ে যেতে পারেন, এবং এতে আরও সামগ্রী যোগ করতে পারেন:

আরও প্রেমের গান যোগ করা হচ্ছে (সূত্র: https://youtu.be/ozA1V00GIT8)


এগিয়ে যান, স্টেজ করুন এবং আপনার ফাইল কমিট করুন:

পছন্দসই অবস্থার সাথে নতুন প্রতিশ্রুতি তৈরি করা হচ্ছে (সূত্র: https://youtu.be/ozA1V00GIT8)


ভালো হয়েছে 👏🏻


আপনি "কমিট 2.4" এর এই পরিষ্কার, সুন্দর ইতিহাস পেয়েছেন "কমিট 1" এর দিকে নির্দেশ করে।


এখন আমাদের টুলবক্সে একটি নতুন টুল আছে, git reset 💪🏻

গিট রিসেট এখন আমাদের টুলবক্সে (সূত্র: https://youtu.be/ozA1V00GIT8)


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


নতুনদের জন্য, আমি সুপারিশ করছি শুধুমাত্র git reset ব্যবহার করার জন্য প্রায় যেকোনো সময় আপনি গিট এ পূর্বাবস্থায় ফেরাতে চান। একবার আপনি এটির সাথে স্বাচ্ছন্দ্য বোধ করলে, এটি অন্যান্য সরঞ্জামগুলিতে যাওয়ার সময়।

দৃশ্যকল্প #2

আসুন আরেকটি ঘটনা বিবেচনা করা যাক।


new.txt নামে একটি নতুন ফাইল তৈরি করুন; পর্যায় এবং প্রতিশ্রুতি:

`new.txt` এবং "কমিট 3" তৈরি করা হচ্ছে (সূত্র: https://youtu.be/ozA1V00GIT8)


উফ। আসলে, এটি একটি ভুল. আপনি main ছিলেন, এবং আমি চেয়েছিলাম আপনি একটি বৈশিষ্ট্য শাখায় এই প্রতিশ্রুতি তৈরি করুন। আমার খারাপ 😇


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


এই দৃশ্যের জন্য, বর্তমান অবস্থা এবং পছন্দসই অবস্থা দেখতে এরকম:

দৃশ্যকল্প #2: বর্তমান-বনাম-কাঙ্ক্ষিত রাজ্য (সূত্র: https://youtu.be/ozA1V00GIT8)


আপনি তিনটি পরিবর্তন লক্ষ্য করবেন:


  1. বর্তমান অবস্থায় "কমিট 3" (নীল এক), কিন্তু কাঙ্খিত অবস্থায় "কমিট 2.4" এর main পয়েন্ট।


  2. feature শাখা বর্তমান অবস্থায় বিদ্যমান নেই, তবুও এটি বিদ্যমান এবং পছন্দসই অবস্থায় "কমিট 3" নির্দেশ করে।


  3. HEAD বর্তমান অবস্থায় main দিকে নির্দেশ করে এবং কাঙ্খিত অবস্থায় feature দেখায়।


আপনি যদি এটি আঁকতে পারেন এবং আপনি কীভাবে git reset ব্যবহার করতে জানেন তবে আপনি অবশ্যই এই পরিস্থিতি থেকে নিজেকে বের করে আনতে পারেন।


তাই আবার, সবচেয়ে গুরুত্বপূর্ণ জিনিস একটি শ্বাস নিতে এবং এটি আঁকতে হয়.


উপরের অঙ্কনটি পর্যবেক্ষণ করে, আমরা কীভাবে বর্তমান অবস্থা থেকে কাঙ্ক্ষিত অবস্থায় যেতে পারি?


অবশ্যই কয়েকটি ভিন্ন উপায় আছে, তবে আমি প্রতিটি দৃশ্যের জন্য শুধুমাত্র একটি বিকল্প উপস্থাপন করব। পাশাপাশি অন্যান্য বিকল্পগুলির সাথে খেলতে বিনা দ্বিধায়।


আপনি git reset --soft HEAD~1 ব্যবহার করে শুরু করতে পারেন। এটি পূর্ববর্তী কমিট, "কমিট 2.4" এর দিকে নির্দেশ করার জন্য main সেট করবে:

'প্রধান' পরিবর্তন করা; "কমিট 3 অস্পষ্ট কারণ এটি এখনও সেখানে আছে, কেবল পৌঁছানো যায় না (সূত্র: https://youtu.be/ozA1V00GIT8)


বর্তমান-বনাম-কাঙ্খিত চিত্রটি আবার উঁকি দিয়ে, আপনি দেখতে পাচ্ছেন যে আপনার একটি নতুন শাখা দরকার, তাই না? আপনি এটির জন্য git switch -c feature বা git checkout -b feature ব্যবহার করতে পারেন (যা একই কাজ করে):

`ফিচার` শাখা তৈরি করা হচ্ছে (সূত্র: https://youtu.be/ozA1V00GIT8)


এই কমান্ডটি নতুন শাখার দিকে নির্দেশ করার জন্য HEAD আপডেট করে।


যেহেতু আপনি git reset --soft ব্যবহার করেছেন, আপনি সূচী পরিবর্তন করেননি, তাই এটিতে বর্তমানে ঠিক সেই অবস্থা রয়েছে যা আপনি করতে চান — কতটা সুবিধাজনক! আপনি কেবল feature শাখায় প্রতিশ্রুতিবদ্ধ করতে পারেন:

`ফিচার` শাখায় প্রতিশ্রুতিবদ্ধ (সূত্র: https://youtu.be/ozA1V00GIT8)


এবং আপনি পছন্দসই অবস্থায় পেয়েছেন 🎉

দৃশ্যকল্প #3

অতিরিক্ত ক্ষেত্রে আপনার জ্ঞান প্রয়োগ করতে প্রস্তুত?


love.txt এ কিছু পরিবর্তন যোগ করুন, এবং cool.txt নামে একটি নতুন ফাইল তৈরি করুন। তাদের স্টেজ করুন এবং প্রতিশ্রুতি দিন:

"কমিট 4" তৈরি করা হচ্ছে (উৎস: https://youtu.be/ozA1V00GIT8)


ওহ, ওহো, আসলে আমি চেয়েছিলাম আপনি দুটি আলাদা কমিট তৈরি করুন, প্রতিটি পরিবর্তনের সাথে একটি 🤦🏻

এই এক নিজেকে চেষ্টা করতে চান?


আপনি প্রতিশ্রুতিবদ্ধ এবং স্টেজিং পদক্ষেপগুলি পূর্বাবস্থায় ফিরিয়ে আনতে পারেন:

`git reset --mixed HEAD~1` ব্যবহার করে কমিট করা এবং স্টেজিং পূর্বাবস্থায় ফেরান (সূত্র: https://youtu.be/ozA1V00GIT8)


এই কমান্ড অনুসরণ করে, সূচীতে আর এই দুটি পরিবর্তন অন্তর্ভুক্ত করা হয় না, তবে তারা উভয়ই এখনও আপনার ফাইল সিস্টেমে রয়েছে। তাই এখন, যদি আপনি শুধুমাত্র love.txt স্টেজ করেন, তাহলে আপনি আলাদাভাবে এটি কমিট করতে পারেন, এবং তারপর cool.txt এর জন্য একই কাজ করতে পারেন:

আলাদাভাবে প্রতিশ্রুতি দেওয়া হচ্ছে (সূত্র: https://youtu.be/ozA1V00GIT8)


চমৎকার 😎

দৃশ্যকল্প #4

কিছু টেক্সট সহ একটি নতুন ফাইল ( new_file.txt ) তৈরি করুন এবং love.txt এ কিছু টেক্সট যোগ করুন। উভয় পরিবর্তনের পর্যায়, এবং তাদের প্রতিশ্রুতিবদ্ধ:

একটি নতুন প্রতিশ্রুতি (সূত্র: https://youtu.be/ozA1V00GIT8)


উফ 🙈🙈


তাই এই সময়, আমি এটি অন্য শাখায় হতে চেয়েছিলাম, কিন্তু একটি নতুন শাখা নয়, বরং একটি ইতিমধ্যে বিদ্যমান শাখা.


তো তুমি কি করতে পার?


আমি আপনাকে একটি ইঙ্গিত দেব. উত্তর সত্যিই সংক্ষিপ্ত এবং সত্যিই সহজ. আমরা প্রথমে কি করব?


না, reset নয়। আমরা আঁকি. এটি করা প্রথম জিনিস, কারণ এটি অন্য সবকিছুকে অনেক সহজ করে তুলবে। তাই এই বর্তমান অবস্থা:

'প্রধান'-এ নতুন প্রতিশ্রুতি নীল দেখা যাচ্ছে (সূত্র: https://youtu.be/ozA1V00GIT8)


আর কাঙ্খিত রাষ্ট্র?

আমরা চাই "নীল" প্রতিশ্রুতি অন্য একটি, `বিদ্যমান` শাখায় থাকুক (উৎস: https://youtu.be/ozA1V00GIT8)


আপনি কিভাবে বর্তমান অবস্থা থেকে কাঙ্ক্ষিত অবস্থায় পেতে পারেন, সবচেয়ে সহজ হবে কি?


সুতরাং একটি উপায় হল git reset ব্যবহার করা যেমন আপনি আগে করেছিলেন, তবে আরেকটি উপায় আছে যা আমি চাই আপনি চেষ্টা করুন।


প্রথমে, existing শাখায় নির্দেশ করতে HEAD সরান:

`বিদ্যমান` শাখায় যান (উৎস: https://youtu.be/ozA1V00GIT8)


স্বজ্ঞাতভাবে, আপনি যা করতে চান তা হল নীল প্রতিশ্রুতিতে প্রবর্তিত পরিবর্তনগুলি গ্রহণ করুন এবং existing শাখার উপরে এই পরিবর্তনগুলি ("কপি-পেস্ট") প্রয়োগ করুন। এবং গিট শুধু যে জন্য একটি টুল আছে.


এই কমিট এবং এর প্যারেন্ট কমিটের মধ্যে প্রবর্তিত পরিবর্তনগুলি নিতে এবং শুধুমাত্র সক্রিয় শাখায় এই পরিবর্তনগুলি প্রয়োগ করতে গিটকে জিজ্ঞাসা করতে, আপনি git cherry-pick ব্যবহার করতে পারেন। এই কমান্ডটি নির্দিষ্ট রিভিশনে প্রবর্তিত পরিবর্তনগুলি গ্রহণ করে এবং সেগুলি সক্রিয় কমিটে প্রয়োগ করে।


এটি একটি নতুন কমিট অবজেক্টও তৈরি করে এবং এই নতুন অবজেক্টের দিকে নির্দেশ করতে সক্রিয় শাখা আপডেট করে।

`গিট চেরি-পিক` ব্যবহার করা হচ্ছে (উৎস: https://youtu.be/ozA1V00GIT8)


উপরের উদাহরণে, আমি তৈরি করা কমিটের SHA-1 শনাক্তকারী নির্দিষ্ট করেছি, কিন্তু আপনি git cherry-pick main ব্যবহার করতে পারেন, কারণ যে প্রতিশ্রুতিটির পরিবর্তনগুলি আমরা প্রয়োগ করছি সেটি একটি main নির্দেশ করছে।


কিন্তু আমরা চাই না এই পরিবর্তনগুলো main শাখায় থাকুক। git cherry-pick শুধুমাত্র existing শাখায় পরিবর্তনগুলি প্রয়োগ করেছে। কিভাবে আপনি main থেকে তাদের সরাতে পারেন?


একটি উপায় হল main এ ফিরে switch এবং তারপর git reset --hard HEAD~1 :

'প্রধান' রিসেট করা হচ্ছে (উৎস: https://youtu.be/ozA1V00GIT8)


তুমি এটি করেছিলে! 💪🏻


উল্লেখ্য যে git cherry-pick প্রকৃতপক্ষে নির্দিষ্ট কমিট এবং এর প্যারেন্টের মধ্যে পার্থক্য গণনা করে এবং তারপরে তাদের সক্রিয় প্রতিশ্রুতিতে প্রয়োগ করে। এর মানে হল যে কখনও কখনও, গিট সেই পরিবর্তনগুলি প্রয়োগ করতে সক্ষম হবে না কারণ আপনি একটি দ্বন্দ্ব পেতে পারেন, তবে এটি অন্য পোস্টের জন্য একটি বিষয়।


এছাড়াও, মনে রাখবেন যে আপনি গিটকে যেকোন কমিটে প্রবর্তিত পরিবর্তনগুলিকে cherry-pick করতে বলতে পারেন, শুধুমাত্র একটি শাখা দ্বারা উল্লেখিত কমিট নয়।


আমরা একটি নতুন টুল অর্জন করেছি, তাই আমাদের বেল্টের নিচে git cherry-pick এবং git reset আছে।

দৃশ্যকল্প #5

ঠিক আছে, তাই অন্য দিন, অন্য রেপো, অন্য সমস্যা।


একটি প্রতিশ্রুতি তৈরি করুন:

আরেকটি প্রতিশ্রুতি (সূত্র: https://youtu.be/ozA1V00GIT8)


এবং এটি দূরবর্তী সার্ভারে push :

(সূত্র: https://youtu.be/ozA1V00GIT8)


উম, উফ 😓…


আমি শুধু কিছু লক্ষ্য করেছি. সেখানে একটি টাইপো আছে. আমি লিখেছিলাম This is more tezt এর পরিবর্তে This is more text । উফফফ তাহলে এখন বড় সমস্যা কি? আমি ed push , যার মানে অন্য কেউ ইতিমধ্যেই এই পরিবর্তন pull হতে পারে.


যদি আমি git reset ব্যবহার করে সেই পরিবর্তনগুলিকে ওভাররাইড করি, যেমনটি আমরা এখন পর্যন্ত করেছি, আমাদের আলাদা ইতিহাস থাকবে এবং সমস্ত নরক ভেঙে যেতে পারে। আপনি রেপোর আপনার নিজের অনুলিপিটি যতক্ষণ চান ততক্ষণ পুনরায় লিখতে পারেন যতক্ষণ না আপনি এটিকে push


একবার আপনি পরিবর্তনটি push , আপনাকে অবশ্যই নিশ্চিত হতে হবে যে আপনি যদি ইতিহাস পুনর্লিখন করতে যাচ্ছেন তবে অন্য কেউ সেই পরিবর্তনগুলি নিয়ে আসেনি।


বিকল্পভাবে, আপনি git revert নামে আরেকটি টুল ব্যবহার করতে পারেন। এই কমান্ডটি আপনি যে প্রতিশ্রুতি প্রদান করছেন তা গ্রহণ করে এবং এর প্যারেন্ট কমিট থেকে ডিফ গণনা করে, ঠিক যেমন git cherry-pick , কিন্তু এই সময়, এটি বিপরীত পরিবর্তনগুলি গণনা করে।


সুতরাং যদি নির্দিষ্ট কমিটে আপনি একটি লাইন যোগ করেন, বিপরীতটি লাইনটি মুছে ফেলবে এবং এর বিপরীতে।

পরিবর্তনগুলি পূর্বাবস্থায় ফেরাতে `গিট রিভার্ট` ব্যবহার করে (সূত্র: https://youtu.be/ozA1V00GIT8)


git revert একটি নতুন কমিট অবজেক্ট তৈরি করেছে, যার মানে এটি ইতিহাসের একটি সংযোজন। git revert ব্যবহার করে, আপনি ইতিহাস পুনর্লিখন করেননি। আপনি আপনার অতীতের ভুল স্বীকার করেছেন, এবং এই প্রতিশ্রুতি হল একটি স্বীকৃতি যে আপনি একটি ভুল করেছেন এবং এখন আপনি এটি ঠিক করেছেন।


কেউ কেউ বলবেন এটি আরও পরিণত উপায়। কেউ কেউ বলবে যে এটি এতটা পরিষ্কার ইতিহাস নয় যতটা আপনি পাবেন যদি আপনি পূর্ববর্তী প্রতিশ্রুতিটি পুনরায় লেখার জন্য git reset ব্যবহার করেন। কিন্তু ইতিহাস পুনর্লিখন এড়াতে এটি একটি উপায়।


আপনি এখন টাইপো ঠিক করতে পারেন এবং আবার কমিট করতে পারেন:

পরিবর্তনগুলি পুনরায় করা হচ্ছে (সূত্র: https://youtu.be/ozA1V00GIT8)


আপনার টুলবক্স এখন একটি নতুন চকচকে টুল দিয়ে লোড হয়েছে, revert :

আমাদের টুলবক্স (সূত্র: https://youtu.be/ozA1V00GIT8)


দৃশ্যকল্প #6

কিছু কাজ সম্পন্ন করুন, কিছু কোড লিখুন এবং এটি love.txt এ যোগ করুন। এই পরিবর্তনটি মঞ্চস্থ করুন, এবং এটি প্রতিশ্রুতিবদ্ধ করুন:

আরেকটি প্রতিশ্রুতি (সূত্র: https://youtu.be/ozA1V00GIT8)


আমি আমার মেশিনে একই কাজ করেছি, এবং আমি পূর্ববর্তী কমান্ডগুলিতে স্ক্রোল করার জন্য আমার কীবোর্ডে Up তীর কীটি ব্যবহার করেছি, এবং তারপরে আমি Enter , এবং... বাহ।


উফফফ

আমি কি শুধু 'গিট রিসেট -- হার্ড' করেছি? (সূত্র: https://youtu.be/ozA1V00GIT8)


আমি কি শুধু git reset --hard ব্যবহার করেছি? 😨


আসলে কি হয়েছিল? গিট পয়েন্টারটিকে HEAD~1 এ নিয়ে গেছে, তাই আমার সমস্ত মূল্যবান কাজের সাথে শেষ প্রতিশ্রুতিটি বর্তমান ইতিহাস থেকে পৌঁছানো সম্ভব নয়। গিট স্টেজিং এরিয়া থেকে সমস্ত পরিবর্তন আনস্টেজ করেছে, এবং তারপর স্টেজিং এরিয়ার অবস্থার সাথে ওয়ার্কিং ডিরকে মেলেছে।


অর্থাৎ, সবকিছু মিলে এই রাজ্যে যেখানে আমার কাজ… চলে গেছে।


পাগল আউট সময়. বিব্রতকর

কিন্তু, সত্যিই, ভয় পাওয়ার কারণ আছে কি? সত্যিই না... আমরা স্বচ্ছন্দ মানুষ। আমরা কি করি? ভাল, স্বজ্ঞাতভাবে, প্রতিশ্রুতি কি সত্যিই, সত্যিই চলে গেছে? না। কেন নয়? এটি এখনও গিটের অভ্যন্তরীণ ডাটাবেসের ভিতরে বিদ্যমান।


যদি আমি কেবল জানতাম যে এটি কোথায়, আমি SHA-1 মানটি জানতাম যা এই প্রতিশ্রুতিটিকে চিহ্নিত করে, আমরা এটি পুনরুদ্ধার করতে পারি। আমি এমনকি পূর্বাবস্থাকে পূর্বাবস্থায় ফিরিয়ে আনতে পারি এবং এই প্রতিশ্রুতিতে পুনরায় reset


সুতরাং আমার এখানে সত্যিই যে জিনিসটি দরকার তা হল "মুছে ফেলা" কমিটের SHA-1।


তাই প্রশ্ন হল, আমি কিভাবে এটি খুঁজে পেতে পারি? git log দরকারী হবে?


সত্যিই ভাল না. git log HEAD এ যাবে, যা main এর দিকে নির্দেশ করে, যা আমরা যে কমিট খুঁজছি তার প্যারেন্ট কমিটকে নির্দেশ করে। তারপর, git log প্যারেন্ট চেইনের মাধ্যমে ফিরে আসবে, যা আমার মূল্যবান কাজের সাথে প্রতিশ্রুতি অন্তর্ভুক্ত করে না।

`গিট লগ` এই ক্ষেত্রে সাহায্য করে না (সূত্র: https://youtu.be/ozA1V00GIT8)


সৌভাগ্যক্রমে, গিট তৈরি করা খুব স্মার্ট লোকেরা আমাদের জন্য একটি ব্যাকআপ প্ল্যান তৈরি করেছে এবং এটিকে বলা হয় reflog


আপনি গিট এর সাথে কাজ করার সময়, আপনি যখনই HEAD পরিবর্তন করেন, যা আপনি git reset ব্যবহার করে করতে পারেন, তবে অন্যান্য কমান্ড যেমন git switch বা git checkout , গিট reflog একটি এন্ট্রি যোগ করে।


`git reflog` আমাদের দেখায় যে `HEAD` কোথায় ছিল (সূত্র: https://youtu.be/ozA1V00GIT8)


আমরা আমাদের প্রতিশ্রুতি খুঁজে পেয়েছি! এটি 0fb929e দিয়ে শুরু হয়।


আমরা এটির সাথে এর "ডাকনাম" - HEAD@{1} দ্বারাও সম্পর্কযুক্ত হতে পারি। তাই যেমন গিট HEAD এর প্রথম অভিভাবকের কাছে যাওয়ার জন্য HEAD~1 ব্যবহার করে এবং HEAD এর দ্বিতীয় অভিভাবককে বোঝাতে HEAD~2 ব্যবহার করে এবং আরও অনেক কিছু, গিট HEAD এর প্রথম reflog অভিভাবককে বোঝাতে HEAD@{1} ব্যবহার করে, যেখানে HEAD পূর্ববর্তী ধাপে নির্দেশ করেছে।


আমরা git rev-parse এর মান দেখাতেও বলতে পারি:

(সূত্র: https://youtu.be/ozA1V00GIT8)


reflog দেখার আরেকটি উপায় হল git log -g ব্যবহার করে, যা git log আসলে reflog বিবেচনা করতে বলে:

`git log -g` এর আউটপুট (সূত্র: https://youtu.be/ozA1V00GIT8)


আমরা উপরে দেখতে পাচ্ছি যে reflog , ঠিক যেমন HEAD , main দিকে নির্দেশ করে, যা "কমিট 2" নির্দেশ করে। কিন্তু reflog এ সেই এন্ট্রির অভিভাবক "কমিট 3"-এর দিকে নির্দেশ করে।


তাই "কমিট 3" এ ফিরে যেতে, আপনি শুধু git reset --hard HEAD@{1} (বা "কমিট 3" এর SHA-1 মান) ব্যবহার করতে পারেন:

(সূত্র: https://youtu.be/ozA1V00GIT8)


এবং এখন, যদি আমরা git log :

আমাদের ইতিহাস ফিরে এসেছে!!! (সূত্র: https://youtu.be/ozA1V00GIT8)


আমরা দিন সংরক্ষণ! 🎉👏🏻


আমি আবার এই কমান্ড ব্যবহার করলে কি হবে? এবং git commit --reset HEAD@{1} ? গিট শেষ reset আগে যেখানে HEAD নির্দেশ করছিল সেখানে HEAD সেট করবে, যার অর্থ "কমিট 2"। আমরা সারাদিন চলতে পারি:

(সূত্র: https://youtu.be/ozA1V00GIT8)


এখন আমাদের টুলবক্সের দিকে তাকানো, এটি এমন সরঞ্জামগুলির সাথে লোড করা হয়েছে যা আপনাকে অনেকগুলি ক্ষেত্রে সমাধান করতে সাহায্য করতে পারে যেখানে গিট-এ কিছু ভুল হয়:

আমাদের টুলবক্স বেশ বিস্তৃত! (সূত্র: https://youtu.be/ozA1V00GIT8)


এই সরঞ্জামগুলির সাহায্যে, আপনি এখন আরও ভালভাবে বুঝতে পারবেন কিভাবে গিট কাজ করে। আরও অনেক টুল রয়েছে যা আপনাকে ইতিহাসকে বিশেষভাবে পুনঃলিখন করার অনুমতি দেবে, git rebase ), কিন্তু আপনি ইতিমধ্যে এই পোস্টে অনেক কিছু শিখেছেন। ভবিষ্যতের পোস্টগুলিতে, আমি git rebase ডুব দেব।


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

গিট সম্পর্কে আরও জানুন

আমি এই পোস্টের বিষয়বস্তু কভার একটি লাইভ বক্তৃতা দিয়েছি. আপনি যদি একটি ভিডিও পছন্দ করেন (বা পড়ার পাশাপাশি এটি দেখতে চান) - আপনি এটি খুঁজে পেতে পারেন .


সাধারণভাবে, আমার ইউটিউব চ্যানেল গিট এবং এর অভ্যন্তরীণ অনেক দিক কভার করে; আপনি স্বাগত জানাই এটা দেখ (শ্লেষের উদ্দেশ্যে 😇)

লেখক সম্পর্কে

ওমের রোজেনবাউম এর CTO এবং সহ-প্রতিষ্ঠাতা সাঁতার কাটা , একটি devtool যা ডেভেলপারদের এবং তাদের দলগুলিকে আপ-টু-ডেট অভ্যন্তরীণ ডকুমেন্টেশন সহ তাদের কোডবেস সম্পর্কে জ্ঞান পরিচালনা করতে সহায়তা করে। ওমের চেক পয়েন্ট সিকিউরিটি একাডেমির প্রতিষ্ঠাতা এবং আইটিসি-তে সাইবার সিকিউরিটি লিড ছিলেন, একটি শিক্ষা প্রতিষ্ঠান যা প্রযুক্তিতে ক্যারিয়ার গড়ে তোলার জন্য প্রতিভাবান পেশাদারদের প্রশিক্ষণ দেয়।


ওমের তেল আবিব বিশ্ববিদ্যালয় থেকে ভাষাবিজ্ঞানে এমএ করেছেন এবং তিনি এর স্রষ্টা সংক্ষিপ্ত ইউটিউব চ্যানেল .


এখানে প্রথম প্রকাশিত