পুশ করার আগে একাধিক কমিটের সম্মিলন


130

এই প্রশ্নটি কীভাবে এই কাজটি সম্পাদন করতে পারে তা নয়, গিটের সাথে এটি করা ভাল বা খারাপ অনুশীলন কিনা।

বিবেচনা করুন যে স্থানীয়ভাবে আমি মাস্টার শাখায় বেশিরভাগ কাজ করি তবে আমি একটি টপিকাল শাখা তৈরি করেছি আমি "শীর্ষস্থানীয়_এক্সফাইচার" বলব। "টপিকাল_এক্সফিজার" এ কাজ করার এবং মাস্টার ব্রাঞ্চে অন্য কাজ করার জন্য পিছনে স্যুইচ করার প্রক্রিয়াতে দেখা গেছে যে আমি "টপিক্যাল_এক্স ফিচার" শাখায় একাধিক প্রতিশ্রুতিবদ্ধ করেছি, তবে প্রতিটি প্রতিশ্রুতির মধ্যে আমি কোনও কাজ করি নি ধাক্কা।

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

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

উত্তর:


139

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

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

আপনি যদি একসাথে বেশ কয়েকটি কমিটি স্কোয়াশ করতে চান তবে আপনি ব্যবহার করতে পারেন git rebase -i। আপনি শাখায় থাকলে topical_xFeature, আপনি চালিত হবে git rebase -i master। এটি সম্পাদকের উইন্ডোটি খুলবে, উপস্থাপিত তালিকাভুক্ত একগুচ্ছ কমিটস সহ pick। আপনি প্রথমটির পরিবর্তে যাবতীয় পরিবর্তন করতে পারেন squash, যা গিটকে এই সমস্ত পরিবর্তনগুলি রাখতে বলবে, তবে এগুলি প্রথম প্রতিশ্রুতিতে স্কোয়াশ করবে। এটি করার পরে, দেখুন masterএবং আপনার বৈশিষ্ট্য শাখায় মার্জ করুন:

git checkout topical_xFeature
git rebase -i master
git checkout master
git merge topical_xFeature

পরিবর্তে আপনি যদি শুধু স্কোয়াশ সবকিছু করতে চান topical_xFeatureমধ্যে master, আপনি শুধু নিম্নোক্ত কাজ করতে পারে:

git checkout master
git merge --squash topical_xFeature
git commit

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


1
আমি - স্কোয়াশের সাথে একীভূত হওয়ার পরে, আমি এর সাথে টপিক শাখাটি মুছতে সক্ষম হই না git branch -d topic। গিট সমস্ত পরিবর্তনগুলি একত্রিত হয়েছে তা সনাক্ত করতে সক্ষম হয় না কেন?
বালকি

7
@ বাল্কি কারণ গিট সনাক্ত করেছে যে প্রদত্ত শাখার ইতিহাসে প্যাচগুলি প্রদর্শিত হবে কিনা তার ভিত্তিতে প্যাচগুলি মার্জ করা হয়েছে কিনা c স্কোয়াশিং কমিট তাদের পরিবর্তন করে; তারা একটি নতুন প্রতিশ্রুতিতে পরিণত হয়, এবং সেই নতুন প্রতিশ্রুতি অন্যের মতো একই কাজটি করার সময়, গিট তা বলতে পারে না, কেবল একই অভিযোগ করতে পারে যদি তাদের একই কমিট আইডি থাকে (এসএইএ -১) । সুতরাং একবার এটি স্কোয়াশ করার পরে, আপনাকে পুরানো শাখাটি git branch -D topicজোর করে মুছে ফেলার জন্য গিটটি বলতে হবে।
ব্রায়ান ক্যাম্পবেল

66

কোডটি ধাক্কা দেওয়ার আগে আমি সাধারণত একাধিক কমিটকে একক প্রতিশ্রুতিবদ্ধভাবে একত্রিত করতে অনুসরণ করি।

এটি অর্জনের জন্য, আমি আপনাকে জিআইটি দ্বারা সরবরাহিত ' স্কোয়াশ ' ধারণাটি ব্যবহার করার পরামর্শ দিচ্ছি ।

নীচের পদক্ষেপগুলি অনুসরণ করুন।

1) Git রি-বেসের ফলে -i মাস্টার (পরিবর্তে মাস্টার এছাড়াও আপনি একটি নির্দিষ্ট ব্যবহার করতে পারেন কমিট)

রিবাজ ইন্টারেক্টিভ সম্পাদকটি খুলুন, যেখানে এটি আপনার সমস্ত প্রতিশ্রুতি প্রদর্শন করবে। মূলত যেখানে আপনাকে সেই কমিটগুলি সনাক্ত করতে হবে যা আপনি একক প্রতিশ্রুতিতে মার্জ করতে চান।

এগুলি আপনার কমিটগুলি মনে করুন এবং সম্পাদকটিতে এর মতো কিছু দেখানো হয়েছে।

pick f7f3f6d changed my name a bit    
pick 310154e updated README formatting and added blame   
pick a5f4a0d added cat-file  

আপনি লগ কমান্ড ব্যবহার করে সাধারণত দেখার চেয়ে এই কমিটগুলি বিপরীত ক্রমে তালিকাভুক্ত হয় তা গুরুত্বপূর্ণ important মানে, পুরানো প্রতিশ্রুতি প্রথম দেখানো হবে।

2) শেষ প্রতিশ্রুতিবদ্ধ পরিবর্তনের জন্য 'বাছাই'টিকে' স্কোয়াশ 'এ পরিবর্তন করুন। নীচে দেখানো মত কিছু। এটি করে আপনার শেষ 2 টি কমিট প্রথমটির সাথে একীভূত হবে।

pick f7f3f6d changed my name a bit         
squash 310154e updated README formatting and added blame   
squash a5f4a0d added cat-file

আপনার যদি সংহত করার জন্য প্রচুর কমিট থাকে তবে আপনি সংক্ষিপ্ত ফর্মটিও ব্যবহার করতে পারেন:

p f7f3f6d changed my name a bit         
s 310154e updated README formatting and added blame   
s a5f4a0d added cat-file

'i' ব্যবহারের সম্পাদনা করার জন্য এটি সম্পাদককে সন্নিবেশের জন্য সক্ষম করবে। মনে রাখবেন শীর্ষ সর্বাধিক (প্রাচীনতম) প্রতিশ্রুতি স্কোয়াশ করা যাবে না কারণ এর সাথে সম্মিলনের জন্য পূর্বের কোন প্রতিশ্রুতি নেই। সুতরাং এটি বাছাই করতে হবে বা 'পি' করতে হবে। সন্নিবেশ মোড থেকে প্রস্থান করতে 'ইস্ক' ব্যবহার করুন।

3) এখন, নিম্নলিখিত কমান্ড দিয়ে সম্পাদকটি সংরক্ষণ করুনজন্য: wq

আপনি যখন এটি সংরক্ষণ করেন, তখন আপনার একক প্রতিশ্রুতি থাকে যা পূর্ববর্তী তিনটি কমিটের পরিবর্তনের সাথে পরিচিত হয়।

আশা করি এটা তোমাকে সাহায্য করবে।


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

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

সম্ভবত @ নোকুগুয়ের মতোই git rebase -i HEAD~2আমার জন্য শুরু করার সহায়ক জায়গা ছিল। তাহলে এই উত্তরটি সহায়ক ছিল। তারপরে, আমার git statusদেখানো হয়েছে "আপনার শাখা এবং 'উত্স / বৈশিষ্ট্য / এক্সআইজেড' সরানো হয়েছে এবং যথাক্রমে প্রত্যেকে 1 এবং 1 টি আলাদা কমিট করেছে।" তাই আমি প্রয়োজন git push origin feature/xyz --force-with-leaseদেখুন stackoverflow.com/a/59309553/470749 এবং freecodecamp.org/forum/t/...
রায়ান

11

প্রথম : আপনাকে পুশ প্রতি শাখায় কেবল একটি প্রতিশ্রুতি রাখতে কিছুই বলে না: একটি ধাক্কা একটি প্রকাশনার কৌশল যা আপনাকে স্থানীয় ইতিহাস (যেমন কমিটের সংগ্রহ) একটি দূরবর্তী রেপোতে প্রকাশ করতে দেয়।

দ্বিতীয় : একটি গুরুতর git merge --no-ff topical_xFeatureআপনার চাপ কাজ করার আগে, আপনার বিষয় কাজ হিসাবে রেকর্ড করবে master
(এইভাবে, আপনি topical_xFeatureআরও বিবর্তনের জন্য আশেপাশে রয়েছেন, যে আপনি masterপরবর্তী সংশ্লেষ সম্পর্কে একক নতুন প্রতিশ্রুতি হিসাবে রেকর্ড করতে পারবেন - কোন- ff।
যদি পরিত্রাণ পাওয়া topical_xFeatureলক্ষ্য হয়, তবে git merge --squashসঠিক বিকল্প, ব্রায়ান ক্যাম্পবেলে বিস্তারিত হিসাবে এর উত্তর ।)


আমি মনে করি --squash, --no-ffআপনি যা চান তা নয় । --no-ffএকটি মার্জ কমিট তৈরি করে, কিন্তু সমস্ত কমিট থেকেও ছেড়ে দেয় topical_xFeature
ব্রায়ান ক্যাম্পবেল

@ ব্রায়ান: আমি সম্মত হয়েছি এবং আপনার উত্তরটিকে অগ্রাহ্য করেছি, তবে আমি প্রথমে --no-ff বিকল্পের কথা ভেবেছিলাম কারণ আমি topical_featureশাখাটি প্রায় রাখতে চেয়েছিলাম , এবং কেবল masterশাখায় একটি প্রতিশ্রুতি রেকর্ড করেছি ।
ভনসি

8

মাস্টার শাখায় স্যুইচ করুন এবং নিশ্চিত হন যে আপনি আপ টু ডেট আছেন।

git checkout master

git fetch উত্স / মাস্টার সম্পর্কিত আপডেটগুলি পেতে এটি আপনার (আপনার গিট কনফিগারেশনের উপর নির্ভর করে) প্রয়োজনীয় হতে পারে

git pull

মাস্টার শাখায় বৈশিষ্ট্য শাখাটি মার্জ করুন।

git merge feature_branch

উত্সের স্থিতিতে মাস্টার শাখাটি পুনরায় সেট করুন।

git reset origin/master

গিট এখন সমস্ত পরিবর্তনকে অচিহ্নবদ্ধ পরিবর্তন হিসাবে বিবেচনা করে। আমরা একটি পরিবর্তন হিসাবে এই পরিবর্তনগুলি যুক্ত করতে পারি as যুক্ত হচ্ছে। এছাড়াও তালিকৃত ফাইল যুক্ত করবে।

git add --all

git commit

রেফ: https://makandracards.com/makandra/527-squash-several-git-commits-into-a-single-commit


3
এই উত্তরটি অনুসরণ করা সহজ এবং কল্পনা করা সত্যিই সহজ।
জোকব

6
  1. প্রথমে কোনটি প্রতিশ্রুতিবদ্ধ হোক তা বেছে নিন everything

    git reflog
    5976f2b HEAD@{0}: commit: Fix conflicts
    80e85a1 HEAD@{1}: commit: Add feature
    b860ddb HEAD@{2}: commit: Add something
    
  2. আপনার নির্বাচিত মাথায় পুনরায় সেট করুন (আমি নির্বাচন করেছি HEAD@{2})

    git reset b860ddb --soft
    
  3. git status (নিশ্চিত হবার জন্য)

  4. আপনার নতুন প্রতিশ্রুতি যুক্ত করুন

    git commit -m "Add new commit"
    

দ্রষ্টব্য: HEAD@{0}এবং HEAD@{1}এখন 1 টি প্রতিশ্রুতিতে মার্জ করা হয়েছে, এটি একাধিক কমিটির জন্যও করা যেতে পারে।

git reflog আবার প্রদর্শিত হবে:

git reflog
5976f2b HEAD@{0}: commit: Add new commit
b860ddb HEAD@{1}: commit: Add something

0

একাধিক কমিটকে স্বয়ংক্রিয় করার একটি সরঞ্জাম

যেমন Kondal Kolipaka বলছেন । "গিট রিবেস -i" ব্যবহার করা হচ্ছে

"গিট রিবেস" এর যুক্তি

"গিট রেবেস -i" ব্যবহার করার সময়, গিটটি বর্তমান .git / রিবেস-মার্জ ডিরেক্টরিতে গিট-রিবেস-টুডো ফাইল তৈরি করে এবং তারপরে গিট সম্পাদকের জন্য অনুরোধ করে ব্যবহারকারীদের প্রক্রিয়াজাতকরণের জন্য গিট-রিবেস-টুডো ফাইল সম্পাদনা করতে। সুতরাং সরঞ্জামটি পূরণ করা প্রয়োজন:

  1. আমরা যে সরঞ্জামটি সরবরাহ করেছি তাতে গিট সম্পাদকটি পরিবর্তন করুন;
  2. সরঞ্জামটি গিট-রিবেস-টুডো ফাইলটি প্রক্রিয়া করে।

ডিফল্ট গিট সম্পাদকটি পরিবর্তন করুন

git config core.editor #show current default git editor
git config --local --replace-all  core.editor NEW_EDITOR # set the local branch using NEW_EDITOR as git editor

সুতরাং, সরঞ্জামটির গিট সম্পাদক পরিবর্তন করতে হবে এবং গিট-রিবেস-টুডো ফাইলটি প্রক্রিয়া করা উচিত। নীচে পাইথন ব্যবহার করার সরঞ্জামটি:

#!/usr/bin/env python3
#encoding: UTF-8

import os
import sys

def change_editor(current_file):
    os.system("git config --local --replace-all  core.editor " + current_file) # Set current_file as git editor
    os.system("git rebase -i") # execute the "git rebase -i" and will invoke the python file later with git-rebase-todo file as argument
    os.system("git config --local --replace-all core.editor vim") # after work reset the git editor to default

def rebase_commits(todo_file):
    with open(todo_file, "r+") as f:
        contents = f.read() # read git-rebase-todo's content
        contents = contents.split("\n")
        first_commit = True
        f.truncate()
        f.seek(0)
        for content in contents:
            if content.startswith("pick"):
                if first_commit:
                    first_commit = False
                else:
                    content = content.replace("pick", "squash") # replace the pick to squash except for the first pick
            f.write(content + "\n")

def main(args):
    if len(args) == 2:
        rebase_commits(args[1]) # process the git-rebase-todo
    else:
        change_editor(os.path.abspath(args[0])) # set git editor

if __name__ == "__main__":
    main(sys.argv)

রেফ: https://liwugang.github.io/2019/12/30/git_commits_en.html


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