গিটের "রিবেস - প্রিফারিজ-মার্জগুলি" ঠিক কী করে (এবং কেন?)


355

কমান্ডের জন্যrebase গিটের ডকুমেন্টেশন বেশ সংক্ষিপ্ত:

--preserve-merges
    Instead of ignoring merges, try to recreate them.

This uses the --interactive machinery internally, but combining it
with the --interactive option explicitly is generally not a good idea
unless you know what you are doing (see BUGS below).

সুতরাং আপনি যখন ব্যবহার আসলে কি হয় --preserve-merges? এটি কীভাবে ডিফল্ট আচরণ থেকে পৃথক হয় (যে পতাকা ছাড়াই)? মার্জ "পুনরায় তৈরি" এর অর্থ কী?


20
সতর্কতা: গিট 2.18 দিয়ে শুরু (5 বছর পরে Q2 2018), git --rebase-mergesশেষ পর্যন্ত পুরানোটিকে প্রতিস্থাপন করবে git --preserve-merges। দেখুন নিচের আমার উত্তর
VonC

উত্তর:


464

সাধারণ গিট রিবেসের মতো, গিটটি --preserve-mergesপ্রথমে কমিট গ্রাফের এক অংশে করা কমিটের তালিকা চিহ্নিত করে এবং তারপরে সেই অংশগুলি অন্য অংশের উপরে পুনরায় প্রদর্শন করে। --preserve-mergesকোন কমিট করে তা উদ্বেগের সাথে পার্থক্যগুলি পুনরায় প্লে করার জন্য নির্বাচিত হয় এবং কীভাবে পুনরায় খেলতে পারা মার্জ করার জন্য কাজ করে।

স্বাভাবিক এবং মার্জ-সংরক্ষণের রিবেসের মধ্যে প্রধান পার্থক্য সম্পর্কে আরও স্পষ্ট করে জানাতে:

  • মার্জ-সংরক্ষণ রিবেস পুনরায় খেলতে ইচ্ছুক (কিছু) মার্জ কমিটস, অন্যদিকে সাধারণ রিবাজে সম্পূর্ণভাবে মার্জ কমিটকে উপেক্ষা করে।
  • যেহেতু এটি মার্জ কমিটগুলি পুনরায় খেলতে ইচ্ছুক, মার্জ-সংরক্ষণের পুনর্বাসনকে মার্জ কমিট পুনরায় খেলতে পারা মানে কী তা সংজ্ঞায়িত করতে হবে এবং কিছু অতিরিক্ত চুলকানি নিয়ে কাজ করতে হবে
    • ধারণাটির দিক থেকে সবচেয়ে আকর্ষণীয় অংশটি সম্ভবত নতুন প্রতিশ্রুতিবদ্ধতার পিতামাতার কী হওয়া উচিত তা বেছে নেওয়া।
    • মার্জ কমিটগুলি পুনরায় খেলতেও স্পষ্টভাবে নির্দিষ্ট কমিটগুলি ( git checkout <desired first parent>) পরীক্ষা করে দেখতে হবে , অন্যদিকে স্বাভাবিক পুনর্বাসনের বিষয়ে উদ্বিগ্ন হওয়ার দরকার নেই।
  • মার্জ-সংরক্ষণ রিবেস পুনর্বিবেচনার জন্য কমিটের একটি অগভীর সেট বিবেচনা করে:
    • বিশেষত, এটি কেবল সাম্প্রতিকতম সংশ্লেষ বেস (গুলি) -র পর থেকে করা কমিটগুলি পুনরায় খেলতে বিবেচনা করবে - যেমন দুটি শাখাটি সর্বাধিক সাম্প্রতিক সময় - যেখানে স্বাভাবিক পুনর্বাসনে দুটি শাখা ডাইভার্ট করা প্রথমবারে পুনরায় খেলতে হবে its
    • অস্থায়ী এবং অস্পষ্ট হতে, আমি বিশ্বাস করি এটি শেষ পর্যন্ত "পুরানো কমিটগুলি" পুনরায় প্লে করার একটি মাধ্যম যা ইতিমধ্যে একটি সংহত অঙ্গীকারকে "অন্তর্ভুক্ত" করা হয়েছে।

প্রথমে আমি রিবেস কী --preserve-mergesকরে "পর্যাপ্তরূপে" বর্ণনা করার চেষ্টা করব এবং তারপরে কিছু উদাহরণ থাকবে। কেউ অবশ্যই উদাহরণগুলি দিয়ে শুরু করতে পারেন, যদি এটি আরও কার্যকর বলে মনে হয়।

"ব্রিফ" এর অ্যালগরিদম

আপনি যদি সত্যিই আগাছা পেতে চান তবে গিট উত্সটি ডাউনলোড করুন এবং ফাইলটি অন্বেষণ করুন git-rebase--interactive.sh। (রিবেস গিতের সি কোরের অংশ নয়, বরং ব্যাশে লেখা হয়েছে And এবং পর্দার আড়ালে এটি "ইন্টারেক্টিভ রিবেস" সহ কোডটি শেয়ার করে))

তবে আমি এখানে স্কেচ করব যা আমি মনে করি এটির সারাংশ। ভাবতে ভাবতে সংখ্যা কমাতে আমি কিছুটা স্বাধীনতা নিয়েছি। (উদাহরণস্বরূপ, গণনাগুলি ঘটে যায় এমন সঠিক ক্রমে আমি 100% নির্ভুলতার সাথে ক্যাপচার করার চেষ্টা করি না, এবং কিছু কম কেন্দ্রীয়-বোধ বিষয়গুলি উপেক্ষা করি, যেমন শাখাগুলির মধ্যে ইতিমধ্যে চেরি-বাছাই করা কমিটগুলি সম্পর্কে কী করা উচিত)।

প্রথম, নোট করুন যে একটি অ-মার্জ-সংরক্ষণের রিবেস বরং সহজ। এটি কমবেশি:

Find all commits on B but not on A ("git log A..B")
Reset B to A ("git reset --hard A") 
Replay all those commits onto B one at a time in order.

রিবেস --preserve-mergesতুলনামূলকভাবে জটিল। এখানে এতটা সহজ যে আমি এটি গুরুত্বপূর্ণ হিসাবে গুরুত্বপূর্ণ জিনিসগুলি না হারিয়ে এটি তৈরি করতে সক্ষম হয়েছি:

Find the commits to replay:
  First find the merge-base(s) of A and B (i.e. the most recent common ancestor(s))
    This (these) merge base(s) will serve as a root/boundary for the rebase.
    In particular, we'll take its (their) descendants and replay them on top of new parents
  Now we can define C, the set of commits to replay. In particular, it's those commits:
    1) reachable from B but not A (as in a normal rebase), and ALSO
    2) descendants of the merge base(s)
  If we ignore cherry-picks and other cleverness preserve-merges does, it's more or less:
    git log A..B --not $(git merge-base --all A B)
Replay the commits:
  Create a branch B_new, on which to replay our commits.
  Switch to B_new (i.e. "git checkout B_new")
  Proceeding parents-before-children (--topo-order), replay each commit c in C on top of B_new:
    If it's a non-merge commit, cherry-pick as usual (i.e. "git cherry-pick c")
    Otherwise it's a merge commit, and we'll construct an "equivalent" merge commit c':
      To create a merge commit, its parents must exist and we must know what they are.
      So first, figure out which parents to use for c', by reference to the parents of c:
        For each parent p_i in parents_of(c):
          If p_i is one of the merge bases mentioned above:
            # p_i is one of the "boundary commits" that we no longer want to use as parents
            For the new commit's ith parent (p_i'), use the HEAD of B_new.
          Else if p_i is one of the commits being rewritten (i.e. if p_i is in R):
            # Note: Because we're moving parents-before-children, a rewritten version
            # of p_i must already exist. So reuse it:
            For the new commit's ith parent (p_i'), use the rewritten version of p_i.
          Otherwise:
            # p_i is one of the commits that's *not* slated for rewrite. So don't rewrite it
            For the new commit's ith parent (p_i'), use p_i, i.e. the old commit's ith parent.
      Second, actually create the new commit c':
        Go to p_1'. (i.e. "git checkout p_1'", p_1' being the "first parent" we want for our new commit)
        Merge in the other parent(s):
          For a typical two-parent merge, it's just "git merge p_2'".
          For an octopus merge, it's "git merge p_2' p_3' p_4' ...".
        Switch (i.e. "git reset") B_new to the current commit (i.e. HEAD), if it's not already there
  Change the label B to apply to this new branch, rather than the old one. (i.e. "git reset --hard B")

একটি --onto Cআর্গুমেন্ট সঙ্গে রিবেস খুব অনুরূপ হওয়া উচিত। বি এর হেডে কমিট প্লেব্যাক শুরু করার পরিবর্তে, আপনি পরিবর্তে সি এর হেডে প্লেব্যাক শুরু করবেন। (এবং বি_নউয়ের পরিবর্তে সি_ইউ ব্যবহার করুন))

উদাহরণ 1

উদাহরণস্বরূপ, কমিট গ্রাফ নিন

  B---C <-- master
 /                     
A-------D------E----m----H <-- topic
         \         /
          F-------G

মিঃ পিতামাতার ই এবং জি এর সাথে একীভূত প্রতিশ্রুতি is

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

  • বাছাই ডি
  • ই বাছাই
  • এফ
  • জি বাছাই
  • এইচ চয়ন করুন

এবং তারপরে কমিট গ্রাফ আপডেট করুন:

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

(ডি ', ডি, ইত্যাদির পুনরায় খেলানো সমতুল্য)

নোট করুন যে মার্জ কমিট মি রিপ্লেয়ের জন্য নির্বাচিত নয়।

যদি আমরা পরিবর্তে --preserve-mergesসি এর শীর্ষে এইচ এর রিবেসটি করি (উদাহরণস্বরূপ, চেকআউট বিষয়; রিবাস - প্রিফারিজ-মার্জ মাস্টার ।) এই নতুন ক্ষেত্রে, গিটটি পুনরায় প্লে করার জন্য নিম্নলিখিত কমিটগুলি নির্বাচন করবে:

  • বাছাই ডি
  • ই বাছাই
  • F বাছুন ('সাবটোপিক' শাখার ডি'র দিকে)
  • জি বাছুন ('সাবটোপিক' শাখায় F 'তে)
  • বিষয়টিতে শাখা 'সাবটোপিক' মার্জ করুন
  • এইচ চয়ন করুন

এখন এম রিপ্লে জন্য বেছে নেওয়া হয়েছিল । আরও মনে রাখবেন যে মার্জ পিতামাতারা E এবং G কে মার্জ কমিট এম এর আগে অন্তর্ভুক্তির জন্য বেছে নেওয়া হয়েছিল।

এখানে ফলাফল প্রতিশ্রুতিবদ্ধ গ্রাফ:

 B---C <-- master
/     \                
A      D'-----E'----m'----H' <-- topic
        \          / 
         F'-------G'

আবার, ডি 'হ'ল চেরি-বাছাই করা (অর্থাত্ পুনঃনির্ধারিত) ডি সেম ফর ই' ইত্যাদি ইত্যাদির সংস্করণ master E এবং G উভয়কে (m এর একীভূত পিতামাতার) এম এর পিতামাতার হিসাবে পরিবেশন করতে E এবং G হিসাবে পুনঃনির্ধারণ করা হয়েছে (পুনঃবাসের পরেও, গাছের ইতিহাস এখনও একই রয়েছে)।

উদাহরণ 2

সাধারণ রিবেসের সাথে পৃথক নয়, মার্জ-সংরক্ষণের রিবাজে প্রবাহের মাথাটি একাধিক শিশু তৈরি করতে পারে।

উদাহরণস্বরূপ, বিবেচনা করুন:

  B---C <-- master
 /                     
A-------D------E---m----H <-- topic
 \                 |
  ------- F-----G--/ 

যদি আমরা সি (মাস্টার) এর শীর্ষে এইচ (বিষয়) রিবেস করি তবে পুনঃবাসের জন্য নির্বাচিত কমিটগুলি হ'ল:

  • বাছাই ডি
  • ই বাছাই
  • এফ
  • জি বাছাই
  • মি
  • এইচ চয়ন করুন

এবং ফলাফলটি এর মতো:

  B---C  <-- master
 /    | \                
A     |  D'----E'---m'----H' <-- topic
       \            |
         F'----G'---/

উদাহরণ 3

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

উদাহরণস্বরূপ, বিবেচনা করুন:

  B--C---D <-- master
 /    \                
A---E--m------F <-- topic

আমরা যদি মাস্টারের উপর বিষয়টিকে পুনরায় চালু করি (মার্জগুলি সংরক্ষণ করে), তবে পুনরায় প্লে করার প্রতিশ্রুতি হবে

  • পিক্স মার্জ কমিট মি
  • এফ

পুনর্লিখিত কমিট গ্রাফটি দেখতে এরকম হবে:

                     B--C--D <-- master
                    /       \             
                   A-----E---m'--F'; <-- topic

এখানে রিপ্লেড মার্জ কমিট এম 'পিতামাতাদের প্রতিশ্রুতিবদ্ধ গ্রাফের পূর্ব-অস্তিত্ব পেয়ে যায়, যথা ডি (মাস্টারের হেড) এবং ই (মূল সংশ্লেষ কমিটের পিতা-মাতার একজন)।

উদাহরণ 4

মার্জ-সংরক্ষণ রিবেস কিছু "ফাঁকা প্রতিশ্রুতি" ক্ষেত্রে বিভ্রান্ত হতে পারে। অন্তত এটি গিটের কিছু পুরানো সংস্করণে সত্য (উদাহরণস্বরূপ 1.7.8))

এই প্রতিশ্রুতি গ্রাফ নিন:

                   A--------B-----C-----m2---D <-- master
                    \        \         /
                      E--- F--\--G----/
                            \  \
                             ---m1--H <--topic

মনে রাখবেন যে এম 1 এবং এম 2 উভয়ই কমিটিকে বি এবং এফ থেকে সমস্ত পরিবর্তন একত্রিত করা উচিত ছিল Note

যদি আমরা git rebase --preserve-mergesডি (মাস্টার) এ এইচ (বিষয়) করার চেষ্টা করি তবে নিম্নলিখিত কমিটগুলি পুনরায় প্লে করার জন্য বেছে নেওয়া হয়েছে:

  • এম 1 চয়ন করুন
  • এইচ চয়ন করুন

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

পরিবর্তে, তবে, গিটটি ডি এর উপরে এম 1 রিপ্লে করার প্রচেষ্টাটিকে প্রত্যাখ্যান করতে পারে আপনি এর মতো একটি ত্রুটি পেতে পারেন:

error: Commit 90caf85 is a merge but no -m option was given.
fatal: cherry-pick failed

দেখে মনে হচ্ছে যে কেউ গিটের কাছে পতাকা পাস করতে ভুলে গেছে তবে অন্তর্নিহিত সমস্যাটি হ'ল গিটটি খালি কমিট তৈরি করা অপছন্দ করে।


6
আমি লক্ষ্য করেছি যে git rebase --preserve-mergesহয় অনেক ধীর তুলনায় rebaseছাড়া --preserve-merges। এটি কি সঠিক প্রতিশ্রুতি সন্ধানের একটি পার্শ্ব প্রতিক্রিয়া? এটির গতি বাড়ানোর জন্য কেউ কি কিছু করতে পারে? (যাইহোক ... খুব বিস্তৃত উত্তরের জন্য ধন্যবাদ!)
ডেভিড অ্যালান হেজেল

7
মনে হচ্ছে আপনার সর্বদা - প্রিফারিজ-মার্জগুলি ব্যবহার করা উচিত। অন্যথায় ইতিহাস হারানোর সম্ভাবনা রয়েছে অর্থাৎ মার্জটি কমিট করে।
দারভিয়ার

19
@ দরওয়ার আপনি সবসময়ই রিবেসটির ইতিহাস ছেড়ে দেন, কারণ আপনি দাবি করেছেন যে পরিবর্তিত স্থানগুলি যেখানে ছিল ঠিক তার চেয়ে আলাদা কোডবেসে হয়েছে।
ক্রনিকিয়াল

5
এটি কি এখনও একটি "অস্থায়ী উত্তর"?
অ্যান্ড্রু গ্রিম

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

94

গিট 2.18 (কিউ 2 2018) --preserve-mergeএকটি নতুন বিকল্প যুক্ত করে বিকল্পটিতে যথেষ্ট উন্নতি করবে ।

কমিট গ্রাফের পুরো টপোলজি অন্য কোথাও প্রতিস্থাপন করতে " git rebase" শিখেছি " --rebase-merges" ।

(দ্রষ্টব্য: গিট 2.22, কিউ 2 2019, প্রকৃতপক্ষে অবমূল্যায়ন করে --preserve-merge এবং গিট 2.25, কিউ 12020, " git rebase --help" আউটপুটে এটির বিজ্ঞাপন দেওয়া বন্ধ করে )

দেখুন 25cff9f কমিট , 7543f6f কমিট , 1131ec9 কমিট , 7ccdf65 কমিট , 537e7d6 কমিট , a9be29c কমিট , 8f6aed7 কমিট , 1644c73 কমিট , d1e8b01 কমিট , 4c68e7d কমিট , 9055e40 কমিট , cb5206e কমিট , a01c2a5 কমিট , 2f6b1d1 কমিট , কমিট bf5c057 (25 এপ্রিল 2018) দ্বারা জোহানেস Schindelin ( dscho)
দেখুন কমিট f431d73 (25 এপ্রিল 2018) দ্বারা স্টিফান Beller ( stefanbeller)
দেখুন কমিট 2429335 (25 এপ্রিল 2018) দ্বারা ফিলিপ কাঠ ( phillipwood)
(দ্বারা একীভূত junio সি Hamano - gitster- মধ্যে 2c18e6a কমিট , 23 মে 2018)

pull: --rebase-mergesশাখা টোপোলজি পুনরায় তৈরি করতে গ্রহণ করুন

কমান্ডের বিকল্পটি preserveকেবল মোডের মতোই মোডটি কেবল --preserve-mergesবিকল্পটি পাস করে ।rebasemerges--rebase-merges

এটি ব্যবহারকারীদেরকে নতুন করে কমিট করার সময়, তত্পরতা ছাড়াই অপ্রয়োজনীয় কমিট টোপোলজিকে সুবিধামতভাবে রিবেস করতে দেয়।


git rebaseম্যান পৃষ্ঠাতে এখন পুরো বিভাগটি একীভূতকরণের সাথে ইতিহাস রিবেসিংকে উত্সর্গীকৃত

নির্যাস:

কোনও বিকাশকারী মার্জ কমিটগুলি পুনরায় তৈরি করতে চান এমন বৈধ কারণ রয়েছে: একাধিক, আন্তঃসম্পর্কিত শাখায় কাজ করার সময় শাখা কাঠামো (বা "টপোলজি প্রতিশ্রুতিবদ্ধ") রাখতে।

নিম্নলিখিত উদাহরণে, বিকাশকারী একটি বিষয় শাখায় কাজ করে যা বোতামগুলি সংজ্ঞায়িত করার উপায়ে রিফ্যাক্টর করে এবং অন্য একটি বিষয় শাখায় যে "বাগের প্রতিবেদন করুন" বোতামটি প্রয়োগ করতে সেই রিফ্যাক্টরিং ব্যবহার করে।
এর ফলাফলটি এর git log --graph --format=%s -5মতো দেখতে পাওয়া যাবে:

*   Merge branch 'report-a-bug'
|\
| * Add the feedback button
* | Merge branch 'refactor-button'
|\ \
| |/
| * Use the Button class for all buttons
| * Extract a generic Button class from the DownloadButton one

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

এই রিবেস --rebase-mergesবিকল্পটি ব্যবহার করে সম্পাদন করা যেতে পারে ।


একটি ছোট উদাহরণের জন্য 1644c73 কমিট করুন দেখুন :

rebase-helper --make-script: মার্জগুলি পুনরায় চালু করতে একটি পতাকা প্রবর্তন করুন

সিকোয়েন্সারটি শাখার কাঠামোটি পুনরায় তৈরি করার উদ্দেশ্যে নতুন কমান্ডগুলি শিখেছে ( একইভাবে --preserve-merges, তবে যথেষ্ট কম ভাঙা নকশার সাথে )।

আসুন rebase--helperনতুন --rebase-mergesবিকল্প দ্বারা ট্রিগার করে এই কমান্ডগুলি ব্যবহার করে টুডো তালিকা তৈরি করার অনুমতি দিন ।
এর মতো প্রতিশ্রুতিবদ্ধ টোপোলজির জন্য (যেখানে HEAD সি তে নির্দেশ করে):

- A - B - C (HEAD)
    \   /
      D

উত্পাদিত টুডু তালিকাটি দেখতে এইরকম হবে:

# branch D
pick 0123 A
label branch-point
pick 1234 D
label D

reset branch-point
pick 2345 B
merge -C 3456 D # C

এর সাথে পার্থক্য কী --preserve-merge?
কমিট 8f6aed7 ব্যাখ্যা করে:

একসময়, এই এখানে বিকাশকারী ভেবেছিলেন: উইন্ডোজের মূল গিটের উপরের প্যাচগুলি শাখাগুলির একটি ছোট ছোট অংশ হিসাবে উপস্থাপিত করা যেতে পারে এবং গিটের শীর্ষে পুনর্বাসিত করা যেতে পারে, তবে এটি কী ভাল হবে না? প্যাচ সিরিজের চেরি-পিক'এল সেট বজায় রাখবেন?

এই উত্তর মূল প্রয়াস ছিল: git rebase --preserve-merges

যাইহোক, সেই পরীক্ষাকে কখনই ইন্টারেক্টিভ বিকল্প হিসাবে চিহ্নিত করা হয়নি, এবং এটি কেবল পিগি-সমর্থিত git rebase --interactiveকারণ এই আদেশটির বাস্তবায়ন ইতিমধ্যে খুব, খুব চেনা লাগছিল: এটি একই ব্যক্তি ডিজাইন করেছিলেন যিনি ডিজাইন করেছিলেন --preserve-merges: সত্যই আপনার।

এবং "সত্যই আপনার" দ্বারা, লেখক নিজেকে উল্লেখ করেছেন: জোহানেস শিন্ডেলিন ( dscho) , যিনি মূল কারণ (অন্য কয়েকজন নায়ক - হ্যানস, স্টিফেন, সেবাস্তিয়ান, ...) সহ যে আমাদের উইন্ডোজের জন্য গিট রয়েছে (যদিও ফিরে দিন - 2009 - যে সহজ ছিল না )। ২০১৫ সালের সেপ্টেম্বরের পর থেকে
তিনি মাইক্রোসফ্টে কাজ করছেন , যা মাইক্রোসফ্টকে এখন ভারীভাবে গিট ব্যবহার করে এবং তার পরিষেবাগুলির প্রয়োজন বিবেচনা করে তা বিবেচনা করে। এই প্রবণতাটি ২০১৩ সালে টিএফএসের সাথে শুরু হয়েছিল । তার পর থেকে মাইক্রোসফ্ট গ্রহের বৃহত্তম গিট সংগ্রহস্থল পরিচালনা করে ! এবং, অক্টোবর 2018 সাল থেকে মাইক্রোসফ্ট গিটহাবটি অর্জন করেছে

আপনি এপ্রিল 2018 এ গিট মার্জ 2018 এর জন্য জোহানেসদের এই ভিডিওতে কথা বলতে পারেন ।

কিছু সময় পরে, কিছু অন্যান্য ডেভেলপার (আমি, আপনি খুঁজছেন করছি আন্দ্রিয়াস! ;-)) সিদ্ধান্ত নিয়েছে এটি একটি ভাল ধারণা করার অনুমতি হবে যে --preserve-mergesসঙ্গে মিলিত হতে পারে --interactive(আদেশ সহকারে সঙ্গে!) এবং গীত রক্ষণাবেক্ষণকারী (অবশ্য অন্তর্বর্তী গীত রক্ষণাবেক্ষণকারী জুনিওর অনুপস্থিতির সময়, এটি সম্মত হয়েছে) এবং এটি তখনই যখন --preserve-mergesডিজাইনের গ্ল্যামারটি বরং দ্রুত এবং unglamorously পৃথক্ভাবে পড়তে শুরু করে।

এখানে জোনাথন সুস থেকে আন্ড্রেয়াস সোয়াব সম্পর্কে কথা বলছেন ।
আপনি তাদের আলোচনার কয়েকটি 2012 সালে ফিরে দেখতে পারেন ।

কারন? ইন --preserve-mergesমোড, মার্জ বাবা (অথবা যে বিষয়টি জন্য এর কমিট কোনো কমিট) স্পষ্টভাবে বিবৃত করা হয় নি, কিন্তু সেটা উহ্য কমিট নাম প্রেরণ দ্বারা pickকমান্ড

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

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

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

(গিট গার্ডেন শিয়ার স্ক্রিপ্টটি প্রতিশ্রুতি 9055e40 এ এই প্যাচে উল্লেখ করা হয়েছে )

এটি ২০১৩ সালে ছিল
And এবং ডিজাইনের সাথে আসতে এবং গাছের বাইরে স্ক্রিপ্ট হিসাবে এটি প্রয়োগ করতে প্রায় তিন সপ্তাহ লেগেছিল। বলা বাহুল্য, বাস্তবায়ন স্থিতিশীল হওয়ার জন্য বেশ কয়েক বছর সময় প্রয়োজন, সমস্ত সময় ডিজাইন নিজেই নিজেকে সাউন্ড প্রমাণ করে।

এই প্যাচটির সাথে, গিট গার্ডেন শিয়েরগুলির মঙ্গলতা git rebase -iনিজের মধ্যে আসেবিকল্পটি
পাস --rebase-mergesকরা একটি টুডো তালিকা তৈরি করবে যা সহজেই বোঝা যায় এবং যেখানে কমিটগুলি পুনরায় অর্ডার করতে হবে তা স্পষ্ট । কমান্ড
সন্নিবেশ করানো labelএবং কল করে নতুন শাখা চালু করা যেতে পারে merge <label>
এবং একবার এই মোডটি স্থিতিশীল হয়ে উঠবে এবং সর্বজনীনভাবে স্বীকৃত হয়ে উঠলে, আমরা সেই নকশার ভুলটি হ্রাস করতে পারি--preserve-merges


গিট 2.19 (কিউ 3 2018) --rebase-mergesএটিকে কাজ করে নতুন বিকল্পটিকে উন্নত করে --exec

" --exec" " " " " অপশনে git rebase --rebase-mergesএক্সিকিউট কমান্ডগুলি ভুল জায়গায় স্থাপন করেছে, যা সংশোধন করা হয়েছে।

দেখুন 1ace63b কমিট (09 আগস্ট 2018), এবং f0880f7 কমিট দ্বারা (06 আগস্ট 2018) জোহানেস Schindelin ( dscho)
(দ্বারা একীভূত junio সি Hamano - gitster- মধ্যে কমিট 750eb11 , 20 আগস্ট 2018)

rebase --exec: এটি দিয়ে কাজ করা --rebase-merges

প্রত্যেকের পরে --execএকটি execকল সংযোজন করা ধারণা pick

fixup!/ S quash!কমিটের সূচনা হওয়ার পরে , এই ধারণাটি "পিক, সম্ভবত একটি ফিক্সআপ / স্কোয়াশ চেইন" প্রয়োগ করার জন্য প্রসারিত করা হয়েছিল, অর্থাত্ কোনও এক্স pickএবং এর সাথে সম্পর্কিত fixupবা squashলাইনগুলির মধ্যে সন্নিবেশ করা হবে না ।

বর্তমান বাস্তবায়ন এটি অর্জনের জন্য একটি নোংরা কৌশল ব্যবহার করে: এটি ধরে নিয়েছে যে কেবল পিক / ফিক্সআপ / স্কোয়াশ কমান্ড রয়েছে এবং তারপরে প্রথমটি বাদ দিয়ে লাইনগুলি সন্নিবেশ করায় এবং একটি চূড়ান্ত সংযোজন করে।execpick

দ্বারা উত্পন্ন করণীয় তালিকাগুলি দিয়ে git rebase --rebase-merges, এই সহজ বাস্তবায়নের শো তার সমস্যার: এটা সঠিক ভুল জিনিস আছে যখন উৎপন্ন label, resetএবং mergeকমান্ড।

: আসুন পরিবর্তন বাস্তবায়ন ঠিক করতে আমরা কি চাই জন্য বর্ণন pickলাইন, কোনো ফিক্সআপ / স্কোয়াশ চেইন এড়িয়ে যান এবং তারপর সন্নিবেশ exec লাইন । হালকা, ধুয়ে ফেলা, পুনরাবৃত্তি।

দ্রষ্টব্য: আমরা যখনই সম্ভব কমেন্ট লাইনগুলির আগে toোকাতে ব্যথা নিই , কেননা খালি কমিটগুলি মন্তব্য করা আউট পিক লাইনগুলি দ্বারা উপস্থাপিত করা হয় (এবং আমরা এই জাতীয় লাইনের আগে একটি পূর্ববর্তী পিকের এক্সিকিউট লাইনটি সন্নিবেশ করতে চাই , এর পরে নয়)।

এটির সময়ে, কমান্ডগুলির execপরে লাইনগুলিও যুক্ত করুন merge, কারণ কমান্ডের সাথে সেগুলি একই রকম pick: তারা নতুন কমিট যোগ করে।


গিট ২.২২ (Q2 2019) একটি রিবাজ অন্তর্বর্তী রাষ্ট্রগুলি সংরক্ষণের জন্য রেফ / পুনর্লিখন / শ্রেণিবিন্যাসের ব্যবহার স্থির করে, যা অন্তর্নিহিতভাবে ওয়ার্কট্রি প্রতি শ্রেণিবদ্ধ করে তোলে makes

দেখুন b9317d5 কমিট , 90d31ff কমিট , 09e6564 কমিট (07 মার্চ 2019) দ্বারা গান Nguyễn গান Thái আরো Ngọc গান Duy ( pclouds)
(দ্বারা একীভূত junio সি Hamano - gitster- মধ্যে কমিট 917f2cd , 09 এপ্রিল 2019)

নিশ্চিত করুন যে রেফগুলি / পুনর্লিখন / প্রতি কর্মশক্তি রয়েছে

a9be29c (সিকোয়েন্সার: labelওয়ার্কট্রি-লোকাল, 2018-04-25, গিট 2.19) কমান্ড দ্বারা তৈরি করা রেফগুলি refs/rewritten/ওয়ার্কট্রি রেফারেন্স স্পেস হিসাবে যুক্ত করে।
দুর্ভাগ্যক্রমে (আমার খারাপ) এমন কয়েকটি জায়গা রয়েছে যা বাস্তবিক প্রতি কর্মশালার জন্য তা নিশ্চিত করার জন্য আপডেটের প্রয়োজন।

- add_per_worktree_entries_to_dir()refs/rewritten/প্রতি-রেপো একের পরিবর্তে প্রতি-কর্মশ্রেখায় রেফারিং তালিকাটি নিশ্চিত করার জন্য আপডেট করা হয়েছে ।

  • common_list[]আপডেট করা হয়েছে যাতে git_path()সঠিক অবস্থানটি ফিরে আসে। এর মধ্যে " rev-parse --git-path" অন্তর্ভুক্ত রয়েছে ।

এই জগাখিচুড়ি আমার দ্বারা তৈরি করা হয়েছে।
আমি refs/worktree,বিশেষ চিকিত্সা ব্যতীত যেখানে সমস্ত রেফ-ওয়ার্কট্রি হবে তার প্রবর্তন দিয়ে এটি ঠিক করার চেষ্টা শুরু করেছি ।
দুর্ভাগ্যজনক রেফ / পুনর্লিখনগুলি রেফ / ওয়ার্কট্রি এর আগে এসেছিল তাই আমরা কেবল এটিই করতে পারি।


গিট 2.24 (Q4 2019) এর সাথে, " git rebase --rebase-merges" বিভিন্ন সংহত কৌশল চালানো এবং কৌশলগুলিকে তাদের নির্দিষ্ট বিকল্পগুলি পাস করতে শিখেছে।

দেখুন কমিট 476998d (04 সেপ্টেম্বর 2019) দ্বারা ইলিয়াস Newren ( newren)
দেখুন কমিট e1fac53 , a63f990 কমিট , 5dcdd74 কমিট , e145d99 কমিট , 4e6023b কমিট , f67336d কমিট , a9c7107 কমিট , b8c6f24 কমিট , d51b771 কমিট , কমিট c248d32 , কমিট 8c1e240 , কমিট 5efed0e , কমিট 68b54f6 , 2e7bbac কমিট , কমিট 6180b20 , d5b581f কমিট 31 ( জুলাই 2019) দ্বারাজোহানেস শিন্ডেলিন ( dscho)
(দ্বারা একীভূত junio সি Hamano - gitster- মধ্যে কমিট 917a319 , 18 সেপ্টেম্বর 2019)


গিট 2.25 (কিউ 12020) এর সাথে, ওয়ার্কট্রি স্থানীয় এবং ভাণ্ডার গ্লোবাল রেফগুলি পৃথক পৃথক বলতে বলার জন্য ব্যবহৃত যুক্তিটি স্থির করা হয়েছে, সংরক্ষণ-সংযুক্তির সুবিধার্থে।

দেখুন কমিট f45f88b , কমিট c72fc40 , কমিট 8a64881 , কমিট 7cb8c92 , কমিট ই 536 বি 1 এফ (21 অক্টোবর 2019) এসজেডের গবার ( szeder) এর মাধ্যমে
(দ্বারা একীভূত junio সি Hamano - gitster- মধ্যে db806d7 কমিট , 10 নভেম্বর 2019)

path.c: matchমান ব্যতীত ফাংশনটি কল করবেন নাtrie_find()

সাইন-অফ-বাই: এসজেডর গোবর

'লগস / রেফস' কোনও বৃক্ষ-নির্দিষ্ট পথ নয়, তবে যেহেতু b9317d55a3 (নিশ্চিত করুন রেফ / পুনর্লিখিত / প্রতি কর্মশালার প্রতিশ্রুতি দিন, 2019-03-07, v2.22.0-rc0) ' git rev-parse --git-path' একটি বগাস পথ ফিরিয়েছে যদি একটি পিছনে ' /' উপস্থিত থাকে:

$ git -C WT/ rev-parse --git-path logs/refs --git-path logs/refs/
/home/szeder/src/git/.git/logs/refs
/home/szeder/src/git/.git/worktrees/WT/logs/refs/

আমরা trieকোনও পথ সাধারণ ডিরের অন্তর্গত বা গাছ-নির্দিষ্ট কাজ করে কিনা তা দক্ষতার সাথে সিদ্ধান্ত নিতে একটি ডেটা স্ট্রাকচার ব্যবহার করি ।

ঘটনাচক্রে b9317d55a3 একটি বাগ যে পুরনো হিসাবে সূত্রপাত trieবাস্তবায়ন নিজে যোগ 4e09cf2acf ( " path: অপ্টিমাইজ সাধারণ Dir পরীক্ষণ", 2015-08-31, গীত v2.7.0-rc0 - একত্রীকরণ তালিকাভুক্ত ব্যাচ # 2 )।

  • বর্ণিত মন্তব্য অনুসারে trie_find(), এটি কেবল একটি "/ -অর- \ 0-সমাপ্ত উপসর্গের জন্য ট্রাইতে একটি মান রয়েছে" এর জন্য প্রদত্ত ম্যাচ ফাংশনটিকে 'fn' বলা উচিত।
    এটি সত্য নয়: তিনটি জায়গা রয়েছে যেখানে ট্রাই_ফাইন্ড () ম্যাচের ফাংশনটিকে কল করে তবে তাদের মধ্যে একটিতে মানটির অস্তিত্বের জন্য চেকটি অনুপস্থিত।

  • b9317d55a3 দুটি নতুন কী যুক্ত করেছে trie:

    • ' logs/refs/rewritten', এবং
    • ' logs/refs/worktree', ইতিমধ্যে বিদ্যমান ' logs/refs/bisect' এর পরে।
      এর ফলে trieপথ ' logs/refs/' নোডে পরিণত হয়েছিল , যা আগে ছিল না এবং এর কোনও মান সংযুক্ত নেই।
      ' logs/refs/' এর জন্য একটি কোয়েরি এই নোডটি সন্ধান করে এবং তারপরে সেই matchফাংশনটির একটি কলসাইটকে হিট করে যা মানটির অস্তিত্বের জন্য যাচাই করে না এবং এইভাবে matchফাংশনটিকে NULLমান হিসাবে অনুরোধ করে।
  • matchফাংশনটি যখন check_common()একটি NULLমান সহ আহ্বান করা হয়, এটি 0 প্রদান করে, যা সূচিত করে যে কোয়েরি করা পথটি সাধারণ ডিরেক্টরিতে অন্তর্ভুক্ত নয়, শেষ পর্যন্ত ফলস্বরূপ উপরের দেখানো বগাস পথের ফলাফল।

অনুপস্থিত শর্তটি এতে জুড়ুন trie_find()যাতে এটি কোনও অ-বিদ্যমান মানের সাথে মিল ফাংশনটিকে কখনই ডাকে না।

check_common() এরপরে এটি আর পরীক্ষা করতে হবে না যে এটি একটি নন-নুল মান পেয়েছে, সুতরাং সেই শর্তটি সরিয়ে দিন।

আমি বিশ্বাস করি যে অন্য কোনও পথ নেই যা অনুরূপ বগাস আউটপুট তৈরি করতে পারে।

ম্যাচ ফাংশনটির সাথে একটি NULLমান হিসাবে ডাকা হওয়ার ফলস্বরূপ কেবল অন্যান্য চাবি এএএএফসিটি হ'ল ' co' (কীগুলির কারণে ' common' এবং ' config')।

তবে, তারা সাধারণ ডিরেক্টরি অন্তর্ভুক্ত এমন কোনও ডিরেক্টরিতে না থাকায় ফলস্বরূপ কার্যকর বৃক্ষ-নির্দিষ্ট পথটি প্রত্যাশিত।


3
আমি মনে করি এটি শীর্ষস্থানীয় উত্তর হওয়া উচিত, --preserve-mergesযা আপনি চান ঠিক তেমন মার্জগুলি "সংরক্ষণ" করে না, এটি খুব নিষ্পাপ। আপনাকে ইন্টারেক্টিভ রিবেসের নমনীয়তা দেওয়ার সময় এটি আপনাকে মার্জ কমিটগুলি এবং তাদের পিতামাতার সম্পর্কগুলি সংরক্ষণ করার অনুমতি দেয় allows এই নতুন বৈশিষ্ট্যটি দুর্দান্ত & এবং যদি এই ভাল লিখিত এই উত্তরটির জন্য না হয় তবে আমি জানতাম না!
উদাহরণস্বরূপ 31:38

@ ইগুসিয়ার আপনাকে ধন্যবাদ এবং এটি গিট 2.18 ( স্ট্যাকওভারফ্লো.com / search?q=user%3A6309+%22git+ 2.18%22 ), এবং গিট 2.19 ( স্ট্যাকওভারফ্লো.com/search?q=user%3A6309+%22git+ 2.19%) এর একমাত্র বৈশিষ্ট্য নয় 22 )
ভোনসি

1
অত্যন্ত সহায়ক যদি আপনার চারপাশের এই প্রশ্ন / এ, মত করে এর কৃপণ ব্যক্তি সরানোর চেষ্টা করছেন stackoverflow.com/questions/45059039/...
okovko

1
ওহ, আসলেই আমি যা কিছুক্ষণ ধরে খুঁজছিলাম! আমার মতো কেসগুলির জন্য আমার একটি ম্যানুয়াল কাজ রয়েছে যার উপর ভিত্তি করে একজনের উচিত সমস্ত সংশ্লেষে যোগদানের একটি কল্পিত প্রতিশ্রুতি তৈরি করা।
carnicer

সাধারণ গিট একটি সাধারণ প্রশ্ন জিজ্ঞাসা করার সাহস এবং আপনাকে সম্ভবত গিটের ইতিহাস, অভ্যন্তরীণ অ্যালগরিদমগুলি, সমস্ত অগোছালো বাস্তবায়নের বিশদ শিখতে হবে এবং কী চলছে তা বোঝার জন্য আপনার গ্রাফ তত্ত্বেরও একটি মেজর প্রয়োজন।
দিমিত্রিস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.