গিটে শেষ প্রতিশ্রুতি কীভাবে দুটিতে ভাগ করা যায়


277

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

সমাধানটি হ'ল একরকম ভুল প্রতিশ্রুতি মুছে ফেলা এবং এটি দুটি পৃথক কমিটের সাথে প্রতিস্থাপন করা হবে, একটি হ'ল যে পরিবর্তনটি আমি মাস্টার বেছে নিতে চাইছি এবং অন্যরা সেখানে নেই।

আমি চেষ্টা করেছি

git reset --hard HEAD^

যা সমস্ত পরিবর্তন মুছে ফেলেছে, তাই আমাকে আবার ফিরে যেতে হয়েছিল

git reset ORIG_HEAD

সুতরাং আমার প্রশ্নটি হল, শেষ প্রতিশ্রুতি দুটি পৃথক কমিটে বিভক্ত করার সর্বোত্তম উপায় কী?

উত্তর:


332

আপনার সূচিটি ব্যবহার করা উচিত। একটি মিশ্র পুনরায় সেট করার পরে (" গিট রিসেট হেড ^"), সূচীতে পরিবর্তনগুলির প্রথম সেট যুক্ত করুন, তারপরে তাদের প্রতিশ্রুতিবদ্ধ। তারপরে বাকী প্রতিশ্রুতিবদ্ধ।

কোনও ফাইলের সমস্ত পরিবর্তনকে সূচকে রেখে দিতে আপনি " গিট অ্যাড " ব্যবহার করতে পারেন । আপনি যদি কোনও ফাইলের প্রতিটি সংশোধনী মঞ্চ করতে না চান, তবে তাদের মধ্যে কয়েকটি, আপনি "গিট অ্যাড-পি" ব্যবহার করতে পারেন।

আসুন একটি উদাহরণ দেখুন। ধরা যাক আমার কাছে মাইফাইল নামে একটি ফাইল রয়েছে, এতে নিম্নলিখিত পাঠ্য রয়েছে:

something
something else
something again

আমি এটি আমার শেষ প্রতিশ্রুতিতে সংশোধন করেছি যাতে এখন এটির মতো দেখাচ্ছে:

1
something
something else
something again
2

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

প্রথমে আমি হেডের পিতামাতার কাছে ফিরে যাই, তবে আমি ফাইল সিস্টেমে পরিবর্তনগুলি রাখতে চাই, তাই আমি যুক্তি ছাড়াই "গিট রিসেট" ব্যবহার করি (যা তথাকথিত "মিশ্র" রিসেটটি করবে):

$ git reset HEAD^
myfile: locally modified
$ cat myfile
1
something
something else
something again
2

আমি সূচিতে প্রতিশ্রুতিবদ্ধ পরিবর্তনগুলি যোগ করতে "গিট অ্যাড-পি" ব্যবহার করি (= আমি তাদের পর্যায়ক্রমে)। "গিট অ্যাড-পি" একটি ইন্টারেক্টিভ সরঞ্জাম যা আপনাকে সূচীতে ফাইলের কী পরিবর্তন করা উচিত তা সম্পর্কে জিজ্ঞাসা করে।

$ git add -p myfile
diff --git a/myfile b/myfile
index 93db4cb..2f113ce 100644
--- a/myfile
+++ b/myfile
@@ -1,3 +1,5 @@
+1
 something
 something else
 something again
+2
Stage this hunk [y,n,a,d,/,s,e,?]? s    # split this section into two!
Split into 2 hunks.
@@ -1,3 +1,4 @@
+1
 something
 something else
 something again
Stage this hunk [y,n,a,d,/,j,J,g,e,?]? y  # yes, I want to stage this
@@ -1,3 +2,4 @@
 something
 something else
 something again
+2
Stage this hunk [y,n,a,d,/,K,g,e,?]? n   # no, I don't want to stage this

তারপরে আমি এই প্রথম পরিবর্তনটি করছি:

$ git commit -m "Added first line"
[master cef3d4e] Added first line
 1 files changed, 1 insertions(+), 0 deletions(-)

এখন আমি অন্যান্য সমস্ত পরিবর্তনগুলি করতে পারি (নাম্বার "2" শেষ লাইনে দেওয়া):

$ git commit -am "Added last line"
[master 5e284e6] Added last line
 1 files changed, 1 insertions(+), 0 deletions(-)

আমাদের কী আছে তা দেখার জন্য লগটি পরীক্ষা করে দেখুন:

$ git log -p -n2 | cat
Commit 5e284e652f5e05a47ad8883d9f59ed9817be59d8
Author: ...
Date: ...

    Added last line

Diff --git a/myfile b/myfile
Index f9e1a67..2f113ce 100644
--- a/myfile
+++ b/myfile
@@ -2,3 +2,4 @@
 something
 something else
 something again
+2

Commit cef3d4e0298dd5d279a911440bb72d39410e7898
Author: ...
Date: ...

    Added first line

Diff --git a/myfile b/myfile
Index 93db4cb..f9e1a67 100644
--- a/myfile
+++ b/myfile
@@ -1,3 +1,4 @@
+1
 something
 something else
 something again

1
আমি গত দেড় সপ্তাহ ধরে ধীরে ধীরে মার্চুরিয়াল থেকে গিটিংয়ের অভ্যস্ত হয়ে উঠছি, এবং একটি সহজ শর্টকাট কমান্ড রয়েছে git reset [--patch|-p] <commit>যা আপনি git add -pপুনরায় সেট করার পরে থাকা সমস্যাটি রক্ষা করতে ব্যবহার করতে পারেন । আমি কি সঠিক? গিট 1.7.9.5 ব্যবহার করে।
ট্রোজার

2
এই কৌশলটি সম্পর্কে আরও কিছু এখানে দেওয়া হয়েছে, যদি এটি পুরানো প্রতিশ্রুতি ছিল তবে রিবাইজ সহ, বা আপনাকে এম কমিটে এন কমিটগুলি পরিবর্তন করতে হবে: emmanuelbernard.com/blog/2014/04/14/…
ক্রিস ওয়েস্টিন

84

গোল:

  • আমি একটি অতীত প্রতিশ্রুতি ( splitme) কে দুটি ভাগে ভাগ করতে চাই ।
  • আমি প্রতিশ্রুতিবদ্ধ বার্তা বজায় রাখতে চাই ।

পরিকল্পনা:

  1. একের আগে থেকেই ইন্টারেক্টিভ রিবেস করুন splitme
  2. সম্পাদন করা splitme
  3. ফাইলগুলি দ্বিতীয় প্রতিশ্রুতিতে বিভক্ত করতে পুনরায় সেট করুন।
  4. প্রতিশ্রুতি সংশোধন করুন, বার্তা বজায় রাখা, প্রয়োজনীয় হিসাবে সংশোধন করুন।
  5. প্রথম প্রতিশ্রুতি থেকে বিভক্ত ফাইলগুলি আবার যুক্ত করুন।
  6. একটি নতুন বার্তা দিয়ে প্রতিশ্রুতিবদ্ধ।
  7. রিবেস চালিয়ে যান।

রিবেস স্টেপগুলি (১ এবং)) এড়িয়ে যেতে পারে যদি splitmeসর্বাধিক সাম্প্রতিক প্রতিশ্রুতি থাকে।

git rebase -i splitme^
# mark splitme commit with 'e'
git reset HEAD^ -- $files
git commit --amend
git add $files
git commit -m "commit with just some files"
git rebase --continue

আমি যদি বিভক্ত ফাইলগুলি প্রথমে প্রতিশ্রুতিবদ্ধ করতে চাইতাম তবে আমি আবার -i আবার রিবাজ করব এবং আদেশটি স্যুইচ করব

git rebase -i splitme^
# swap order of splitme and 'just some files'

1
git reset HEAD^ধাঁধা অনুপস্থিত ছিল। -pখুব ভাল সঙ্গে কাজ করে। ধন্যবাদ!
মারিয়াস গেডমিনাস

10
-- $filesযুক্তিটি লক্ষ করা জরুরী git reset। পাথগুলি অতিক্রম করার সাথে সাথে, git resetফাইলগুলি রেফারেন্সড কমিটের অবস্থায় পুনরুদ্ধার করে তবে কোনও কমিট পরিবর্তন করে না। আপনি যদি পথ ছেড়ে দেন, তবে পরবর্তী পদক্ষেপে আপনি যে প্রতিশ্রুতিটি সংশোধন করতে চান তা "হারান"।
ডিউলিন চিহ্নিতকারী

2
এই পদ্ধতিটি আপনাকে গ্রহণযোগ্য উত্তরের তুলনায় আপনার প্রথম প্রতিশ্রুতি বার্তাটি অনুলিপি করতে এবং আটকাতে বাধা দেয়।
ক্যালভিন

এছাড়াও: আপনি যদি সমস্ত ফাইল পুনরায় সেট করতে চান তবে কেবল ব্যবহার করুন git reset HEAD^ -- .। অত্যন্ত আশ্চর্যের বিষয়, এটি ঠিক তেমন আচরণ নয়git reset HEAD^
অ্যালিডোইসউইন

52

বর্তমান কমিটিকে দুটি কমিটে রূপান্তর করতে, আপনি নীচের মতো কিছু করতে পারেন।

উভয় ক্ষেত্রেই:

git reset --soft HEAD^

এটি শেষ প্রতিশ্রুতিটি পূর্বাবস্থায় ফিরে আসে তবে সবকিছুই মঞ্চস্থ করে ফেলে। তারপরে আপনি নির্দিষ্ট ফাইলগুলি আনস্টেজ করতে পারেন:

git reset -- file.file

Filesচ্ছিকভাবে এই ফাইলগুলির অংশগুলি পুনঃস্থাপন করুন:

git add -p file.file

একটি নতুন প্রথম প্রতিশ্রুতিবদ্ধ করুন:

git commit

দ্বিতীয় প্রতিশ্রুতিতে মঞ্চ এবং বাকী পরিবর্তনগুলি প্রতিশ্রুতিবদ্ধ:

git commit -a

বা:

শেষ প্রতিশ্রুতি থেকে সমস্ত পরিবর্তন পূর্বাবস্থায় ফিরিয়ে আনুন এবং স্টেস্টেজ করুন:

git reset HEAD^

নির্বাচিতভাবে প্রথম দফতর পরিবর্তনের মঞ্চস্থ করুন:

git add -p

সমর্পণ

git commit

বাকি পরিবর্তনগুলি প্রতিশ্রুতিবদ্ধ:

git commit -a

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


22

চালান git gui, "সংশোধন সর্বশেষ প্রতিশ্রুতিবদ্ধ" রেডিও বোতামটি নির্বাচন করুন এবং (প্রথম প্রতিশ্রুতিবদ্ধতা থেকে আনাইস্টেজ থেকে কমিট, বা Ctrl- U) যে পরিবর্তনগুলি আপনি প্রথম প্রতিশ্রুতিতে যেতে চান না তা স্টেস্ট করুন un আমি মনে করি এটি সম্পর্কে সবচেয়ে সহজতম উপায়।

আপনি যা করতে পারেন তা হ'ল পরিবর্তন ( git cherry-pick -n) না করে চেরি-বাছাই করুন এবং তারপরে হয় ম্যানুয়ালি বা git guiকমিট করার আগে বাছাই করা পছন্দসই পরিবর্তন সহ ।


15
git reset HEAD^

- - হ্যাড যা আপনার পরিবর্তনগুলি হত্যা করছে।


13

আমি অবাক হলাম কেউ পরামর্শ দেয়নি git cherry-pick -n forum। এটি সর্বশেষতম forumপ্রতিশ্রুতি থেকে পরিবর্তনগুলি পর্যবেক্ষণ করবে কিন্তু সেগুলি প্রতিশ্রুতিবদ্ধ করবে না - আপনি তারপরে resetআপনার প্রয়োজনীয় পরিবর্তনগুলি সরিয়ে ফেলতে পারেন এবং আপনি যা রাখতে চান তা প্রতিশ্রুতিবদ্ধ করতে পারেন।


3

ডাবল-রিভার্ট-স্কোয়াশ পদ্ধতি

  1. আরেকটি প্রতিশ্রুতিবদ্ধ করুন যা অবাঞ্ছিত পরিবর্তনগুলি সরিয়ে দেয়। (যদি এটি ফাইলের প্রতি হয় তবে এটি সত্যই সহজ: git checkout HEAD~1 -- files with unwanted changesএবং git commitযদি তা না হয় তবে মিশ্র পরিবর্তিত ফাইলগুলি আংশিকভাবে মঞ্চস্থ হতে পারে git reset fileএবং git add -p fileমধ্যবর্তী পদক্ষেপ হিসাবে।) এটিকে রিভার্ট বলুন
  2. git revert HEAD- আরেকটি প্রতিশ্রুতিবদ্ধ করুন, যা অবাঞ্ছিত পরিবর্তনগুলিকে আবার যুক্ত করে। এটি ডাবল-রিভার্ট
  3. আপনি এখন যে 2 টি কমিট করেছেন তার মধ্যে প্রথমে স্কোয়াশ করুন বিভক্ত করার প্রতিশ্রুতিতে ( git rebase -i HEAD~3)। এই প্রতিশ্রুতি এখন অনাকাঙ্ক্ষিত পরিবর্তনগুলি থেকে মুক্ত হয়, তাদের জন্য যারা দ্বিতীয় প্রতিশ্রুতিবদ্ধ।

উপকারিতা

  • প্রতিশ্রুতি বার্তা সংরক্ষণ করে
  • এমনকি বিভক্ত করার প্রতিশ্রুতিও যদি শেষটি না হয় তবে কাজ করে। এটি কেবল প্রয়োজন যে অনাকাঙ্ক্ষিত পরিবর্তনগুলি পরবর্তীকালের কমিটগুলির সাথে দ্বন্দ্ব না করে

1

যেহেতু আপনি চেরি-বাছাই করছেন, আপনি এটি করতে পারেন:

  1. cherry-pickএটি --no-commitবিকল্প যুক্ত করা হয়েছে।
  2. resetএবং ব্যবহার add --patch, add --editবা শুধু addপর্যায় কি রাখতে চান করতে।
  3. commit মঞ্চ পরিবর্তন।
    • মূল প্রতিশ্রুতি বার্তাটি পুনরায় ব্যবহার করতে, আপনি কমান্ডটিতে যুক্ত --reuse-message=<old-commit-ref>বা --reedit-message=<old-commit-ref>বিকল্পগুলি করতে পারেন commit
  4. এর সাথে অচিহ্নবদ্ধ পরিবর্তনগুলি দূরে সরিয়ে দিন reset --hard

আর একটি উপায়, মূল প্রতিশ্রুতি বার্তা সংরক্ষণ বা সম্পাদনা:

  1. cherry-pick সাধারণ হিসাবে স্বাভাবিক প্রতিশ্রুতিবদ্ধ।
  2. আপনি চান না এমন পরিবর্তনগুলি বিপরীত করুন এবং addবিপরীতটি মঞ্চস্থ করতে ব্যবহার করুন ।
    • আপনি যা যুক্ত করেছেন তা যদি আপনি মুছে ফেলছেন তবে এই পদক্ষেপটি সহজ হবে তবে আপনি যা সরিয়েছেন বা কোনও পরিবর্তনকে উল্টো করে দিচ্ছেন তা যদি কিছুটা জটিল হয়।
  3. commit --amend চেরি-বাছাই প্রতিশ্রুতি উপর বিপরীত প্রভাব।
    • আপনি আবার একই প্রতিশ্রুতি বার্তা পাবেন, যা আপনি প্রয়োজনীয় হিসাবে রাখা বা সংশোধন করতে পারেন।

0

এটি একটি বৃহত প্রতিশ্রুতিবদ্ধ এবং খুব কম ফাইলের একটি নতুন প্রতিশ্রুতিতে স্থানান্তরিত হওয়া দরকার যেখানে ক্ষেত্রে লক্ষ্যযুক্ত অন্য সমাধান হতে পারে। <path>HEAD এ শেষ প্রতিশ্রুতি থেকে একটি ফাইলের সেট বের করা এবং সমস্ত নতুন প্রতিশ্রুতিতে সরানো হলে এটি কাজ করবে। একাধিক কমিটির প্রয়োজন হলে অন্যান্য সমাধানগুলি ব্যবহার করা যেতে পারে।

প্রথমে মঞ্চযুক্ত এবং অচঞ্চল অঞ্চলগুলিতে প্যাচগুলি তৈরি করুন যাতে কোডটি পরিবর্তনের আগে এবং পরিবর্তনের পরে যথাক্রমে পরিবর্তন করতে হবে:

git reset HEAD^ <path>

$ git status
On branch <your-branch>
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   <path>

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   <path>

কী ঘটবে তা বুঝতে (তীর এবং মন্তব্যগুলি কমান্ডের অংশ নয়):

git diff --cached   -> show staged changes to revert <path> to before HEAD
git diff            -> show unstaged changes to add current <path> changes

<path>সর্বশেষ প্রতিশ্রুতি পরিবর্তনগুলি প্রত্যাবর্তন করুন :

git commit --amend  -> reverts changes on HEAD by amending with staged changes

<path>পরিবর্তনগুলি সহ নতুন প্রতিশ্রুতি তৈরি করুন :

git commit -a -m "New Commit" -> adds new commit with unstaged changes

এটি শেষ প্রতিশ্রুতি থেকে নিষ্কাশিত পরিবর্তনগুলি সমন্বিত একটি নতুন প্রতিশ্রুতি তৈরির প্রভাব ফেলে।

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