গিট সহ একটি নতুন শাখায় সর্বাধিক সাম্প্রতিক প্রতিশ্রুতি (গুলি) সরান


4980

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

আমি কীভাবে এটি থেকে যেতে পারি

master A - B - C - D - E

এই?

newbranch     C - D - E
             /
master A - B 

113
দ্রষ্টব্য: আমি এখানে
বেনজল


6
এখানে মন্তব্যগুলি শুদ্ধ ছিল? আমি জিজ্ঞাসা করি কারণ আমার এই দ্বিবার্ষিকী এই প্রশ্নটি দেখার সময়, আমি সবসময় সেই মন্তব্যে স্ক্রোল করি।
তেজস কালে

উত্তর:


6446

একটি বিদ্যমান শাখায় সরানো

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

git checkout existingbranch
git merge master         # Bring the commits here
git checkout master
git reset --keep HEAD~3  # Move master back by 3 commits.
git checkout existingbranch

--keepএকভাবে কি - বিকল্প কোন স্বাধীন পরিবর্তন সম্পর্কহীন ফাইল, অথবা aborts মধ্যে থাকতে পারে যে যদি যারা পরিবর্তন মুছে ফেলা হতে হবে অপরিবর্তিত git checkoutআছে। যদি এটি বাতিল হয়, git stashআপনার পরিবর্তনগুলি এবং পুনরায় চেষ্টা করুন, বা --hardপরিবর্তনগুলি হারাতে ব্যবহার করুন (এমনকি ফাইলগুলিও যে কমিটগুলির মধ্যে পরিবর্তন হয়নি!)

একটি নতুন শাখায় সরানো হচ্ছে

এই পদ্ধতিটি প্রথম কমান্ড ( git branch newbranch) দিয়ে একটি নতুন শাখা তৈরি করে কাজ করে তবে এটিতে স্যুইচ না করে। তারপরে আমরা বর্তমান শাখাটি (মাস্টার) পিছনে রোল করব এবং কাজ চালিয়ে যেতে নতুন শাখায় স্যুইচ করব।

git branch newbranch      # Create a new branch, containing all current commits
git reset --keep HEAD~3   # Move master back by 3 commits (Make sure you know how many commits you need to go back)
git checkout newbranch    # Go to the new branch that still has the desired commits
# Warning: after this it's not safe to do a rebase in newbranch without extra care.

তবে নিশ্চিত হন যে কতজন ফিরে যেতে চায় its বিকল্পভাবে, পরিবর্তে HEAD~3, আপনি কেবল origin/masterফিরে যেতে চান এমন কমিটের হ্যাশ (বা রেফারেন্সের মতো ) সরবরাহ করতে পারেন, যেমন:

git reset --keep a1b2c3d4

সতর্কতা: গিট সংস্করণ ২.০ সহ এবং তার পরে যদি আপনি পরে git rebaseমূল ( master) শাখায় নতুন শাখা করেন --no-fork-pointতবে মাস্টার শাখা থেকে সরিয়ে নেওয়া কমিটগুলি হারাতে এড়াতে আপনার রিবাসের সময় একটি স্পষ্ট বিকল্পের প্রয়োজন হতে পারে। রয়ে branch.autosetuprebase alwaysসেট এই সম্ভাবনা বেশি করে তোলে। দেখুন জন Mellor এর উত্তর জানার জন্য।


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

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

142
@ জোনাথন ডুমাইন: কারণ আমি পুরানো শাখা থেকে কমিটগুলি সরিয়ে নেওয়ার আগে নতুন শাখা তৈরি করেছি। তারা এখনও সেখানে নতুন শাখায় রয়েছে।
সিকোড়া

86
গিটের শাখাগুলি কেবল চিহ্নিতকারী যা ইতিহাসে প্রতিশ্রুতি দেয়, সেখানে ক্লোন করা, তৈরি বা মোছার কিছুই নেই (চিহ্নিতকারী ব্যতীত)
নিটল

218
এছাড়াও নোট করুন: আপনার কাজের অনুলিপিতে অনির্দিষ্ট পরিবর্তনের সাথে এটি করবেন না! এই শুধু আমাকে বিট! :(
অ্যাডাম ট

1038

এটি কেন কাজ করে তা নিয়ে ভাবছেন (যেমনটি আমি আগে ছিলাম):

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

A-B-C-D-E (HEAD)
        ↑
      master

পরে git branch newBranch:

    newBranch
        ↓
A-B-C-D-E (HEAD)
        ↑
      master

পরে git reset --hard HEAD~2:

    newBranch
        ↓
A-B-C-D-E (HEAD)
    ↑
  master

যেহেতু একটি শাখা কেবলমাত্র পয়েন্টার, তাই মাস্টার শেষ প্রতিশ্রুতিতে নির্দেশিত। আপনি যখন নতুন ব্রাঞ্চ তৈরি করেছেন , আপনি শেষ প্রতিশ্রুতিতে কেবল নতুন পয়েন্টার তৈরি করেছেন। তারপরে git resetআপনি মাস্টার পয়েন্টারটি ব্যবহার করে দুটি পদক্ষেপ ফিরিয়ে নিয়েছেন। তবে যেহেতু আপনি নিউ ব্রাঞ্চ স্থানান্তরিত করেননি , এখনও এটি মূলত যে প্রতিশ্রুতিবদ্ধ তা নির্দেশ করে।


55
git push origin master --forceমূল সংগ্রহস্থলটিতে পরিবর্তনটি দেখানোর জন্য আমারও কিছু করা দরকার ।
দিনান

9
এই উত্তরটির ফলে প্রতিশ্রুতিগুলি হারাতে পারে: পরের বার আপনি git rebase, 3 টি কমিট চুপচাপ বাদ দিয়ে দেবেন newbranch। বিশদ এবং নিরাপদ বিকল্পের জন্য আমার উত্তর দেখুন ।
জন মেলর

14
@ জন, এটি বাজে কথা। আপনি কী করছেন তা না জেনে রেবসিংয়ের ফলে প্রতিশ্রুতি হারানো হয়। আপনি যদি প্রতিশ্রুতি হারিয়ে ফেলেন তবে আমি আপনার জন্য দুঃখিত, কিন্তু এই উত্তরটি আপনার কমিটগুলি হারাতে পারেনি। উল্লেখ্য যে origin/masterউপরের চিত্রটিতে প্রদর্শিত হবে না। আপনি যদি উপরে চাপিয়ে দেন origin/masterএবং তারপরে উপরের পরিবর্তনগুলি করেন তবে অবশ্যই জিনিসগুলি মজাদার হয়ে উঠবে। তবে এটি একজন "ডাক্তার, যখন আমি এই" ধরণের সমস্যা করি তখন ব্যথা হয়। এবং আসল প্রশ্নটি যা জিজ্ঞাসা করেছে তার সুযোগের বাইরে। আমি আপনাকে এটিকে হাইজ্যাকের পরিবর্তে আপনার পরিস্থিতি অন্বেষণ করতে নিজের প্রশ্ন লিখতে পরামর্শ দিচ্ছি।
রায়ান লুন্ডি

1
@ জন, আপনার উত্তরে আপনি বলেছিলেন "এটি করবেন না! git branch -t newbranch"। ফিরে যান এবং উত্তরগুলি আবার পড়ুন। কেউ তা করার পরামর্শ দেয়নি
রায়ান লুন্ডি

1
@ ক্যারলেসা, অবশ্যই, তবে আপনি যদি প্রশ্নটির চিত্রটি দেখেন তবে এটি স্পষ্ট যে তারা newbranchতাদের বিদ্যমান স্থানীয় masterশাখাটি ভিত্তিক হতে চায় । গৃহীত উত্তরটি সম্পাদন করার পরে, ব্যবহারকারী যখন চলতে git rebaseশুরু newbranchকরবে তখন গিট তাদের মনে করিয়ে দেবে যে তারা প্রবাহ শাখাটি সেট করতে ভুলে গেছে, তাই তারা git branch --set-upstream-to=masterতখন চালাবে git rebaseএবং একই সমস্যা থাকবে have তারা পাশাপাশি git branch -t newbranchপ্রথম স্থানে ব্যবহার করতে পারে ।
জন মেলর

454

সাধারণভাবে ...

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

ওপি যা চায় তা অর্জন করতে এটি একটি ২-পদক্ষেপ প্রক্রিয়া:

পদক্ষেপ 1 - নোটটি যা আপনি চান তার উপর মাস্টার থেকে কমিট করে newbranch

এক্সিকিউট

git checkout master
git log

(3 বলুন) হ্যাশগুলি নোট করুন আপনি যেটি করতে চান তা কমিট করে newbranch। এখানে আমি ব্যবহার করব:
সি কমিট: 9aa1233
ডি কমিট: 453ac3d
ই কমিট:612ecb3

দ্রষ্টব্য: আপনি প্রথম সাতটি অক্ষর বা সম্পূর্ণ কমিট হ্যাশ ব্যবহার করতে পারেন

পদক্ষেপ 2 - এগুলি রাখুন newbranch

git checkout newbranch
git cherry-pick 612ecb3
git cherry-pick 453ac3d
git cherry-pick 9aa1233

বা (গিট 1.7.2+ এ, ব্যাপ্তি ব্যবহারের ক্ষেত্রে)

git checkout newbranch
git cherry-pick 612ecb3~1..9aa1233

গিট চেরি-পিক এই তিনটি কমিটকে নিউব্র্যাঞ্চে প্রয়োগ করে।


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

6
এটি খুব ভালভাবে কাজ করে যদি আপনি দুর্ঘটনাক্রমে ভুল, অ-মাস্টার শাখা প্রতিশ্রুতিবদ্ধ হন, যখন আপনার একটি নতুন বৈশিষ্ট্য শাখা তৈরি করা উচিত ছিল।
জুলিয়ান্ক

5
কিছু পরিস্থিতিতে দরকারী পদ্ধতির জন্য +1 এটি কেবলমাত্র যদি নিজের নিজস্ব প্রতিশ্রুতিগুলি (অন্যদের সাথে ছেদ করা হয়) একটি নতুন শাখায় টানতে চান তবে এটি ভাল।
টাইলার ভি।

7
এটি আরও ভাল উত্তর। আপনি যে কোনও শাখায় কমিটগুলি সরিয়ে নিতে পারেন।
স্কাইওয়ান্ডার

8
চেরি বাছাইয়ের ক্রমটি কি গুরুত্বপূর্ণ?
কন সাইক

328

এটি করার আরেকটি উপায়, মাত্র 2 কমান্ড ব্যবহার করে। আপনার বর্তমান কাজের গাছ অক্ষত রাখে।

git checkout -b newbranch # switch to a new branch
git branch -f master HEAD~3 # make master point to some older commit

পুরানো সংস্করণ - আমি জানার আগেgit branch -f

git checkout -b newbranch # switch to a new branch
git push . +HEAD~3:master # make master point to some older commit 

করতে সক্ষম হচ্ছে pushথেকে .একটা চমৎকার কৌতুক জানতে হয়।


1
বর্তমান ডিরেক্টরি আমার ধারণা আপনি কেবল শীর্ষ ডিরেক্টরিতে থাকলে এটি কাজ করবে।
আরগায়ার

1
স্থানীয় ধাক্কা গ্রান্ট-প্ররোচিত, তবে প্রতিবিম্বের উপর, এখানে কীভাবে এটি আলাদা git branch -f?
jthill

2
@ জেরার্ডসেক্সটনের .বর্তমান পরিচালক। গিট রিমোটস বা জিআইটি ইউআরএলগুলিতে চাপ দিতে পারে। path to local directoryগিট ইউআরএল সিনট্যাক্স সমর্থিত। জিআইটি ইউআরএলএস বিভাগটি দেখুন git help clone
দুর্বল করুন

31
আমি জানি না কেন এটি উচ্চতর রেট দেওয়া হয় না। ডেড সহজ, এবং গিট রিসেটের ছোট তবে সম্ভাব্য বিপদটি ছাড়াই --হরড।
গডস্মিথ

4
@ গুডস্মিথ আমার অনুমান যে লোকেরা আরও দুটি অস্পষ্ট কমান্ডের চেয়ে তিনটি সাধারণ কমান্ড পছন্দ করে। এছাড়াও, শীর্ষস্থানীয় ভোট দেওয়া উত্তরগুলি প্রথমে প্রদর্শিত হওয়ার প্রকৃতির দ্বারা আরও উত্সাহ পেতে পারে।
JS_Riddler

321

বেশিরভাগ পূর্ববর্তী উত্তরগুলি বিপজ্জনকভাবে ভুল!

এটা করো না:

git branch -t newbranch
git reset --hard HEAD~3
git checkout newbranch

পরের বার হিসাবে আপনি চালিত git rebase(বা git pull --rebase) সেই 3 টি কমিট চুপচাপ বাদ দেওয়া হবে newbranch! (নীচে ব্যাখ্যা দেখুন)

পরিবর্তে এটি করুন:

git reset --keep HEAD~3
git checkout -t -b newbranch
git cherry-pick ..HEAD@{2}
  • প্রথমে এটি 3 অতি সাম্প্রতিক কমিটগুলি বাদ দেয় ( --keepপছন্দ মতো --hardতবে নিরাপদ, যেমন আপত্তিজনক পরিবর্তনগুলি ছুঁড়ে ফেলার পরিবর্তে ব্যর্থ হয়)।
  • তারপর এটি কাঁটাচামচ বন্ধ newbranch
  • তারপরে এটি চেরি-পিকগুলি সেই 3 টি প্রতিশ্রুতি ফিরে আসে newbranch। যেহেতু সেগুলি আর কোনও শাখার দ্বারা রেফারেন্স করা হয় না, এটি গিটের রিফ্লোগ ব্যবহার করে : HEAD@{2}এটি প্রতিশ্রুতি যা HEAD2 ক্রিয়াকলাপ আগে উল্লেখ করা হয়েছিল, অর্থাৎ আমরা আগে 1. পরীক্ষা করে দেখেছিnewbranch এবং ২ git resetটি কমিট বাতিল করার জন্য ব্যবহৃত হয়েছিল।

সতর্কতা: রিফ্লোগটি ডিফল্টরূপে সক্ষম করা হয়েছে, তবে আপনি যদি ম্যানুয়ালি এটিকে অক্ষম করে থাকেন (যেমন "বেয়ার" গিট সংগ্রহস্থল ব্যবহার করে), আপনি চালানোর পরে 3 টি প্রত্যাবর্তন ফিরে পেতে সক্ষম হবেন না git reset --keep HEAD~3

এমন একটি বিকল্প যা রিফ্লগের উপর নির্ভর করে না:

# newbranch will omit the 3 most recent commits.
git checkout -b newbranch HEAD~3
git branch --set-upstream-to=oldbranch
# Cherry-picks the extra commits from oldbranch.
git cherry-pick ..oldbranch
# Discards the 3 most recent commits from oldbranch.
git branch --force oldbranch oldbranch~3

(যদি আপনি পছন্দ করেন তবে লিখতে পারেন @{-1}- পূর্বে চেক আউট শাখা - পরিবর্তে oldbranch)


প্রযুক্তিগত ব্যাখ্যা

কেন git rebaseপ্রথম উদাহরণের পরে 3 টি কমিট বাতিল করবেন ? এটি কারণ git rebaseকোনও যুক্তি ছাড়াই --fork-pointডিফল্টরূপে বিকল্পটি সক্ষম করে , যা প্রবাহের শাখাকে জোর-ধাক্কা দেওয়ার বিরুদ্ধে দৃ ref় হতে চেষ্টা করার জন্য স্থানীয় রেফলগ ব্যবহার করে।

মনে করুন আপনি এম 1, এম 2, এম 3 দিয়ে থাকে তখন আপনি মূল / মাস্টারকে শাখা থেকে বের করে দিয়েছেন, তারপরে তিনটি প্রতিশ্রুতিবদ্ধ করেছেন:

M1--M2--M3  <-- origin/master
         \
          T1--T2--T3  <-- topic

তবে তারপরে কেউ এম 2 মুছে ফেলার জন্য জোর-পুশিং উত্স / মাস্টার দ্বারা ইতিহাস পুনর্লিখন করেছেন:

M1--M3'  <-- origin/master
 \
  M2--M3--T1--T2--T3  <-- topic

আপনার স্থানীয় রিফ্লগ ব্যবহার করে, git rebaseআপনি দেখতে পাচ্ছেন যে আপনি উত্স / মাস্টার শাখার পূর্বের অবতার থেকে কাঁটাচামচ হয়ে গেছেন এবং সুতরাং এম 2 এবং এম 3 কমিটগুলি আসলে আপনার বিষয় শাখার অংশ নয়। সুতরাং এটি যুক্তিসঙ্গতভাবে ধরে নিয়েছে যে যেহেতু এম 2 টি উজানের শাখা থেকে সরানো হয়েছে, তাই বিষয় শাখাটি পুনরায় সাজানোর পরে আপনি আপনার বিষয় শাখায় আর চান না:

M1--M3'  <-- origin/master
     \
      T1'--T2'--T3'  <-- topic (rebased)

এই আচরণটি বোধগম্য হয় এবং অব্যাহতি দেওয়ার সময় সাধারণত সঠিক জিনিস।

নিম্নলিখিত কারণগুলি ব্যর্থ হওয়ার কারণ:

git branch -t newbranch
git reset --hard HEAD~3
git checkout newbranch

কারণ তারা রিফলগটিকে ভুল অবস্থায় ফেলে। গিট দেখায় newbranchযে 3 টি কমিটস অন্তর্ভুক্ত একটি সংশোধনীতে প্রবাহ শাখাটি কাঁটাচামচ করেছে, তারপরে reset --hardকমিটগুলি অপসারণের জন্য প্রবাহের ইতিহাসটি আবারও লিখেছেন, এবং পরবর্তী সময় আপনি যখন git rebaseএটি চালাবেন তখন এগুলি উজান থেকে সরানো অন্য কোনও প্রতিশ্রুতির মতোই তাদের বাতিল করে দেবে।

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

আরও বিশদের --fork-pointজন্য গিট রিবেস এবং গিট মার্জ-বেস ডক্সের সংজ্ঞা দেখুন।


14
এই উত্তরটি বলে "এটি করবেন না!" কেউ এমন কিছু করারও পরামর্শ দিচ্ছে না যা করার কথা।
রায়ান লুন্ডি

3
অধিকাংশ মানুষ প্রকাশিত ইতিহাস পুনর্লিখন না, বিশেষ করে master। সুতরাং না, এগুলি বিপজ্জনকভাবে ভুল নয়।
ওয়াল্ফ

4
@ কাইরলেস, -tআপনি উল্লেখ করেছেন git branchআপনি যদি git config --global branch.autosetuprebase alwaysসেট করে থাকেন তবে তা স্পষ্টভাবে ঘটে । এমনকি যদি নাও হয়, আমি ইতিমধ্যে আপনাকে বুঝিয়ে দিয়েছি যে এই কমান্ডগুলি সম্পাদন করার পরে আপনি যদি ট্র্যাকিং সেটআপ করেন তবে একই সমস্যা দেখা দেয়, কারণ ওপি সম্ভবত তাদের প্রশ্নটি করার ইচ্ছা করে।
জন মেলোর

2
@ রকলি, হ্যাঁ, এই জাতীয় পরিস্থিতি ঠিক করার সাধারণ উপায়টি একটি নিরাপদ সূচনা পয়েন্ট থেকে একটি নতুন শাখা (নিউ ব্র্যাঞ্চ 2) তৈরি করা এবং তারপরে আপনি যে সমস্ত কমিটগুলি রাখতে চান তা চেরি-বাছাই করুন (ব্যাডনব্রাঞ্চ থেকে নিউব্র্যাঞ্চ ২)। চেরি-বাছাই কমিটিগুলিকে নতুন হ্যাশ দেবে, সুতরাং আপনি নিরাপদে নতুনব্র্যাঞ্চ 2 পুনর্বার করতে সক্ষম হবেন (এবং এখন ব্যাডনব্র্যাঞ্চ মুছতে পারেন)।
জন মেলোর

2
@ ওয়াল্ফ, আপনি ভুল বুঝে গেছেন: গিট রিবেস তাদের ইতিহাস পুনর্লিখনিত প্রবাহের বিরুদ্ধে শক্তিশালী করার জন্য ডিজাইন করা হয়েছে। দুর্ভাগ্যক্রমে, এই দৃust়তার পার্শ্ব প্রতিক্রিয়া সকলকে প্রভাবিত করে, এমনকি যদি তারা বা তাদের উজানে কখনও ইতিহাস পুনরায় লেখেন না।
জন মেলোর

150

গিট স্ট্যাশ ব্যবহার করে অনেক সহজ সমাধান

ভুল শাখায় প্রতিশ্রুতিবদ্ধ করার জন্য এখানে একটি আরও সহজ সমাধান। masterতিনটি ভুল কমিট রয়েছে এমন শাখায় শুরু হচ্ছে :

git reset HEAD~3
git stash
git checkout newbranch
git stash pop

কখন এটি ব্যবহার করবেন?

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

লাইন সংখ্যা দ্বারা এটি কি করে

  1. সর্বশেষ তিনটি কমিট (এবং তাদের বার্তা) পূর্বাবস্থায় ফিরে আসে master, তবুও সমস্ত কার্যকরী ফাইল অক্ষত রেখে দেয়
  2. কার্যকারী সমস্ত masterগাছ পরিবর্তন থেকে দূরে রাখে, কার্যকারী গাছটিকে হ্যাড ~ 3 রাজ্যের ঠিক সমান করে তোলে
  3. একটি বিদ্যমান শাখায় স্যুইচ করে newbranch
  4. আপনার কার্যকারী ডিরেক্টরিতে স্ট্যাশড পরিবর্তনগুলি প্রয়োগ করে এবং স্ট্যাশ পরিষ্কার করে

আপনি এখন ব্যবহার করতে পারেন git addএবং git commitআপনি যেমনটি সাধারণভাবে করেন তেমন। সমস্ত নতুন কমিট যোগ করা হবে newbranch

এটি কি করে না

  • এটি এলোমেলো অস্থায়ী শাখাগুলি আপনার গাছকে বিশৃঙ্খল করে ছাড়বে না
  • এটি ভুল প্রতিশ্রুতি বার্তাগুলি সংরক্ষণ করে না, সুতরাং আপনাকে এই নতুন প্রতিশ্রুতিতে একটি নতুন প্রতিশ্রুতি বার্তা যুক্ত করতে হবে
  • হালনাগাদ! পূর্ববর্তী প্রতিশ্রুতিটির প্রতিশ্রুতি বার্তাটি প্রয়োগ করার জন্য আপনার কমান্ড বাফারের মাধ্যমে স্ক্রোল করতে আপ-তীর ব্যবহার করুন (ধন্যবাদ @ মার্ক)

গোল

ওপিতে উল্লেখ করা হয়েছে যে লক্ষ্য পরিবর্তন না করে "এই প্রতিশ্রুতিবদ্ধ হওয়ার পূর্বেই মাষ্টারকে ফিরিয়ে নেওয়া" ছিল এবং এই সমাধান এটি করে does

আমি ঘটনাক্রমে masterপরিবর্তে নতুন কমিট করার পরে সপ্তাহে অন্তত একবার এটি করি develop। সাধারণত আমার কেবল রোলব্যাকের প্রতিশ্রুতি থাকে যে ক্ষেত্রে git reset HEAD^লাইন 1 এ ব্যবহার করা কেবল একটি প্রতিশ্রুতি রোলব্যাক করার একটি সহজ উপায়।

আপনি যদি মাস্টারের পরিবর্তনগুলি প্রবাহিত করেন তবে এটি করবেন না

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


4
ধন্যবাদ, আমি এখানে এসে পৌঁছানোর জন্য অতীত / অনেক কিছু পড়েছি বলে খুব আনন্দিত, কারণ এটি আমার পক্ষেও একটি সাধারণ সাধারণ ব্যবহারের কারণ। আমরা কি এতটা নাটক?
জিম ম্যাক

6
আমি মনে করি যে আমরা সম্পূর্ণরূপে সাধারণ এবং "উফ আমি ভুলক্রমে মাস্টার হিসাবে প্রেরণ করেছি" মুষ্টিমেয় বা কম কমিটকে ফিরিয়ে আনার জন্য সবচেয়ে সাধারণ ব্যবহার-মামলা- ভাগ্যবান এই সমাধানটি এত সহজ যে আমি এখন এটি মুখস্ত করেছি।
স্লাম

9
এটি গ্রহণযোগ্য উত্তর হওয়া উচিত। এটি সোজা, বুঝতে সহজ এবং সহজে মনে রাখা সহজ
সিনা মাদানী

1
স্ট্যাশিং প্রয়োজনীয় বলে আমি মনে করি না। আমি এটি ছাড়া কেবল এটি করেছি এবং ভাল কাজ করেছি।
একটি ক্যাম্পোস

1
আপনি যদি আপনার সিটিএল (কমান্ড লাইন) ইতিহাসে থাকেন তবে আপনি সহজেই আপনার প্রতিশ্রুতিবদ্ধ বার্তাগুলি ফিরে পেতে পারেন। আমার যে কমান্ড git addএবং git commitকমান্ডগুলি ব্যবহার হয়েছিল সেগুলি উভয়ই হ'ল আমার তীরটি হিট করে কয়েকবার প্রবেশ করানো এবং গম্ভীর হওয়া! সবকিছু ফিরে ছিল, কিন্তু এখন ডান শাখায়।
লুক গিডিওন

30

এটি প্রযুক্তিগত দিক থেকে তাদের "সরানো" নয় তবে এর একই প্রভাব রয়েছে:

A--B--C  (branch-foo)
 \    ^-- I wanted them here!
  \
   D--E--F--G  (branch-bar)
      ^--^--^-- Opps wrong branch!

While on branch-bar:
$ git reset --hard D # remember the SHAs for E, F, G (or E and G for a range)

A--B--C  (branch-foo)
 \
  \
   D-(E--F--G) detached
   ^-- (branch-bar)

Switch to branch-foo
$ git cherry-pick E..G

A--B--C--E'--F'--G' (branch-foo)
 \   E--F--G detached (This can be ignored)
  \ /
   D--H--I (branch-bar)

Now you won't need to worry about the detached branch because it is basically
like they are in the trash can waiting for the day it gets garbage collected.
Eventually some time in the far future it will look like:

A--B--C--E'--F'--G'--L--M--N--... (branch-foo)
 \
  \
   D--H--I--J--K--.... (branch-bar)

1
আপনি কি rebaseএকই জিনিস ব্যবহার করতে পারবেন না ?
বার্গি

হ্যাঁ আপনি rebaseউপরের দৃশ্যে বিচ্ছিন্ন শাখায় বিকল্পভাবে ব্যবহার করতে পারেন ।
সুকিমা

24

ইতিহাস পুনর্লিখন না করে এটি করার জন্য (যেমন আপনি ইতিমধ্যে কমিটগুলিকে ঠেলে দিয়েছেন):

git checkout master
git revert <commitID(s)>
git checkout -b new-branch
git cherry-pick <commitID(s)>

উভয় শাখা তখন জোর করেই ঠেলা যায়!


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

1
সে কারণেই আমি চেরি-বাছাই করে শেষে একটি নতুন শাখায় চলে এসেছি। এইভাবে গিট তাদেরকে নতুন কমিট হিসাবে দেখবে, যা আপনার সমস্যা সমাধান করে।
teh_senaus

এটি প্রথমে যেমন মনে হয় তার থেকে আরও বিপজ্জনক, যেহেতু আপনি সত্যিকার অর্থে এই রাজ্যের প্রভাবগুলি না বুঝেই সংগ্রহস্থলের ইতিহাসের অবস্থার পরিবর্তন করছেন।
মাকোটো

5
আমি আপনার যুক্তি অনুসরণ করি না - এই উত্তরের মূল বক্তব্যটি হ'ল আপনি ইতিহাস পরিবর্তন করছেন না, কেবল নতুন কমিট যুক্ত করছেন (যা কার্যকরভাবে পরিবর্তনগুলি পূর্বাবস্থায় ফিরিয়ে আনবে)। এই নতুন কমিটগুলি সাধারণ হিসাবে ধাক্কা দেওয়া এবং একত্রীকরণ করা যেতে পারে।
teh_senaus

13

শুধু এই পরিস্থিতি ছিল:

Branch one: A B C D E F     J   L M  
                       \ (Merge)
Branch two:             G I   K     N

আমি অভিনয় করেছি:

git branch newbranch 
git reset --hard HEAD~8 
git checkout newbranch

আমি প্রত্যাশা করেছিলাম যে প্রতিশ্রুতিবদ্ধ আমিই প্রধান হব, তবে এখনই প্রতিশ্রুতিবদ্ধ ...

ইতিহাসের সঠিক জায়গায় অবতীর্ণ হওয়া নিশ্চিত হওয়া কমিটের হ্যাশ দিয়ে কাজ করা সহজ easier

git branch newbranch 
git reset --hard #########
git checkout newbranch

7

আমি এ থেকে কীভাবে যেতে পারি

A - B - C - D - E 
                |
                master

এই?

A - B - C - D - E 
    |           |
    master      newbranch

দুটি কমান্ড সহ

  • গিট শাখা -এম মাস্টার নিউ ব্র্যাঞ্চ

দান

A - B - C - D - E 
                |
                newbranch

এবং

  • গিট শাখা মাস্টার বি

দান

A - B - C - D - E
    |           |
    master      newbranch

হ্যাঁ, এটি কাজ করে এবং বেশ সহজ। সোর্সট্রি জিইউআই গিট শেলের পরিবর্তনগুলি সম্পর্কে কিছুটা বিভ্রান্ত, তবে আনার পরে এটি আবার ঠিক আছে।
লারস কে।

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

4

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

  1. বর্তমানের একটি নতুন শাখা তৈরি করুন :git branch new-branch-name

  2. ধাক্কা আপনার নতুন শাখা :git push origin new-branch-name

  3. আপনার পুরাতন (বর্তমান) শাখাটি শেষ ধাক্কা / স্থিতিশীল অবস্থায় ফিরিয়ে দিন :git reset --hard origin/old-branch-name

কিছু লোকের upstreamsপরিবর্তে অন্যগুলিও রয়েছে origin, তাদের যথাযথ ব্যবহার করা উচিতupstream


3

1) একটি নতুন শাখা তৈরি করুন, যা আপনার সমস্ত পরিবর্তনকে নতুন_বাঞ্চে সরিয়ে দেয়।

git checkout -b new_branch

2) তারপরে পুরানো শাখায় ফিরে যান।

git checkout master

3) গিট রিবেস করুন

git rebase -i <short-hash-of-B-commit>

4) তারপরে খোলা সম্পাদকটিতে সর্বশেষ 3 কমিটের তথ্য রয়েছে।

...
pick <C's hash> C
pick <D's hash> D
pick <E's hash> E
...

5) পরিবর্তন করুন pickথেকে dropঐ 3 করে সবকিছুতে আছেন। তারপরে সম্পাদকটি সংরক্ষণ করুন এবং বন্ধ করুন।

...
drop <C's hash> C
drop <D's hash> D
drop <E's hash> E
...

6) এখন সর্বশেষ 3 টি কমিট বর্তমান শাখা ( master) থেকে সরানো হয়েছে । এখন +শাখার নামের আগে চিহ্ন সহ জোর করে শাখাটি চাপুন ।

git push origin +master

2

আপনি এটি করতে পারেন মাত্র 3 সহজ পদক্ষেপ যা আমি ব্যবহার করেছি।

1) নতুন শাখা তৈরি করুন যেখানে আপনি সাম্প্রতিক আপডেটটি প্রতিশ্রুতিবদ্ধ করতে চান।

git branch <branch name>

2) নতুন শাখায় কমিট করার জন্য সাম্প্রতিক কমিট আইডি সন্ধান করুন।

git log

3) সেই প্রতিশ্রুতিবদ্ধ আইডি নোটটি অনুলিপি করুন যে সর্বাধিক সাম্প্রতিক কমিটের তালিকা উপরে রয়েছে। যাতে আপনি আপনার প্রতিশ্রুতি খুঁজে পেতে পারেন। আপনি বার্তার মাধ্যমে এটি পেতে।

git cherry-pick d34bcef232f6c...

আপনি কিছু রেঞ্জ আইডি প্রদান করতে পারেন।

git cherry-pick d34bcef...86d2aec

এখন আপনার কাজ শেষ। আপনি যদি সঠিক আইডি এবং সঠিক শাখা বেছে নিয়ে থাকেন তবে আপনি সাফল্য পাবেন। তাই আগে এই সাবধানে না। অন্যথায় অন্য একটি সমস্যা দেখা দিতে পারে।

এখন আপনি আপনার কোড টিপতে পারেন

git push


0

এটি করার আরেকটি উপায়:

[1]master আপনার শাখার নাম পরিবর্তন করুন newbranch(ধরে নিবেন আপনি masterশাখায় রয়েছেন):

git branch -m newbranch

[2]master আপনি যে প্রতিশ্রুতিবদ্ধ তা থেকে শাখা তৈরি করুন :

git checkout -b master <seven_char_commit_id>

যেমন গিট চেকআউট-বি মাস্টার a34bc22

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