চেরি কীভাবে কমিটস এর ব্যাপ্তি বেছে নেবেন এবং অন্য একটি শাখায় মার্জ করবেন?


640

আমার কাছে নিম্নলিখিত সংগ্রহস্থল বিন্যাস রয়েছে:

  • মাস্টার শাখা (উত্পাদন)
  • মিশ্রণ
  • পরিশ্রমী

আমি যেটি অর্জন করতে চাই তা হ'ল চেরিটি ওয়ার্কিং শাখা থেকে একাধিক কমিট বেছে নিয়ে ইন্টিগ্রেশন শাখায় মার্জ করে। আমি গিটে নতুন এবং আমি সংগ্রহ করতে না পারার জন্য ঠিক কীভাবে এটি করতে পারি (এক অপারেশনে কমিট রেঞ্জের চেরি পিকিংটি মার্জ নয়)) এই সম্পর্কে কোন পয়েন্টার বা চিন্তা? ধন্যবাদ!


উত্তর:


808

যখন এটি কমিটের একটি সীমাতে আসে, চেরি-বাছাই হয় ব্যবহারিক ছিল না।

কিথ কিমের দ্বারা নীচে উল্লিখিত হিসাবে , গিট 1.7.2+ অনেকগুলি কমিটের চেরি-বাছাই করার দক্ষতার পরিচয় দিয়েছে (তবে ভবিষ্যতে সংযুক্তির জন্য আপনাকে চেরি-পিকিংয়ের ফলাফল সম্পর্কে এখনও সচেতন হওয়া দরকার )

গিট চেরি-পিক "অনেকগুলি কমিট
(যেমন" " cherry-pick A..B" এবং " cherry-pick --stdin") বাছাই করতে শিখেছে , " git revert" যেমনটি rebase [-i]করেছে; যদিও এগুলি উত্তম সিকোয়েন্সিং নিয়ন্ত্রণকে সমর্থন করে না " "।

দামিয়ান মন্তব্য এবং আমাদের সতর্ক করে:

cherry-pick A..Bফর্মটিতে " " এর Aচেয়ে বড় হওয়া উচিতB
যদি তারা ভুল আদেশ হয় তবে কমান্ডটি নিঃশব্দে ব্যর্থ হবে

আপনি যদি (অন্তর্ভুক্ত) মাধ্যমে পরিসরটিBD চয়ন করতে চান তবে তা হবে B^..D। একটি চিত্র হিসাবে
" গিট পূর্ববর্তী কমিটের পরিসর থেকে শাখা তৈরি করবেন? " দেখুন।

যুবস মন্তব্যগুলিতে যেমন উল্লেখ করেছেন :

এটি ধরে নেয় যে Bমূল প্রতিশ্রুতি নয়; unknown revisionঅন্যথায় আপনি একটি " " ত্রুটি পাবেন।

দ্রষ্টব্য: গিট 2.9.x / 2.10 (Q3 2016) হিসাবে, আপনি সরাসরি অনাথ শাখায় (খালি মাথা) অনেকগুলি প্রতিশ্রুতিবদ্ধভাবে চেরি-বাছাই করতে পারেন: " বিদ্যমান শাখাকে গিটের মধ্যে এতিম কীভাবে তৈরি করবেন " দেখুন।


আসল উত্তর (জানুয়ারী ২০১০)

rebase --ontoআরও ভাল হবে, যেখানে আপনি চার্জ বেলি এখানে বর্ণিত হিসাবে আপনার সংহত শাখার শীর্ষে প্রদত্ত প্রতিশ্রুতি পুনরায় খেলুন ।
(এছাড়াও, গিট রিবেস ম্যান পৃষ্ঠাতে "আপনি এখানে কীভাবে একটি শাখার উপর ভিত্তি করে বিষয় শাখাটি অন্য একটি শাখায় প্রতিস্থাপন করবেন" দেখুন, এর ব্যবহারিক উদাহরণ দেখতে git rebase --onto)

যদি আপনার বর্তমান শাখা একীকরণ হয়:

# Checkout a new temporary branch at the current location
git checkout -b tmp

# Move the integration branch to the head of the new patchset
git branch -f integration last_SHA-1_of_working_branch_range

# Rebase the patchset onto tmp, the old location of integration
git rebase --onto tmp first_SHA-1_of_working_branch_range~1 integration

এটি এর মধ্যে সমস্ত কিছু রিপ্লে করবে:

  • first_SHA-1_of_working_branch_range(অতএব ~1) এর পিতামাতার পরে : প্রথম প্রতিশ্রুতি আপনি পুনরায় খেলতে চান
  • " integration" অবধি (যা workingশাখা থেকে আপনি পুনরায় খেলতে চান এমন সর্বশেষ প্রতিশ্রুতির দিকে নির্দেশ করেন )

" tmp" (যা integrationআগে কোথায় নির্দেশ করছিল)

যদি সেগুলির মধ্যে একটির কমিট পুনরায় খেলানো হয় তখন যদি কোনও বিরোধ হয়:

  • হয় এটি সমাধান করুন এবং চালান " git rebase --continue"।
  • অথবা এই প্যাচটি এড়িয়ে যান এবং পরিবর্তে " git rebase --skip" চালান
  • বা " git rebase --abort" দিয়ে সমস্ত জিনিস বাতিল করুন (এবং integrationশাখায় শাখাটি পিছনে রাখুন tmp)

এর পরে rebase --onto, integrationইন্টিগ্রেশন শাখার শেষ প্রতিশ্রুতিতে ফিরে আসবে (এটি tmpশাখা + সমস্ত রিপ্লেড কমিটস)

চেরি-বাছাইয়ের সাথে বা rebase --ontoভুলে যাবেন না যে এখানে বর্ণিত হিসাবে পরবর্তী মার্জগুলিতে এর পরিণতি রয়েছে ।


একটি খাঁটি " cherry-pick" সমাধানটি এখানে আলোচনা করা হয়েছে এবং এর মতো কিছুতে জড়িত:

আপনি যদি কোনও প্যাচ পদ্ধতির ব্যবহার করতে চান তবে "গিট ফর্ম্যাট-প্যাচ | গিট এমএম" এবং "গিট চেরি" আপনার বিকল্প।
বর্তমানে, git cherry-pickশুধুমাত্র একটি একক কমিট গ্রহণ, কিন্তু আপনি পরিসীমা বাছাই করতে চান তাহলে Bমাধ্যমে Dযে হবে B^..DGit শ্রেণীর বা সম্প্রদায়ের ভাষা যাতে,

git rev-list --reverse --topo-order B^..D | while read rev 
do 
  git cherry-pick $rev || break 
done 

তবে যাইহোক, যখন আপনাকে অনেকগুলি কমিট "রিপ্লে" করতে হবে তখন "রিপ্লে" শব্দটি আপনাকে rebaseগিটের " " বৈশিষ্ট্যটি ব্যবহার করার জন্য চাপ দিতে হবে ।


1
আপনার যদি এমন কমিট করে থাকেন যার পিতা-মাতার -mবিকল্প রয়েছে তবে আপনি কীভাবে এই কমিটগুলি পরিচালনা করবেন? বা এই কমিটগুলি ফিল্টার করার কোনও উপায় আছে?
আগস্ট

আপনি এই চেরি-বাছাইয়ের জন্য -mযে -mপ্যারামিটারটি বেছে নিয়েছেন তার দ্বারা রেফারেন্স করা মূল লাইনটি নির্বাচন করে আপনার নিজের জন্য @ অগ হ্যান্ডেল করার কথা রয়েছে ।
ভোনসি

জিনিসটি হ'ল যদি আপনি চেরিটি বিভিন্ন কমিটের বাছাই করে থাকেন তবে এটি চেরিটি পিতামাতার সাথে সঠিকভাবে সম্পাদিত হবে তা সঠিকভাবে বেছে নেবে তবে তারপরে যখন এটি একটি সাধারণ প্রতিশ্রুতিতে আঘাত হানে তখন এটি ব্যর্থ হয় এবং বলে যে প্রতিশ্রুতি একীকরণ নয়। আমার অনুমান যে আমার প্রশ্নটি আরও ভালভাবে অঙ্কিত হয়েছে -mযখন চেরি-বাছাইয়ের সীমাবদ্ধতার সীমাবদ্ধতার সময় পিতামাতার প্রতিশ্রুতিতে আঘাত আসে তখন কীভাবে এটি বিকল্পটি পাস করতে পারে ? ঠিক এখন যদি আমি পাস -mমত git cherry-pick a87afaaf..asfa789 -m 1এটা পরিসীমা মধ্যে সব করে প্রযোজ্য।
আগস্ট

@ অ্যাগ অজানা, আমি সমস্যাটি পুনরুত্পাদন করিনি। আপনার গিট সংস্করণটি কী এবং তাত্ক্ষণিকভাবে দেখা ত্রুটি বার্তাটি হ'ল?
ভোনসি

আহ আমি গিট সংস্করণ ২.6.৪ চালাচ্ছি (অ্যাপল গিট -৩)) ত্রুটি আমি দেখতে কিছু মত হবে error: Commit 8fcaf3b61823c14674c841ea88c6067dfda3af48 is a merge but no -m option was given.আমি আসলে বুঝতে পেরেছি আপনি শুধু পারা git cherry-pick --continueএবং এটি জরিমানা হবে (কিন্তু এটি পিতা বা মাতা অন্তর্ভুক্ত হবে না কমিট)
আগস্ট

136

গিট ভি ১..2.২ হিসাবে চেরি পিক বিভিন্ন সীমাবদ্ধতা গ্রহণ করতে পারে:

git cherry-pickঅনেকগুলি কমিট (যেমন cherry-pick A..Bএবং cherry-pick --stdin) বাছাই করতে শিখেছি , তাই করেছে git revert; rebase [-i]যদিও এগুলি উত্তম সিকোয়েন্সিং নিয়ন্ত্রণটিকে সমর্থন করে না ।


103
দ্রষ্টব্য যে কটি প্রতিশ্রুতিবদ্ধ হবে না (আপনার এটির cherry-pick A..Bপ্রয়োজন হবে A~1..B), এবং যদি কোনও বিবাদ রয়েছে তবে গিটটি স্বয়ংক্রিয়ভাবে রিবেসের মতো চলতে থাকবে না (কমপক্ষে ১.7.৩.১ হিসাবে)
মোথার্ট

3
এটি লক্ষ্য করাও ভাল যে git cherry-pick A..B Cআপনি নির্দোষভাবে এটি প্রত্যাশার মতো কাজ করেন না। এটা তোলে সীমার মধ্যে সবকিছু বাছাই করা হবে না A..Bএবং কমিট C! এটি করার জন্য, আপনাকে প্রথমে git cherry-pick A..Bএবং তারপরে দুটি লাইনে বিভক্ত করতে হবে git cherry-pick C। সুতরাং, যখনই আপনার একটি ব্যাপ্তি রয়েছে, আপনার এটিকে পৃথকভাবে কার্যকর করা দরকার।
মাইক্রোভাইরাস

42

ধরে নিন যে আপনার 2 টি শাখা রয়েছে,

"ব্রাঞ্চএ": আপনি অনুলিপি করতে চান এমন কমিটগুলি অন্তর্ভুক্ত করে ("কমিটএ" থেকে "কমিটবি" তে

"ব্রাঞ্চবি": আপনি যে শাখাটি সম্পাদন করতে চান তা "ব্রাঞ্চএ" থেকে স্থানান্তরিত হবে

1)

 git checkout <branchA>

2) "কমিটএ" এবং "কমিটবি" এর আইডি পান

3)

git checkout <branchB>

4)

git cherry-pick <commitA>^..<commitB>

5) আপনার যদি কোনও বিরোধ হয় তবে তা সমাধান করুন এবং টাইপ করুন

git cherry-pick --continue

চেরি-বাছাই প্রক্রিয়া চালিয়ে যেতে।


মোহন মত কাজ! অনেক ধন্যবাদ!
snukone

28

আপনি কি নিশ্চিত যে আপনি শাখাগুলিকে আসলে মার্জ করতে চান না? যদি ওয়ার্কিং শাখার কিছু সাম্প্রতিক কমিট থাকে যা আপনি চান না তবে আপনি যে পয়েন্টে চান তা কেবল একটি হেড সহ একটি নতুন শাখা তৈরি করতে পারেন।

এখন, আপনি যদি সত্যিই চেরি-বেছে নিতে চান তবে যে কোনও কারণেই হোক না কেন, এটি করার একটি মার্জিত উপায় হ'ল কেবল একটি প্যাচসেটটি টানুন এবং এটি আপনার নতুন ইন্টিগ্রেশন শাখায় প্রয়োগ করুন:

git format-patch A..B
git checkout integration
git am *.patch

গিট-রিবেস যাইহোক যাইহোক এটি করা মূলত এটি তবে গেমগুলি খেলার প্রয়োজন ছাড়াই। আপনার একত্রীকরণের প্রয়োজন হলে আপনি যুক্ত --3wayকরতে git-amপারেন। আপনি যে ডিরেক্টরিটিতে এই কাজটি করছেন সেখানে ইতিমধ্যে অন্য কোনও * .প্যাচ ফাইল নেই তা নিশ্চিত করুন, আপনি যদি নির্দেশাবলী ভারব্যাটিম অনুসরণ করেন ...


1
দ্রষ্টব্য, অন্যান্য সংশোধন ব্যাপ্তির সাথে একই, এটি A^অন্তর্ভুক্ত করা দরকার A
জিনো মেম্পিন

9

আমি সহজেই চলার জন্য ভনসির কোডটিকে একটি সংক্ষিপ্ত ব্যাশ স্ক্রিপ্টে আবৃত করেছিgit-multi-cherry-pick :

#!/bin/bash

if [ -z $1 ]; then
    echo "Equivalent to running git-cherry-pick on each of the commits in the range specified.";
    echo "";
    echo "Usage:  $0 start^..end";
    echo "";
    exit 1;
fi

git rev-list --reverse --topo-order $1 | while read rev 
do 
  git cherry-pick $rev || break 
done 

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


3

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

স্ক্রিপ্ট নীচে।

enter code here



  #!/bin/bash

    # This script will merge the diff between two git revisions to checked out branch
    # Make sure to cd to git source area and checkout the target branch
    # Make sure that checked out branch is clean run "git reset --hard HEAD"


    START=$1
    END=$2

    echo Start version: $START
    echo End version: $END

    mkdir -p ~/temp
    echo > /tmp/status
    #get files
    git --no-pager  diff  --name-only ${START}..${END} > ~/temp/files
    echo > ~/temp/error.log
    # merge every file
    for file in `cat  ~/temp/files`
    do
      git --no-pager diff --binary ${START}..${END} $file > ~/temp/git-diff
      if [ $? -ne 0 ]
      then
#      Diff usually fail if the file got deleted 
        echo Skipping the merge: git diff command failed for $file >> ~/temp/error.log
        echo Skipping the merge: git diff command failed for $file
        echo "STATUS: FAILED $file" >>  /tmp/status
        echo "STATUS: FAILED $file"
    # skip the merge for this file and continue the merge for others
        rm -f ~/temp/git-diff
        continue
      fi

      git apply  --ignore-space-change --ignore-whitespace  --3way --allow-binary-replacement ~/temp/git-diff

      if [ $? -ne 0 ]
       then
#  apply failed, but it will fall back to 3-way merge, you can ignore this failure
         echo "git apply command filed for $file"
       fi
       echo
       STATUS=`git status -s $file`


       if [ ! "$STATUS" ]
       then
#   status is null if the merged diffs are already present in the target file
         echo "STATUS:NOT_MERGED $file"
         echo "STATUS: NOT_MERGED $file$"  >>  /tmp/status
       else
#     3 way merge is successful
         echo STATUS: $STATUS
         echo "STATUS: $STATUS"  >>  /tmp/status
       fi
    done

    echo GIT merge failed for below listed files

    cat ~/temp/error.log

    echo "Git merge status per file is available in /tmp/status"

2

আমি পরীক্ষা করেছি যে কিছু দিন আগে ভঙ্কের খুব স্পষ্ট ব্যাখ্যা পড়ার পরে।

আমার পদক্ষেপ

শুরু

  • শাখা dev : এবিসিডিডিএফজিআইজি
  • শাখা target : এবিসিডি
  • আমিও চাই EনাH

শাখায় E এবং H ধাপ ছাড়াই বৈশিষ্ট্যগুলি অনুলিপি করার পদক্ষেপ dev_feature_wo_E_H

  • git checkout dev
  • git checkout -b dev_feature_wo_E_H
  • git rebase --interactive --rebase-merges --no-ff Dযেখানে আমি dropসামনে রেখেছিলাম EএবংH রিবেস সম্পাদকটিতে
  • বিরোধগুলি সমাধান করুন, চালিয়ে যান এবং commit

dev_feature_wo_E_Hলক্ষ্য রেখে শাখাটি অনুলিপি করার পদক্ষেপ ।

  • git checkout target
  • git merge --no-ff --no-commit dev_feature_wo_E_H
  • বিরোধগুলি সমাধান করুন, চালিয়ে যান এবং commit

কিছু মন্তব্য

  • cherry-pickআগের দিনগুলিতে খুব বেশি হওয়ার কারণে আমি এটি করেছি
  • git cherry-pick শক্তিশালী এবং সহজ কিন্তু

    • এটি সদৃশ কমিট তৈরি করে
    • এবং যখন আমি চাই mergeপ্রাথমিক প্রবর্তনের দ্বন্দ্বগুলি এবং ডুপ্লিকেট কমিটগুলি সমাধান করতে হবে, সুতরাং এক বা দু'য়ের জন্য cherry-pickএটি "চেরি-বাছাই করা" ঠিক আছে তবে আরও এটি খুব ভার্জোজ এবং শাখাটি খুব জটিল হয়ে উঠবে
  • আমার মনে আমি যে পদক্ষেপগুলি করেছি তার থেকে আরও স্পষ্ট git rebase --onto

1
ভাল পোস্ট। সম্মত। এটি আমাকে স্ট্যাকওভারফ্লো . com / a / 38418941 / 6309 এর স্মরণ করিয়ে দেয় । আমি ২০১২ সালে চেরি-পিকিংয়ের ত্রুটিগুলি আবার ফিরে পেয়েছি: stackoverflow.com/a/13524494/6309
ভনসি

1

আর একটি বিকল্প হতে পারে আমাদের কৌশলটির সাথে সীমাবদ্ধতার আগে প্রতিশ্রুতিবদ্ধতার সাথে একত্রীকরণ করা এবং তারপরে সেই পরিসীমাটির শেষ প্রতিশ্রুতি (বা শাখা যখন এটি শেষ হয়) এর সাথে একটি 'সাধারণ' একত্রিত করা। সুতরাং ধরুন কেবল 2345 এবং 3456 মাস্টারের প্রতিশ্রুতিগুলি বৈশিষ্ট্য শাখায় মার্জ করা হবে:

মাস্টার:
1234
2345
3456
4567

বৈশিষ্ট্য শাখায়:

গিট মার্জ -আস আমাদের 4567
গিট মার্জ 2345
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.