কিভাবে এবং/অথবা কেন SVN চেয়ে Git ভাল মার্জ হয়?




version-control mercurial (5)

আমি কয়েকটি জায়গায় শুনেছি যে বিতরিত সংস্করণ নিয়ন্ত্রণ সিস্টেমগুলির আলোকে বিতরণের মূল কারণগুলির মধ্যে একটি হল SVN এর মতো ঐতিহ্যবাহী সরঞ্জামগুলির চেয়ে অনেক ভাল। এটি আসলে দুইটি সিস্টেমের কীভাবে অন্তর্নিহিত পার্থক্যের কারণে, বা গিট / মারকুয়ালিয়ালের মতো নির্দিষ্ট DVCS বাস্তবায়নের কারণে কেবলমাত্র SVN এর চেয়ে ক্লিভেরর মার্জিং অ্যালগরিদমগুলি আছে?


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

কিন্তু তারপর, হয়তো সেই ব্যক্তিদের জন্য একমাত্র সুবিধা যারা আলাদা আলাদা শাখা ব্যবহার করতে পারে (যদি আমি সঠিকভাবে মনে করি, আমাদের কেবলমাত্র একটি শাখা ছিল যা কোম্পানির উন্নয়নের জন্য ব্যবহৃত হয়েছিল যেখানে আমি SVN ব্যবহার করতাম)।


আমি গৃহীত উত্তর পড়া। এটা শুধু প্লেইন ভুল।

SVN মার্জিং একটি ব্যথা হতে পারে, এবং এটি গুরুতর হতে পারে। কিন্তু, এটি একটি মিনিটের জন্য আসলে কিভাবে কাজ করে তা উপেক্ষা করুন। GV যে SVN রাখে বা অর্জন করতে পারে এমন কোনও তথ্য নেই যা রাখা বা অর্জন করতে পারে না। আরো গুরুত্বপূর্ণ, সংস্করণ নিয়ন্ত্রণ পদ্ধতির আলাদা (কখনও কখনও আংশিক) কপি রাখার কারণে আপনার কাছে আরো প্রকৃত তথ্য সরবরাহ করার কোন কারণ নেই। দুই কাঠামো সম্পূর্ণ সমতুল্য।

আপনি "কিছু চতুর জিনিস" করতে চান অনুমান করুন গিট "এ ভাল"। এবং আপনি জিনিস SVN মধ্যে চেক করা হয়।

আপনার এসভিএনকে সমতুল্য গিট ফর্ম রূপে রূপান্তর করুন, এটি গিটে করুন এবং তারপরে ফলাফলটি চেক করুন, সম্ভবত একাধিক কমিটগুলি, কিছু অতিরিক্ত শাখার ব্যবহার করে। আপনি যদি কোন GV সমস্যার মধ্যে একটি SVN সমস্যাটি চালু করার একটি স্বয়ংক্রিয় উপায় কল্পনা করতে পারেন তবে Git এর মৌলিক সুবিধা নেই।

দিনের শেষে, কোন সংস্করণ নিয়ন্ত্রণ সিস্টেম আমাকে দেওয়া হবে

1. Generate a set of objects at a given branch/revision.
2. Provide the difference between a parent child branch/revisions.

উপরন্তু, এটি মার্জ করার জন্য এটি দরকারী (বা সমালোচনামূলক) জানাও

3. The set of changes have been merged into a given branch/revision.

Mercurial , Git এবং Subversion (এখন natively, পূর্বে svnmerge.py ব্যবহার করে) সমস্ত তথ্য তিনটি টুকরা সরবরাহ করতে পারে। ডিভিসি এর সাথে মৌলিকভাবে কিছুটা ভালোভাবে প্রকাশ করার জন্য, অনুগ্রহ করে কিছু চতুর্থাংশ তথ্য যা জিটি / মারকুরিয়াল / DVC তে পাওয়া যায় তা এসভিএন / কেন্দ্রীভূত ভিসি-তে উপলব্ধ নয়।

বলার অপেক্ষা রাখে না তারা ভাল সরঞ্জাম না!


জিভি কন্টেন্ট পরিবর্তন ট্র্যাক যখন SVN ফাইল ট্র্যাক। কোডটির একটি ব্লক ট্র্যাক করার জন্য এটি যথেষ্ট চতুর, যা এক ক্লাস / ফাইল থেকে অন্যটিতে পুনঃনির্দেশিত হয়েছিল। তারা আপনার উৎস ট্র্যাকিং দুটি সম্পূর্ণ ভিন্ন পন্থা ব্যবহার করুন।

আমি এখনও SVN ভারী ব্যবহার করি, কিন্তু আমি গিট ব্যবহার করেছি কয়েক বার খুব খুশি।

আপনি যদি সময় আছে একটি চমৎকার পঠিত: আমি গিট কেন বেছে নিলাম


জোয়েল এর ব্লগে একটি নিবন্ধ পড়ুন (দুঃখজনকভাবে তার শেষ এক)। এটি এক Mercurial সম্পর্কে, কিন্তু এটি আসলে Git হিসাবে বিতরণিত ভিসি সিস্টেমের সুবিধার বিষয়ে আলোচনা করে।

বিতরণ সংস্করণ নিয়ন্ত্রণ সঙ্গে, বিতরণ অংশ আসলে সবচেয়ে আকর্ষণীয় অংশ নয়। আকর্ষণীয় অংশ হল এই সিস্টেমগুলি পরিবর্তনের শর্তে মনে করে, সংস্করণগুলির ক্ষেত্রে নয়।

here নিবন্ধ পড়ুন।


সাবভারসনের চেয়ে DVCS এর মধ্যে মার্জিং কেন ভাল তা দাবিটি বেশ কয়েকবার আগে সাবভার্সিয়নে কীভাবে শাখা এবং মার্জ কাজ করে তার উপর ভিত্তি করে ছিল। 1.5.0 পূর্ববর্তী 1.5.0 কখন শাখাগুলি একত্রিত হয়েছিল সে সম্পর্কে কোন তথ্য সঞ্চয় করে নি, যখন আপনি মার্জ করতে চান তখন আপনাকে কোন পরিসর সংশোধন করতে হবে তা উল্লেখ করতে হয়েছিল।

তাই কেন সাবভার্সেশন ম্লিজ স্তন্যপান ?

এই উদাহরণ বিবেচনা করুন:

      1   2   4     6     8
trunk o-->o-->o---->o---->o
       \
        \   3     5     7
b1       +->o---->o---->o

আমরা ট্রাঙ্কের মধ্যে বি 1 এর পরিবর্তনগুলিকে merge করতে চাই যখন আমরা ট্রাঙ্ক চেক আউট থাকা ফোল্ডারটিতে দাঁড়িয়ে থাকা নিম্নলিখিত কমান্ডটি ইস্যু করব:

svn merge -r 2:7 {link to branch b1}

... যা b1 থেকে আপনার স্থানীয় ওয়ার্কিং ডিরেক্টরীতে পরিবর্তনগুলি একত্রিত করার চেষ্টা করবে। এবং তারপর আপনি কোনও দ্বন্দ্ব সমাধান করার পরে এবং ফলাফল পরীক্ষা করার পরে পরিবর্তনগুলি সম্পাদন করেন। যখন আপনি পুনর্বিবেচনার ট্রি করবেন তখন এটি দেখতে হবে:

      1   2   4     6     8   9
trunk o-->o-->o---->o---->o-->o      "the merge commit is at r9"
       \
        \   3     5     7
b1       +->o---->o---->o

তবে যখন সংস্করণ গাছটি বর্ধিত হওয়ার পরে সংস্করণটি ক্রমবর্ধমান হয় তখন সংশোধনীগুলির রেঞ্জ সংজ্ঞায়িত করার এই উপায়টি কখন এবং কী সংশোধনগুলি একত্রিত হয়ে যায় তার কোনও মেটা ডেটা নেই। পরে কি ঘটছে তা বিবেচনা করুন:

           12        14
trunk  …-->o-------->o
                                     "Okay, so when did we merge last time?"
              13        15
b1     …----->o-------->o

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

এই Subversion কমানোর জন্য এখন শাখা জন্য মেটা তথ্য সঞ্চয় এবং একত্রিত। যে সব সমস্যার সমাধান হবে?

এবং ওহ, উপায় দ্বারা, Subversion এখনও sucks ...

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

আপনার কাছে যত বেশি সরকারী শাখার একটি সংগ্রহস্থলে আছে ততই এটি সমস্ত বিভিন্ন শাখার ট্র্যাক রাখতে হবে। তাই আপনার প্রশ্নটি যদি শাখাটি বিকাশে থাকে বা এটি সত্যিই মৃত হয় তবে যে কোনও কেন্দ্রীভূত সংস্করণ নিয়ন্ত্রণ পদ্ধতিতে বলা কঠিন।

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

তাহলে কেন ডিভিসিএস, যেমন গিট, মারকুরিয়াল এবং বাজার, শাখা এবং মার্জিং এ সাবভারসনের চেয়ে ভাল?

একটি খুব সহজ কারণ কেন: শাখা একটি প্রথম শ্রেণীর ধারণা । ডিজাইন এবং শাখার দ্বারা কোনও ভার্চুয়াল ডিরেক্টরি নেই DVCS- এ হার্ড অবজেক্টস যা এটি কেবলমাত্র রিপোজিটোরির সিঙ্ক্রোনাইজেশান (অর্থাত্ ধাক্কা এবং টান ) সহ কাজ করার জন্য এটি হতে হবে।

আপনি যখন DVCS এর সাথে কাজ করেন তখন প্রথম জিনিসটি হ'ল রিপোজিটরি ক্লোন করতে হয় (গিট এর clone , এইচজি এর clone এবং বিজারের branch )। ক্লোনিং ভার্সন নিয়ন্ত্রণে একটি শাখা তৈরির মত একই জিনিস। কেউ কেউ এই ফর্কিং বা শাখাটি কল করে (যদিও পরেটি সহ-প্রতিষ্ঠিত শাখার উল্লেখ করতে ব্যবহৃত হয়) তবে এটি একই জিনিস। প্রতিটি ব্যবহারকারী তাদের নিজস্ব রিপোজিটরি চালায় যার মানে আপনার কাছে প্রতি ব্যবহারকারীর শাখা চালু রয়েছে।

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

মার্জ করার একটি খুব সহজ উদাহরণ এই হতে হবে; origin এবং একটি ব্যবহারকারী, এলিস নামে একটি কেন্দ্রীয় সংগ্রহস্থল কল্পনা করুন, তার মেশিনে সংগ্রহস্থলের ক্লোন করা।

         a…   b…   c…
origin   o<---o<---o
                   ^master
         |
         | clone
         v

         a…   b…   c…
alice    o<---o<---o
                   ^master
                   ^origin/master

ক্লোন এর সময় কি ঘটে তা হল যে প্রত্যেকটি সংস্করণ অ্যালিসে (যা স্বতন্ত্র শনাক্তযোগ্য হ্যাশ-আইডি দ্বারা যাচাই করা হয়) এবং কপিগুলির মূল শাখাগুলি যেখানে আছে সেখানেই কপি করা হয়।

এলিস তার রেপোতে কাজ করে, নিজের সংগ্রহস্থলে বসে এবং তার পরিবর্তনগুলি ধাক্কা দেওয়ার সিদ্ধান্ত নেয়:

         a…   b…   c…
origin   o<---o<---o
                   ^ master

              "what'll happen after a push?"


         a…   b…   c…   d…   e…
alice    o<---o<---o<---o<---o
                             ^master
                   ^origin/master

সমাধানটি বরং সহজ, origin রেজোজিটরিটি যা করতে হবে তা কেবলমাত্র নতুন সংস্করণগুলি গ্রহণ করা এবং এটির শাখাটিকে নতুন সংশোধন (যা "দ্রুত-অগ্রসর" বলে কল করে) -এ স্থানান্তর করা:

         a…   b…   c…   d…   e…
origin   o<---o<---o<---o<---o
                             ^ master

         a…   b…   c…   d…   e…
alice    o<---o<---o<---o<---o
                             ^master
                             ^origin/master

ব্যবহার ক্ষেত্রে, যা আমি উপরে বর্ণিত, এমনকি কিছু মার্জ করতে হবে না । তাই ইস্যু সত্যিই তিনটি উপায় মার্জ অ্যালগরিদম মার্জিং অ্যালগরিদম সঙ্গে নয় সব সংস্করণ নিয়ন্ত্রণ সিস্টেমের মধ্যে বেশ অনেক একই। সমস্যা কিছু চেয়ে গঠন সম্পর্কে আরো

সুতরাং কিভাবে আপনি সম্পর্কে একটি উদাহরণ যে একটি বাস্তব মার্জ দেখাতে?

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

         a…   b…   c…   f…
bob      o<---o<---o<---o
                        ^ master
                   ^ origin/master

                   "can Bob push his changes?" 

         a…   b…   c…   d…   e…
origin   o<---o<---o<---o<---o
                             ^ master

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

সুতরাং ববকে টানতে হবে এবং তারপরে পরিবর্তনগুলি একত্রিত করতে হবে (গিটের pull দিয়ে বা এইচজি এর pull এবং merge বা বিজারের merge )। এটি একটি দুই ধাপ পদ্ধতি. প্রথম ববকে নতুন সংশোধনগুলি আনতে হবে, যা তারা origin সংগ্রহস্থল থেকে তাদের অনুলিপি করবে। আমরা এখন গ্রাফ বিচ্ছিন্ন দেখতে পারি:

                        v master
         a…   b…   c…   f…
bob      o<---o<---o<---o
                   ^
                   |    d…   e…
                   +----o<---o
                             ^ origin/master

         a…   b…   c…   d…   e…
origin   o<---o<---o<---o<---o
                             ^ master

টান প্রক্রিয়াটির দ্বিতীয় ধাপটি ডাইভারিং টিপগুলি একত্রিত করা এবং ফলাফলের একটি কমিটি করা:

                                 v master
         a…   b…   c…   f…       1…
bob      o<---o<---o<---o<-------o
                   ^             |
                   |    d…   e…  |
                   +----o<---o<--+
                             ^ origin/master

আশা করি মার্জ দ্বন্দ্বগুলিতে দৌড়াবে না (যদি আপনি তাদের প্রত্যাশা করেন তবে আপনি fetch এবং merge সহ দুটো পদক্ষেপ ম্যানুয়ালি করতে পারেন)। পরে যা করতে হবে তা আবার origin সেই পরিবর্তনগুলিতে ধাক্কা দিতে হবে, যা একটি দ্রুত-অগ্রসর একত্রিত হতে পারে কারণ মার্জ কমিটি origin সংগ্রহস্থলগুলির সর্বশেষতম প্রত্যক্ষ উত্তরাধিকারী:

                                 v origin/master
                                 v master
         a…   b…   c…   f…       1…
bob      o<---o<---o<---o<-------o
                   ^             |
                   |    d…   e…  |
                   +----o<---o<--+

                                 v master
         a…   b…   c…   f…       1…
origin   o<---o<---o<---o<-------o
                   ^             |
                   |    d…   e…  |
                   +----o<---o<--+

বিট এবং এইচজিতে একত্রিত হওয়ার আরেকটি বিকল্প রয়েছে, যা রিবেস নামে পরিচিত, যা নতুন পরিবর্তনগুলির পরে বব এর পরিবর্তনগুলি সরাবে। যেহেতু আমি এই উত্তরটি আর কোনও শব্দের হতে চাই না তাই আমি সেই পরিবর্তে আপনি git , mercurial বা bazaar ডক্সগুলি পড়তে দেব।

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

প্রতিটি বিকাশকারীর মধ্যে প্যাচ পাঠানোর সমস্যা রয়েছে, এটি সাবভার্সনটিতে একটি বিশাল সমস্যা যা গিট, এইচজি এবং বিজেআর মধ্যে স্বতন্ত্র শনাক্তযোগ্য সংশোধন দ্বারা মাপা হয়। একবার কেউ তার পরিবর্তনগুলি একত্রিত করে (অর্থাত একটি মার্জ কমিট তৈরি করে) এবং এটি সেন্ট্রাল রিপোজিটরিতে ধাক্কা দিয়ে বা প্যাচ পাঠানোর মাধ্যমে দলটির অন্য সকলের জন্য পাঠায় তবে তাদের মার্জ সম্পর্কে চিন্তা করতে হবে না কারণ এটি ইতিমধ্যে ঘটেছে । মার্টিন Fowler কাজ promiscuous ইন্টিগ্রেশন এই ভাবে কল।

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





merge