গিটে কীভাবে আমি একটি উপ ডিরেক্টরিকে একীভূত করব?


86

স্থানীয় গিট শাখা থেকে কেবল একটি উপ-ডিরেক্টরিতে পরিবর্তনগুলি একটি দূরবর্তী গিট শাখায় মার্জ করা সম্ভব নাকি এটি "সব কিছু না কিছুই"?

উদাহরণস্বরূপ, আমার আছে:

branch-a
 - content-1
 - dir-1
   - content-2

এবং

branch-b
 - content-1
 - dir-1
   - `content-2

আমি কেবল শাখা-একটি দির -1 এর বিষয়বস্তুগুলিকে শাখা-বি ডির -1 এর সামগ্রীগুলির সাথে একত্রীকরণ করতে চাই।


4
আমি মনে করি এটি এর সদৃশ: স্ট্যাকওভারফ্লো.
com/ প্রশ্নগুলি

উত্তর:


82

" আপনি কীভাবে গিট-মার্জ করে বেছে বেছে ফাইলগুলি একীভূত করবেন? " এই প্রশ্নের একটি বিকল্প হিসাবে , আমি সবেমাত্র এই গিটহাব থ্রেডটি পেয়েছি যা গিট রিড-ট্রি-এর উপর ভিত্তি করে একটি সম্পূর্ণ উপ - ডিরেক্টরিকে মার্জ করার জন্য আরও বেশি খাপ খাইয়ে নিতে পারে :

  • আমার সংগ্রহস্থল => cookbooks
    আমার সংগ্রহস্থল লক্ষ্য ডিরেক্টরি =>cookbooks/cassandra
  • দূরবর্তী সংগ্রহস্থল => infochimps
    রিমোট সংগ্রহস্থল উত্স আমি cookbooks/cassandra=> এ একত্রীকরণ করতে চাই intoinfochimps/cookbooks/cassandra

আমি তাদের একীভূত করার জন্য যে আদেশগুলি ব্যবহার করেছি তা এখানে

  • সংগ্রহস্থল যোগ করুন এবং এটি আনুন
গিট রিমোট অ্যাড -ফ ইনফোকিম্পস গিট: //github.com/infochimps/cluster_chef.git
  • সংযুক্তি সম্পাদন করুন
গিট একীভূত - নিবন্ধ-সম্পর্কহীন-ইতিহাস - আমাদের - না-প্রতিশ্রুতিবদ্ধ ইনফোকিম্পস / মাস্টার

(এটি 'আমাদের' কৌশলটি ব্যবহার করে মার্জ করে -s ours) ( যা উত্স শাখা থেকে পরিবর্তনগুলি বাতিল করে দেয় This infochimps/masterএটি লক্ষ্য শাখায় কোনও ফাইল সংশোধন না করেই একীভূত হওয়া সত্যটি রেকর্ড করে )

  • শুধুমাত্র infochimps/cookbooks/cassandraমধ্যে মার্জ করুনcassandra
গিট রিড-ট্রি - প্রিফিক্স = ক্যাসান্দ্রা / -উ ইনফোকিম্পস / মাস্টার: কুকবুকস / ক্যাসান্দ্রা

এটি কেবলমাত্র উত্স উপ-ডিরেক্টরি cookbooks/cassandraহিসাবে উত্স সংগ্রহস্থলের উজানের শাখায় গাছটি পড়ে ।

লক্ষ্য করুন যে টার্গেটের সাব-ডিরেক্টরী নামটিও হওয়া উচিত cookbooks/cassandra, বা আপনি দেখতে পাবেন:

fatal: Not a valid object name
  • পরিবর্তন প্রতিশ্রুতিবদ্ধ
 গিট কমিট-এম 'ইনফোকিম্পস ক্যাসান্দ্রায় মার্জ করা'

সংযোজন

এটি উদ্ভট, [আমাকে সম্পাদনা করুন] - তবে read-treeপদক্ষেপটি সম্ভবত এইভাবে ব্যর্থ হতে পারে:

error: Entry 'infochimps/cookbooks/cassandra/README' overlaps with 'cookbooks/cassandra/README'. Cannot bind.

... উভয় ফাইল অভিন্ন হলেও । এটি সাহায্য করতে পারে:

git rm -r cassandra
git read-tree --prefix=cassandra/ -u infochimps/master:cookbooks/cassandra

তবে অবশ্যই, ম্যানুয়ালি যাচাই করুন যে এটি আপনার যা চায় তা করে।


4
@Martin git-scm.com/docs/git-rev-parse#_specifying_revisions জন্য চেহারা <rev>:<path>যেমন HEAD:README, :README,master:./README
VonC

6
git read-tree: ধাপে আমার জন্য ব্যর্থ হয়error: Entry 'foo/bar/baz.php' overlaps with 'bar/baz.php'. Cannot bind.
ওয়েস্টন Ruter

4
@ ভনসি তবে না, আমার ইতিহাস দরকার। গাছটির মধ্যে থাকা ফাইলগুলিতে স্থানীয় পরিবর্তন রয়েছে সে ক্ষেত্রে এই উত্তরটি দায়ী নয়। সুতরাং এটি একীভূত করা প্রয়োজন।
ওয়েস্টন রাউটার

আমার জন্য overlaps withউপরে উল্লিখিত ত্রুটিটি অভিন্ন ফাইলগুলিতেও পপ আপ হয় । এ কেমন অদ্ভুত?
ulidtko

4
@ ক্রিসহ্যালক্রো লক্ষ্য সংস্থায় infochimps/masterকোনও ফাইল সংশোধন না করে একত্রিত হয়েছে এমন সত্যটি রেকর্ড করতে । কারণ পরবর্তী পদক্ষেপটি git read-tree --prefix=cassandraপরিবর্তনটি করবে। চূড়ান্ত প্রতিশ্রুতি প্রকৃত "মার্জ" সামগ্রী রেকর্ড করবে।
ভনসি

32

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

git checkout destination
git checkout source newFeature/
git commit -am "Merged the new feature from source to destination branch."
git pull --rebase
git push

আমি দেখেছি এমন সমস্ত কিছুর তুলনায় এটি উল্লেখযোগ্যভাবে কম সংশ্লেষিত এবং এটি আমার জন্য নিখুঁতভাবে কাজ করেছে, যা এখানে পাওয়া যায়

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


4
এটি কি ইতিহাস সংরক্ষণ করে?
বিব্রাক

4
@ বিবারাক এই পদ্ধতির ইতিহাস সংরক্ষণ করে না। কমপক্ষে বর্তমান কমান্ডগুলি সহ নয়।
রবি গিদওয়ানি

6

আমি এটি একটিগ্রিপ ফোরামের থ্রেড থেকে পেয়েছি এবং এটি একটি কবজির মতো কাজ করেছে:

git checkout source-branch
git checkout target-branch <directories-or-files-you-do-**NOT**-want> 
git commit
git checkout target-branch
git merge source-branch

4
আমি এটি চেষ্টা করেছিলাম এবং টার্গেট-শাখার উত্স-শাখা থেকে একটি ডিরেক্টরি নিয়ে এসেছি যা আমি চাইনি। এটি ডিয়ারের সেট দিয়ে নির্দিষ্ট করা সত্ত্বেও আমি ২ য় কমান্ডে চাইনি।
ম্যারাথন

4
এটি একীভূত হয় না, এটি উত্স শাখা থেকে ফোল্ডারের পরিবর্তে।
জিপি 2 এমভি 3

@ জিপি 2 এমভি 3 আমি মনে করি এটি দৃ looks় দেখাচ্ছে। checkoutফোল্ডারগুলিকে একই => পার্থক্যটি কেবল আন- checkoutফোল্ডার => mergeপার্থক্য করে। এটি একটি বৈধ কৌশল।
ক্যাভম্যান

6

ওপি এর দৃশ্যকল্প যেখানে তারা দুটি শাখা আছে, কিন্তু একমাত্র ইতিহাস একত্রীকরণ করতে চান প্রদত্ত Dir-1 থেকে শাখা-একটি মধ্যে শাখা-B :

# Make sure you are in the branch with the changes you want
git checkout branch-a

# Split the desired folder into its own temporary branch
# This replays all commits, so it could take a while
git subtree split -P dir-1 -b temp-branch

# Enter the branch where you want to merge the desired changes into
git checkout branch-b

# Merge the changes from the temporary branch
git subtree merge -P dir-1 temp-branch

# Handle any conflicts
git mergetool

# Commit
git commit -am "Merged dir-1 changes from branch-a"

# Delete temp-branch
git branch -d temp-branch

1

git cherry-pickআপনি যে কমিটগুলি চান তা নির্বাচন করতে এবং কেবল এই কমিটগুলিকে মার্জ করার জন্য ব্যবহার করুন। এখানে মূল কৌশলটি হ'ল এই কমিটগুলি একটি সহজ উপায়ে নেওয়া (যাতে আপনাকে গিট লগটি ম্যানুয়ালি পরীক্ষা করে হাতে হাতে এনে প্রবেশ করার প্রয়োজন নেই)। এখানে কীভাবে: কমিটের SHA-1 আইডি git logপ্রিন্ট করতে ব্যবহার করুন :

git log ^<commit-a> <commit-b> --pretty=format:"%h" --reverse -- <subdir>

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

তারপরে এটি করুন:

git cherry-pick $(git log ^<commit-a> <commit-b> --pretty=format:"%h" --reverse -- <subdir>)

এটি দুটি ধাপ, সহজ এবং স্থিতিশীল!


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

4
এটি ধরে নেওয়া কমিটগুলি কেবলমাত্র প্রশ্নের মধ্যে থাকা ডিরেক্টরিকেই প্রভাবিত করে। যদি কোনও প্রতিশ্রুতিবদ্ধকরণটি আপনি যে मर्জ করতে চান এবং যে ডিরেক্টরিগুলি আপনি না করেন সেগুলি উভয়কেই প্রভাবিত করে, এটি চেরি-বাছাই করবে।
স্কট

Two steps, simple and stable!মোটেও সহজ নয় :)
রাফা

সুতরাং আপনি কোন উপায়টিকে সহজ বলে মনে করেন? @ রাফা
রবার্ট

@ রবার্ট আমি বোঝাতে চাইনি যে আপনার উত্তরটি সহজ নয়; দোষটি সবই রয়েছে git, যার রহস্য এবং এলোমেলো নাম এবং অর্থগুলি পূর্ণ একটি ভয়াবহ ইন্টারফেস এবং ভয়ানক মানসিক মডেল।
রাফা

0

ব্রাঞ্চ-এ এবং শাখা-বি উভয়ই রাখার জন্য একটি গিট সংগ্রহস্থল তৈরি করুন:

git checkout branch-a
git diff branch-b dir-1 > a.diff
patch -R -p1 < a.diff

14
এই উত্তরের আরও তথ্যের প্রয়োজন। এর মধ্যে আসল কোড বনাম মন্তব্য কী?
কোডেনিনজা

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