গিট চেরি পিক বনাম রিবাজে


119

আমি সম্প্রতি গিটের সাথে কাজ শুরু করেছি।

ওভার যাওয়া গীত বই অনলাইন আমি "রি-বেসের ফলে গীত" বিভাগের মধ্যে নিম্নলিখিত পাওয়া যায়নি:

রিবেস কমান্ডের সাহায্যে আপনি একটি শাখায় প্রতিশ্রুতিবদ্ধ সমস্ত পরিবর্তন নিতে পারেন এবং সেগুলি অন্য একটিতে পুনরায় খেলতে পারেন।

(এর থেকে উদ্ধৃত: http://git-scm.com/book/en/Git-Branching- রিবেসিং )

আমি ভেবেছিলাম এটি গিট চেরি-পিকের সঠিক সংজ্ঞা (বর্তমানে পরীক্ষা করা শাখায় কমিট বা কমিটের বস্তুর সেট প্রয়োগ করুন)।

এই দুটির মধ্যে পার্থক্য কী ?

উত্তর:


165

যেহেতু সময়টি git cherry-pickএকাধিক কমিট প্রয়োগ করতে সক্ষম হতে শিখেছে, তাই পার্থক্যটি কিছুটা বাস্তব হয়ে উঠেছে, তবে এটিকে অভিজাত বিবর্তন বলা যায় ;-)

সত্য পার্থক্য উভয় সরঞ্জাম তৈরি করার মূল উদ্দেশ্যতে নিহিত:

  • git rebaseএর কাজটি হ'ল কোনও বিকাশকারী তাদের প্রাইভেট ভাণ্ডারগুলিতে কিছু প্রবাহ শাখার সংস্করণ X এর বিপরীতে তৈরি করে একই শাখার (ওয়াই> এক্স) সংস্করণ ওয়াইয়ের এক ধারাবাহিক পরিবর্তনকে ফরওয়ার্ড-পোর্ট করা। এটি কার্যকরভাবে সেই সিরিজের কমিটগুলির ভিত্তি পরিবর্তন করে, তাই "রিবাজিং"।

    (এটি বিকাশকারীকে যেকোন স্বেচ্ছাসেবী প্রতিশ্রুতিবদ্ধতায় একের পর এক কমিটের প্রতিশ্রুতি প্রতিস্থাপনের অনুমতি দেয়, তবে এটি কম সুস্পষ্ট ব্যবহারের নয়))

  • git cherry-pickউন্নয়নের এক লাইন থেকে অন্য লাইনে একটি আকর্ষণীয় প্রতিশ্রুতি আনার জন্য। একটি ক্লাসিক উদাহরণ অস্থিতিশীল উন্নয়ন শাখায় করা একটি সুরক্ষা ফিক্সকে একটি স্থিতিশীল (রক্ষণাবেক্ষণ) শাখায় ব্যাকপোর্ট করা, যেখানে mergeকোনও অর্থ হয় না, কারণ এটি পুরোপুরি অযাচিত পরিবর্তন আনবে।

    এটির প্রথম উপস্থিতির পরে, git cherry-pickএকযোগে একাধিক কমিট বেছে নিতে সক্ষম হয়েছে।

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

ব্যবহার করে git rebaseআলোচিত হওয়ার উদাহরণটি আরও ব্যাখ্যা করতে আপডেট করুন

এই পরিস্থিতি বিবেচনা করে,
রিবাইজ করার আগে রেপুর একটি অবস্থা
বইটি বলেছে:

তবে, আরও একটি উপায় আছে: আপনি সি 3-এ চালু হওয়া প্যাচটি নিতে পারেন এবং সি 4 এর শীর্ষে এটি পুনরায় প্রয়োগ করতে পারেন। গিটকে একে রিবিসিং বলা হয়। রিবেস কমান্ডের সাহায্যে আপনি একটি শাখায় প্রতিশ্রুতিবদ্ধ সমস্ত পরিবর্তন নিতে পারেন এবং সেগুলি অন্য একটিতে প্রয়োগ করতে পারেন।

এই উদাহরণে, আপনি নিম্নলিখিত চালাতে চান:

$ git checkout experiment
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: added staged command

"ধরা" এখানে এই উদাহরণস্বরূপ, "পরীক্ষা" শাখাটি (প্রত্যাখ্যানের বিষয়) মূলত "মাস্টার" শাখাটি বন্ধ করে দেওয়া হয়েছিল, এবং তাই এটি C2 এর মাধ্যমে C0 এর সাথে ভাগ করে - কার্যকরভাবে "পরীক্ষা" হয় " এর উপরে সি 2 প্লাস কমিট করুন "সহ এবং অন্তর্ভুক্ত করুন"। (এটি সবচেয়ে সহজ সম্ভাব্য কেস; অবশ্যই, "পরীক্ষা-নিরীক্ষায়" এর মূল বেসের শীর্ষে কয়েক ডজন কমিট থাকতে পারে))

এখন "মাস্টার" git rebaseএর বর্তমান টিপটিতে "পরীক্ষা" পুনরায় চালু করতে বলা হয় এবং এটি git rebaseএরকম হয়:

  1. রান git merge-baseকি গত উভয় "পরীক্ষা" এবং "মাস্টার" (, বেষ্টনী বিন্দু কি অন্য কথায়) দ্বারা ভাগ করা কমিট দেখতে। এটি সি 2
  2. ডাইভার্সন পয়েন্ট থেকে করা সমস্ত কমিটগুলি সরিয়ে দেয়; আমাদের খেলনা উদাহরণে, এটি কেবল সি 3।
  3. "মাস্টার" এর পরামর্শের দিকে ইঙ্গিত করতে হেডকে রিওয়াইন্ডস (যা "অপারেশনটি চালুর আগে" পরীক্ষার "টিপ প্রতিশ্রুতি দেখায়) - আমরা এটিতে প্রত্যাখ্যান করছি।
  4. সংরক্ষণ করা প্রতিটি কমিট (যেমনটি দিয়ে থাকে git apply) যাতে করে তা প্রয়োগ করার চেষ্টা করে । আমাদের খেলনা উদাহরণে এটি কেবল একটি প্রতিশ্রুতিবদ্ধ, সি 3। যাক এর অ্যাপ্লিকেশনটি একটি প্রতিশ্রুতিবদ্ধ C3 'উত্পন্ন করবে।
  5. যদি সবকিছু ঠিকঠাক হয় তবে "পরীক্ষামূলক" রেফারেন্সটি সর্বশেষ সংরক্ষিত প্রতিশ্রুতি (আমাদের ক্ষেত্রে সি 3) প্রয়োগ করার ফলে প্রতিশ্রুতিবদ্ধ প্রতি নির্দেশ করতে আপডেট করা হয়।

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

আবার, প্রযুক্তিগতভাবে আপনি বলতে পারেন যে git rebaseএখানে "মাস্টার" থেকে কিছু কমিট অন্তর্ভুক্ত করা হয়েছে, এবং এটি একেবারে সঠিক।


2
ধন্যবাদ। আপনি এখানে কী বলতে চাইছেন তা আমি এখনও পুরোপুরি বুঝতে পারি নি। বইটিতে, উদাহরণটি দেওয়া হয়েছে যে রিবেস অন্য শাখা থেকে টিপস কমিট করার একটি ধারাবাহিক প্রয়োগ করে, যখন আপনি বলে যে এটি "একই শাখা" থেকে এসেছে। অথবা সম্ভবত এটি কয়েকটি ক্ষেত্রে কাজ করে?
লাইজারিক-অ্যাসিড

1
আমার উত্তর আপডেট করে বিষয়টি ব্যাখ্যা করার চেষ্টা করেছি।
কোস্টিক্স

98

চেরি-পিকের সাহায্যে মূল কমিট / শাখা প্রায় লাঠিপেটে যায় এবং নতুন কমিট তৈরি হয়। রিবেস সহ, পুরো শাখাটি শাখাটি দিয়ে পুনরায় খেলানো কমিটগুলির দিকে ইশারা করে সরানো হয়।

ধরুন আপনি এটি দিয়ে শুরু করেছেন:

      A---B---C topic
     /
D---E---F---G master

রি-বেসের ফলে:

$ git rebase master topic

তুমি পাও:

              A'--B'--C' topic
             /
D---E---F---G master

চেরি-বাছাই:

$ git checkout master -b topic_new
$ git cherry-pick A^..C

তুমি পাও:

      A---B---C topic
     /
D---E---F---G master
             \
              A'--B'--C' topic_new

গিট সম্পর্কে আরও তথ্যের জন্য এই বইটির বেশিরভাগ অংশ রয়েছে (http://git-scm.com/book)


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

যদি এর পরিবর্তে কোনও ইন্টারেক্টিভ রিবেস করা হয়, এক বা একাধিক প্রতিশ্রুতি রেখে, আপনার শেষে কোন শাখা থাকবে? যদি এটি কেবল topicউপরের দিকে পুনর্বাসিত করা masterহয় তবে এতে বাম-আউট কমিটস থাকে না তবে তারা কোন শাখার অংশ হবে?
অ্যান্থনি

আমি আরও একটি জিনিস যুক্ত করতে চাই: আপনি git checkout topicএবং তারপর git reset --hard C'চেরি বাছাইয়ের পরে, তবে আপনাকে রিবাইজ করার পরে একই ফলাফল পাওয়া যাবে। রিবিজিংয়ের উপর চেরি পিকিং ব্যবহার করে আমি নিজেকে একত্রীকরণের দ্বন্দ্ব থেকে রক্ষা পেয়েছি, কারণ সাধারণ পূর্বপুরুষ ফিরে এসেছিলেন।
দুঃখিতমিসিজ্যাকসন

@ অ্যান্থনি - স্ট্যাকওভারফ্লো. com/ প্রশ্নগুলি / ১১৮৩৩৯৪৮/২ : যতদূর আমি বুঝতে পারি তারা হারিয়ে গেছে। আমি কোনও gitগুরু নই তবে আমার rebase/ আপনার বুঝতে সমস্যা হয়েছে এমন cherry-pickসমস্ত বিবরণে এটি চলছে git
thoni56

1
আপনার গ্রাফগুলি ভালের চেয়ে বেশি ক্ষতি করে কারণ সেগুলি কার্যত অভিন্ন। পার্থক্যটি হ'ল তৈরি করা শাখা git checkout -b, যার কোনও সম্পর্ক নেই git cherry-pick। একটি ভাল উপায় আপনি কি হবে "আপনি চালাতে বলার চেষ্টা করছি ব্যাখ্যা করার git rebaseউপর topicশাখা এবং এটি পাস master; আপনি চালাতে git cherry-pickউপর masterশাখা এবং এটি (থেকে করে) পাস topic। "
ররি ও'কেনে

14

চেরি-বাছাই স্বতন্ত্র কমিটের জন্য কাজ করে

আপনি যখন এটি ছাড় করেন তখন ইতিহাসের সমস্ত কমান্ডগুলি শাখার প্রধানের কাছে অনুপস্থিত থাকে যা সেখানে অনুপস্থিত রয়েছে।


ধন্যবাদ। আপনি কি জানেন যে এটি কভারগুলির আওতায় একই কাজ করে? ("প্যাচ" ফাইলগুলিতে তাদের মধ্যবর্তী আউটপুট সংরক্ষণ করুন)।
লিজেরজিক-অ্যাসিড

আফাক হ্যাঁ। এটি একের পর এক সমস্ত প্যাচ প্রয়োগ করে। এ কারণেই আপনাকে কখনও কখনও চালিয়ে যাওয়ার আগে পুনরায় মাঝখানে সংলগ্ন দ্বন্দ্বগুলি সমাধান করতে হয়।
ইল্টেম্পো

6
@ ইলতেম্পো, এটি কেবল গিটের পুরানো সংস্করণে পৃথক প্রতিশ্রুতিবদ্ধদের জন্য কাজ করেছে; বর্তমানে আপনি এর মতো কিছু করতে পারেন git cherry-pick foo~3..fooএবং গাছের শীর্ষস্থানীয় ব্যক্তিকে "foo" থেকে এক এক করে বাছাই করতে পারেন।
kostix

1
গিট-রিবেসে একই এপিআই ব্যবহার করা হয়েছে যেমন চেরি-পিকিং কোডবেজে, আইরিক-তে
বিকল্প

আমি মনে করি না যে তারা আসলে কভারগুলির নীচে একই রকম কাজ করে। আমি কয়েক হাজার কমিটকে মুক্তি দেওয়ার চেষ্টা করেছি এবং আমি মনে করি গিট একটি বিশাল মেলবক্স ফাইল তৈরি করে এবং তারপরে git amএটি চালিত হয়। যেখানে চেরি পিক কমিট দ্বারা প্রয়োগ করা হয় (সম্ভবত প্রতিটি প্যাচের জন্য একটি একক-বার্তা মেলবক্স তৈরি করে)। আমার রিবেস ব্যর্থ হচ্ছিল কারণ এটি তৈরি করা মেলবক্স ফাইলটি ড্রাইভের জায়গাগুলির বাইরে চলে গেছে, তবে একই সংশোধনী রেঞ্জের সাথে চেরি-পিক সফল হয়েছে (এবং দ্রুত চলেছে বলে মনে হচ্ছে)।
একমাত্র 18

11

একটি সংক্ষিপ্ত উত্তর:

  • গিট চেরি-পিক আরও "নিম্ন স্তরের"
  • যেমন এটি গিট রিবেস অনুকরণ করতে পারে

উপরে দেওয়া উত্তরগুলি ভাল, আমি কেবল তাদের আন্তঃসম্পর্ক প্রদর্শনের প্রয়াসে একটি উদাহরণ দিতে চেয়েছি।

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

নিম্নলিখিত খেলনা সংগ্রহস্থল দেওয়া:

$ git log --graph --decorate --all --oneline
* 558be99 (test_branch_1) Test commit #7
* 21883bb Test commit #6
| * 7254931 (HEAD -> master) Test commit #5
| * 79fd6cb Test commit #4
| * 48c9b78 Test commit #3
| * da8a50f Test commit #2
|/
* f2fa606 Test commit #1

বলুন, আমাদের মাস্টারে কিছু খুব গুরুত্বপূর্ণ পরিবর্তন হয়েছে (# 2 থেকে # 5 এর মাধ্যমে কমিট করে) যা আমরা আমাদের টেস্ট_ব্রঞ্চ_1 তে অন্তর্ভুক্ত করতে চাই। সাধারণত আমরা কেবল একটি শাখায় চলে যাই এবং "গিট রিবেস মাস্টার" করি। তবে আমরা ভান করে যাচ্ছি আমরা কেবল "গিট চেরি-পিক" দিয়ে সজ্জিত, আমরা এটি করি:

$ git checkout 7254931                # Switch to master (7254931 <-- master <-- HEAD)
$ git cherry-pick 21883bb^..558be99   # Apply a range of commits (first commit is included, hence "^")    

এই সমস্ত অপারেশনের পরে আমাদের প্রতিশ্রুতিবদ্ধ গ্রাফটি এর মতো দেখতে পাবেন:

* dd0d3b4 (HEAD) Test commit #7
* 8ccc132 Test commit #6
* 7254931 (master) Test commit #5
* 79fd6cb Test commit #4
* 48c9b78 Test commit #3
* da8a50f Test commit #2
| * 558be99 (test_branch_1) Test commit #7
| * 21883bb Test commit #6
|/
* f2fa606 Test commit #1

যেমন আমরা দেখতে পাচ্ছি, কমিট # 6 এবং # 7 725745 (মাস্টার একটি টিপ কমিট) এর বিপরীতে প্রয়োগ করা হয়েছিল। মাথা সরানো হয়েছিল এবং একটি প্রতিশ্রুতি নির্দেশ করে যা মূলত, একটি রিবেসড শাখার একটি টিপ। এখন আমাদের যা করা দরকার তা হল একটি পুরানো শাখা পয়েন্টার মুছুন এবং একটি নতুন তৈরি করুন:

$ git branch -D test_branch_1
$ git checkout -b test_branch_1 dd0d3b4

টেস্ট_ব্রঞ্চ_1 এখন সর্বশেষতম মাস্টার অবস্থান থেকে উদ্ভূত। সম্পন্ন!


তবে রিবাজে গিট চেরি-পিকের অনুকরণ করতে পারে?
945

যেহেতু cherry-pickকমিটস বিভিন্ন সীমা প্রয়োগ করতে সক্ষম, তাই আমি মনে করি, হ্যাঁ। যদিও এটি জিনিসগুলি করার কিছুটা অদ্ভুত উপায়, তবে কিছুই আপনার উপরে আপনার বৈশিষ্ট্য শাখায় চেরি-বাছাই করতে বাধা দেয় না master, তারপরে বৈশিষ্ট্যটি শাখাটি মুছুন এবং এটিকে আবার তৈরি করুন যাতে এটি ইঙ্গিত দেয় master। আপনি git rebaseএর ক্রম হিসাবে ভাবতে পারেন git cherry-pick feature_branch, git branch -d feature_branchএবং git branch feature_branch master
রাইস

7

এগুলি উভয়ই অন্যটির উপরের একটি শাখার কমিটগুলি পুনরায় লেখার জন্য আদেশ রয়েছে: "আপনার" (বর্তমানে যাচাই করা আছে HEAD) বা "তাদের" (শাখাটি কমান্ডের আর্গুমেন্ট হিসাবে পাস হয়েছে) - এই শাখার মধ্যে পার্থক্য রয়েছে বেস এই লেখা জন্য।

git rebaseএকটি সময় লাগে শুরুর কমিট এবং রিপ্লেতে আপনার পর আসামাত্রই করে তাহাদেরই (শুরুর কমিট)।

git cherry-pickকমিটের একটি সেট নেয় এবং তাদের কমিটগুলি আপনার (আপনার HEAD) পরে আসার সাথে সাথে পুনরায় প্রদর্শন করে

অন্য কথায়, দুটি কমান্ডগুলি হ'ল তাদের মূল আচরণে (তাদের বিবিধ পারফরম্যান্সের বৈশিষ্ট্যগুলি উপেক্ষা করা, কনভেনশনগুলি আহ্বান করা এবং উন্নয়নের বিকল্পগুলি), প্রতিসম : শাখা পরীক্ষা করা barএবং চালানো শাখাটিকে একই ইতিহাসে git rebase fooসেট করে যা barশাখা চেক আউট fooএবং রানিং git cherry-pick ..barসেট হবে foo(পরিবর্তনের fooপরে, এর পরিবর্তনের দ্বারা bar) পরিবর্তন করতে পারেন ।

নামকরণ অনুসারে, দুটি কমান্ডের মধ্যে পার্থক্য মনে রাখা যেতে পারে যে প্রত্যেকে তার বর্তমান শাখায় কী করে তা বর্ণনা করে : rebaseঅপরকে আপনার পরিবর্তনের জন্য নতুন ভিত্তি করে তোলে , অন্যদিকে cherry-pickঅন্য শাখা থেকে পরিবর্তনগুলি বেছে নিয়ে তাদের শীর্ষেHEAD রাখে আপনার (একটি সানডির উপরে চেরির মতো)।


1
আমি আপনার উত্তর ছাড়া আর কিছুই বুঝতে পারি না! এটি সংক্ষিপ্ত এবং অতিরিক্ত অতিরিক্ত শব্দ ছাড়াই নিখুঁত ধারণা তৈরি করে।
নিওক্সিক

4

উভয়ই খুব অনুরূপ কাজ করে; মূল ধারণাগত পার্থক্য হ'ল (সরল ভাষায়) যে:

  • রি-বেসের ফলে থেকে প্যাচসমূহ করে বর্তমান শাখা থেকে অন্য শাখায়

  • চেরি-বাছাই থেকে কপি করে অন্য শাখা থেকে বর্তমান শাখা

@ কেনি হো এর উত্তরের অনুরূপ চিত্রগুলি ব্যবহার :

এই প্রাথমিক অবস্থা দেওয়া:

A---B---C---D master
     \
      E---F---G topic

... এবং ধরে নিয়ে যে আপনি topicবর্তমান masterশাখার উপরে শাখাটি থেকে পুনরায় খেলতে চান তা আপনার কাছে দুটি বিকল্প রয়েছে:

  1. রি-বেসের ফলে ব্যবহার হচ্ছে: আপনিই প্রথম যেতে চাই topicকরে git checkout topic, এবং তারপর চালিয়ে শাখা সরানো git rebase master, উত্পাদক:

    A---B---C---D master
                 \
                  E'---F'---G' topic
    

    ফলাফল: আপনার বর্তমান শাখাটি topicপুনরায় সাজানো হয়েছিল (সরানো) এর উপরে master। শাখা আপডেট করা হয়েছে, যখন শাখা জায়গায় রয়ে।
    topicmaster

  2. চেরি-বাছুন ব্যবহার : আপনি প্রথম যেতে চাই masterকরে git checkout master, এবং তারপর চালিয়ে শাখা কপি git cherry-pick topic~3..topic(অথবা এবং, equivalently, git cherry-pick B..G), উৎপাদন:

    A---B---C---D---E'---F'---G' master
         \
          E---F---G topic
    

    ফলাফল: করে থেকে topicছিল কপি মধ্যে master। শাখা আপডেট করা হয়েছে, যখন শাখা জায়গায় রয়ে।
    mastertopic


অবশ্যই, এখানে আপনাকে স্পষ্টরূপে ব্যাপ্তি চিহ্ন ব্যবহার করে কমিটের ক্রম বাছাই করতে চেরি-পিকটি বলতে হয়েছিলfoo..bar । যদি আপনি কেবল শাখার নামটি পাশ করে দিয়ে থাকেন তবে এটি শাখার git cherry-pick topicডগায় কেবলমাত্র অঙ্গীকারটি গ্রহণ করতে পারত যার ফলস্বরূপ:

A---B---C---D---G' master
     \
      E---F---G topic
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.