আমি কেন এই আপ-টু-ডেট গিট সাবট্রিটিকে ঠেলাতে পারি না?


88

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

আমি এমন একটি সমস্যায় পড়েছি যেখানে গিট রিপোর্ট করেছে যে আমার সাবট্রিটি আপ টু ডেট রয়েছে, তবে পুশিং প্রত্যাখ্যানিত হয়। উদাহরণ স্বরূপ:

#! git subtree pull --prefix=public/shared project-shared master
From github.com:****
* branch            master     -> FETCH_HEAD
Already up-to-date.

আমি যদি চাপ দিই, আমার একটি বার্তা পাওয়া উচিত যে ধাক্কা দেওয়ার মতো কিছুই নেই ... তাই না? ঠিক আছে? :(

#! git subtree push --prefix=public/shared project-shared master
git push using:  project-shared master
To git@github.com:***
! [rejected]        72a6157733c4e0bf22f72b443e4ad3be0bc555ce -> master (non-fast-forward)
error: failed to push some refs to 'git@github.com:***'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Merge the remote changes (e.g. 'git pull')
hint: before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

এর কারণ কী হতে পারে? ব্যর্থ হচ্ছেন কেন?


গিট আপনাকে যা বলছে তা আপনি কেন করবেন না: গিট টানুন?
অ্যালেক্সওয়েন

8
গিট টান আমার প্রশ্নের সাথে কোন সম্পর্ক নেই। তবে হ্যাঁ, গিট টান আমাকে একটি যুগোপযোগী বার্তা দেয়, কারণ উত্সের রেপোতে নতুন কিছু নেই।
mateusz

4
দেখে মনে হচ্ছে আপনি যে শাখায় রয়েছেন সেখানে পিছনে যেখানে মাস্টার হেড রয়েছে - উদাহরণস্বরূপ ... -> এ -> বি -> সি যেখানে রিমোট মাস্টার হেড সি তে রয়েছে তবে আপনার বর্তমান শাখাটি এ (বা কিছু সি এর সাথে সংযুক্ত না হওয়ার বংশধর)। আমি নিশ্চিত আমার গিট ইতিহাস তাকান।
মার্ক লেইটন ফিশার

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

উত্তর:


99

আমি এই ব্লগের মন্তব্যে উত্তরটি পেয়েছি https://coderwall.com/p/ssxp5q

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

git push heroku `git subtree split --prefix pythonapp master`:master --force

8
উইন্ডোজে এই কমান্ডটি কীভাবে চালানো যায়? আমি পাচ্ছিerror: unknown option 'prefix'
পাইলাউ

4
আশ্চর্যজনক, এটি সবেমাত্র আমার দিনকে রক্ষা করেছে :)
বিপিপ্যাট

4
যদিও এটি একটি পরিশ্রম সরবরাহ করে, এটি আচরণের ব্যাখ্যা দেয় না।
ক্লিমকিন

4
সত্য তবে সম্ভবত এই পদ্ধতিতে সাবট্রির বেশিরভাগ ব্যবহার হিরকুতে একপেশে ধাক্কা। সাধারণত একাধিক ব্যবহারকারীর কাছ থেকে চাপ দিতে এবং টানতে হিরাকুকে একটি ডিফাক্টো গিট রেপো হিসাবে বিবেচনা করা হয় না।
এরিক উডরুফ

11
উত্তরটি সম্পর্কে কী সম্পর্ক herokuএবং তা সনাক্ত করতে আমার বেশ কষ্ট হয়েছিল pythonappgit push <your subtree's origin> `git subtree split --prefix=Path/to/subtree master`:master --force
হেরোকু

39

উইন্ডোজ নেস্টেড কমান্ড কাজ করে না:

git push heroku `git subtree split --prefix pythonapp master`:master --force

আপনি প্রথমে নেস্টেড বিটটি চালাতে পারেন:

git subtree split --prefix pythonapp master

এটি (প্রচুর সংখ্যার পরে) একটি টোকেন ফিরিয়ে দেবে, যেমন

157a66d050d7a6188f243243264c765f18bc85fb956

এটি সমন্বিত কমান্ডে ব্যবহার করুন, যেমন:

git push heroku 157a66d050d7a6188f243243264c765f18bc85fb956:master --force

এটি একটি অনেক পরিষ্কার সমাধান। আমার জন্য কাজ কর!
অসীম

আমি যখন গিট সাবট্রি বিভাজন - প্রিফিক্স সাবট্রিডাইরেক্টরিওনাম মাস্টার চালাচ্ছি তখন আমি মারাত্মক দ্ব্যর্থহীন যুক্তি 'মাস্টার' পাই: অজানা সংশোধন বা পথটি গাছের মধ্যে নেই
ডেমোডাভ

এটি একটি দুর্দান্ত সমাধান, আমি পেয়েছিলাম git subtreeকেবল কোনও আদেশ নয়। আপনার সমাধানটি ব্যবহার করার পরে আমি আমার সমস্ত রেপোর পরিবর্তে হিরকুতে একটি ফোল্ডার স্থাপন করতে সক্ষম হয়েছি
pakman198

দুর্দান্ত সমাধান এবং সময় সাশ্রয়
নিশার্গ শাহ

29

--ontoপতাকাটি ব্যবহার করুন :

# DOESN'T WORK: git subtree push --prefix=public/shared project-shared master --onto=project-shared/master

[সম্পাদনা করুন: দুর্ভাগ্যক্রমে অন্তর্নিহিত subtree pushদিকে এগিয়ে --ontoযায় না split, সুতরাং অপারেশনটি দুটি কমান্ডে করতে হবে! এটি হয়ে গেলে, আমি দেখতে পাচ্ছি যে আমার আদেশগুলি অন্য উত্তরগুলির মধ্যে একটির মতো, তবে ব্যাখ্যাটি আলাদা is সুতরাং আমি এটিকে যাইহোক এখানে রেখে দেব]]

git push project-shared $(git subtree split --prefix=public/shared --onto=project-shared/master):master

বা আপনি যদি ব্যাশ ব্যবহার করছেন না:

git subtree split --prefix=public/shared --onto=project-shared/master
# This will print an ID, say 0123456789abcdef0123456789abcdef,
# which you then use as follows:
git push project-shared 01234567:master

এটিকে বের করার জন্য আমি গিট-সাবট্রি উত্সের সাহায্যে ঘন্টাগুলি ব্যয় করেছি, তাই আমি আশা করি আপনি এটির প্রশংসা করবেন;)

subtree pushদৌড় দিয়ে শুরু হয় subtree split, যা আপনার প্রতিশ্রুতিবদ্ধ ইতিহাসকে এমন ফর্ম্যাটে পুনর্লিখন করে যা ধাক্কা দেওয়ার জন্য প্রস্তুত হওয়া উচিত। এটি যেভাবে এটি করে তা হ'ল এটি যে public/shared/কোনও পাথের সামনে থেকে সরে যায় এবং যে ফাইলগুলি নেই তা সরিয়ে দেয়। এর অর্থ আপনি যদি স্কোয়াশড না টানেন তবুও সমস্ত উজানের সাব-রিপোসিটোরি কমিটগুলি অগ্রাহ্য করা হয় কারণ তারা খালি পথে ফাইলগুলির নাম দেয়। (কমিটস যে কোনও ফাইলের অধীনে স্পর্শ করে নাpublic/shared/, বা অভিভাবকদের অনুরূপ যে একীভূত কমিটগুলিও ধসে পড়েছে। [সম্পাদনা: এছাড়াও, এর পর থেকে আমি কিছু স্কোয়াশ সনাক্তকরণ পেয়েছি, সুতরাং এখন আমি ভাবছি এটি কেবল তখনই আপনি স্কোয়াশড টানেন তবে, এবং অন্য সরল উত্তরটি বর্ণিত সরল মার্জ কমিটগুলি ভেঙে পড়া নন-স্কোয়াশেড পথ বেছে নিতে পরিচালনা করে এবং স্কোয়াশেড পাথটি ফেলে দিন]]] ফলস্বরূপ, যে স্টাফটি এটি ধাক্কা দেওয়ার চেষ্টা করে তা বর্তমান হোস্ট সংগ্রহস্থলের প্রতিশ্রুতিবদ্ধ যে কোনও কাজ থেকে আপনি যে ধরণের চাপ দিচ্ছেন তা সমাপ্ত হয়, তবে সরাসরি সাব-রেজিস্ট্রি বা অন্য হোস্টের মাধ্যমে প্রতিশ্রুতিবদ্ধ লোকদের কাজ করেন না not ভান্ডার

তবে, আপনি যদি ব্যবহার করেন --ontoতবে সমস্ত প্রবাহের কমিটগুলি ভারব্যাটিমটি ব্যবহার করার জন্য ঠিক হিসাবে রেকর্ড করা হয়, সুতরাং যখন পুনর্লিখনের প্রক্রিয়াটি যখন মার্জ করার জন্য পিতা-মাতার একজন হিসাবে পুনরায় লেখার জন্য চান তখন তাদের জুড়ে আসে, এটি তাদের পুনরায় লেখার চেষ্টা না করে এগুলি রাখে সাধারণ ভাবে


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

4
"প্রকল্প-ভাগ" কি?
কলিন ডি

4
@ কলিনডি "প্রকল্প-ভাগ করা" রিমোটটির নাম। জায়গাটি আনার এবং ধাক্কা দেওয়ার জন্য জায়গাটি কনফিগার করার সময় এটি আপনি বেছে নেবেন। আপনি এর সাথে রিমোটগুলির একটি তালিকা পেতে পারেন git remote -v
entheh

আপনি যত ঘন্টা সময় কাটিয়েছেন তা আমার দিনকে জাস্ট করে দিয়েছে। ধন্যবাদ!
জুন

4
আমি এই বাগটি সর্বদা ঘটতে দেখেছি যখন আপনার সাব সংগ্রহস্থলীর একটি ডিরেক্টরি রয়েছে যার নাম উপসর্গের মতো একই, যেমন আপনি প্রধান সংগ্রহস্থলটিতে "লাইবএক্সএক্সএক্সএক্স" হিসাবে সাব-সংগ্রহস্থলটি যুক্ত করেন এবং আপনার উপ-সংগ্রহস্থলটিতে নিজেই একটি "লিবিবএক্সএক্সএক্সএক্স" নামে সাব ডিরেক্টরি রয়েছে "। এক্ষেত্রে গিট সাব রিপোসিটরিতে কমিটগুলি ভুলভাবে মূল সংগ্রহস্থলের হিসাবে বিবেচনা করবে এবং সেগুলি বিভক্ত করার চেষ্টা করবে। --ontoবিকল্প করে সাব সংগ্রহস্থলের মধ্যে ইতিমধ্যেই আছে সনাক্ত করার Git সাহায্য করে।
Cosyn 25:58

14

একটি "গিটহাব পৃষ্ঠাগুলি" টাইপ অ্যাপ্লিকেশানের জন্য, যেখানে আপনি একটি জিও-পৃষ্ঠাগুলি শাখায় একটি "ডিস্ট" সাবট্রি স্থাপন করেন, সমাধানটি এরকম কিছু দেখতে পাবে

git push origin `git subtree split --prefix dist master`:gh-pages --force

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


3

আমি আগেও এই সমস্যার মুখোমুখি হয়েছি এবং আমি কীভাবে এটি সমাধান করেছি তা এখানে।

আমি যা জানতে পেরেছিলাম তা হল আমার একটি শাখা ছিল যা স্থানীয় মাস্টার শাখার সাথে সংযুক্ত ছিল না। এই শাখাটি বিদ্যমান এবং এটি কেবল শূন্যে ঝুলছে। আপনার ক্ষেত্রে, এটি সম্ভবত বলা হয়েছে project-shared। এই বিষয়টি ধরে নেওয়া এবং আপনি যখন একটি কাজ করেন git branchআপনি একটি স্থানীয় project-sharedশাখা দেখতে পাবেন , তারপরে আপনি আপনার বিদ্যমান শাখায় একটি নতুন চুক্তি যুক্ত করতে পারেন project-shared:

git subtree split --prefix=public/shared --onto public-shared --branch public-shared

আমি যেভাবে বুঝতে পেরেছি তা git subtreeথেকে নতুন শাখা তৈরি করা শুরু হবে --onto, এক্ষেত্রে এটির স্থানীয় public-sharedশাখা। তারপরে শাখাটির অর্থ একটি শাখা তৈরি করা, যা কেবল পুরাতন public-sharedশাখাকে প্রতিস্থাপন করে ।

এটি public-sharedশাখার আগের সমস্ত এসএইচএ রাখবে । অবশেষে, আপনি একটি করতে পারেন

git push project-shared project-shared:master

ধরে নিচ্ছি যে আপনার কাছে একটি project-sharedদূরবর্তীও রয়েছে; এটি শূন্য project-shared শাখায় স্থানীয় ঝুলন্তকেmaster দূরবর্তী শাখায় ঠেলে দেবে project-shared


3

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

এটি কীভাবে কাজ করে তা আরও ভাল করে বোঝার জন্য একটি উদাহরণ (যা আপনি সহজেই পুনরুত্পাদন করতে পারেন) দেখুন। নিম্নলিখিত ইতিহাস বিবেচনা করুন (লাইন ফর্ম্যাটটি হ'ল: [গাছ] বিষয় প্রতিশ্রুতিবদ্ধ):

% git log --graph --decorate --pretty=oneline --pretty="%h [%t] %s"
*   E [z] Merge branch 'master' into side-branch
|\
| * D [z] add dir/file2.txt
* | C [y] Revert "change dir/file1.txt"
* | B [x] change dir/file1.txt
|/
*   A [w] add dir/file1.txt

এই উদাহরণে, আমরা বিভক্ত হয় dir। করে Dএবং Eএকই গাছ আছে z, কারণ আমরা কমিট আছে C, যা পূর্বাবস্থায় ফেরানো কমিট Bতাই হয়, B-Cক্রম জন্য কিছুই না dirযদিও এটি এটি পরিবর্তন আছে।

এখন বিভাজন করতে দিন। প্রথম আমরা প্রতিশ্রুতি উপর বিভক্ত C

% git log `git subtree split -P dir C` ...
* C' [y'] Revert "change dir/file1.txt"
* B' [x'] change dir/file1.txt
* A' [w'] add dir/file1.txt

পরবর্তী আমরা প্রতিশ্রুতিবদ্ধ উপর বিভক্ত E

% git log `git subtree split -P dir E` ...
* D' [z'] add dir/file2.txt
* A' [w'] add dir/file1.txt

হ্যাঁ, আমরা দুটি কমিট হারিয়েছি। দ্বিতীয় বিভাজনকে ধাক্কা দেওয়ার চেষ্টা করার সময় ত্রুটির ফলস্বরূপ, কারণ এর মধ্যে দুটি চুক্তি নেই, যা ইতিমধ্যে উত্সতে এসেছে।

সাধারণত আপনি ব্যবহার করে এই ত্রুটিটি সহ্য করতে পারেন push --force, যেহেতু বাদ দেওয়া কমিটগুলির মধ্যে সাধারণত তাদের মধ্যে গুরুত্বপূর্ণ তথ্য থাকে না have দীর্ঘমেয়াদে, বাগটি সংশোধন করা দরকার, সুতরাং বিভক্ত ইতিহাসে dirপ্রত্যাশামুলকভাবে সমস্ত কমিট থাকে, যা স্পর্শ করে । আমি আশা করব যে এই সংশোধনটি গোপন নির্ভরতার জন্য পিতামাতার প্রতিশ্রুতিগুলির গভীরতর বিশ্লেষণ অন্তর্ভুক্ত করবে।

রেফারেন্সের জন্য, আচরণের জন্য দায়বদ্ধ এখানে মূল কোডটির অংশ।

copy_or_skip()
  ...
  for parent in $newparents; do
      ptree=$(toptree_for_commit $parent) || exit $?
      [ -z "$ptree" ] && continue
      if [ "$ptree" = "$tree" ]; then
          # an identical parent could be used in place of this rev.
          identical="$parent"
      else
          nonidentical="$parent"
      fi
  ...
  if [ -n "$identical" ]; then
      echo $identical
  else
      copy_commit $rev $tree "$p" || exit $?
  fi

2020-05-09 (শনি) হিসাবে বাগটি ঠিক করা হয়েছে? @klimkin
halfmoonhalf

বাগ ঠিক করা হয়েছে। দেখুন: অবদান / সাবট্রি: "সাবট্রি বিভাজন" স্কিপড-মার্জ বাগটি ঠিক করুন। github.com/git/git/commit/...
halfmoonhalf

0

এরিক উডরফের উত্তর আমাকে সাহায্য করেনি, তবে নিম্নলিখিতগুলি করেছেন:

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

আমাকে অবশ্যই যুক্ত করতে হবে যে স্কোয়াশেড টানা কোনও বিরোধের উদ্বোধন করে নি, আমাকে বলেছিল যে সবকিছু ঠিক আছে।


0

আরেকটি [সরল] সমাধান হ'ল আপনি যদি পারেন তবে আরও একটি কমিট করে রিমোটের মাথাটি বাড়িয়ে তোলা। আপনি এই উন্নত মাথাটি স্থানীয় সাবট্রিতে টানানোর পরে আপনি আবার এটি থেকে চাপতে সক্ষম হবেন।


4
আমি স্থানীয় সাবট্রির সাথে সিঙ্কের বাইরে দূরবর্তী সংগ্রহস্থলের সাথে একই সমস্যার সমাধান করেছি।
এইডাস বেনডোরাইটিস

0

আপনি স্থানীয় পরিবর্তনগুলি রিমোট সাবট্রি রেপোতে জোর করতে পারেন

git push subtree_remote_address.git `git subtree split --prefix=subtree_folder`:refs/heads/branch --force

0

ক্রিস জর্ডানের সমাধানের ভিত্তিতে উইন্ডোজ ব্যবহারকারীদের জন্য একটি দ্রুত পাওয়ারশেল ll

$id = git subtree split --prefix pythonapp master
Write-Host "Id is: $id"
Invoke-Expression "git push heroku $id`:master --force"

0

সুতরাং এটিই আমি যা লিখেছি তা ভিত্তিতেই লিখেছি @

for /f "delims=" %%b in ('git subtree split --prefix [name-of-your-directory-on-the-file-system-you-setup] -b [name-of-your-subtree-branch]') do @set token=%%b
git push [alias-for-your-subtree] %token%:[name-of-your-subtree-branch] --force

pause

0

এই সমস্যাও ছিল। শীর্ষ উত্তরের উপর ভিত্তি করে আমি যা করেছি তা এখানে রয়েছে:

প্রদত্ত:

#! git subtree push --prefix=public/shared project-shared master
git push using:  project-shared master
To git@github.com:***
! [rejected]        72a6157733c4e0bf22f72b443e4ad3be0bc555ce -> master (non-fast-forward)
error: failed to push some refs to 'git@github.com:***'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Merge the remote changes (e.g. 'git pull')
hint: before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

এটি লিখুন:

git push <origin> 72a6157733c4e0bf22f72b443e4ad3be0bc555ce:<branch> --force

'গিট সাবট্রি পুশ' দ্বারা আউটপুট হওয়া টোকেনটি 'গিট পুশ' তে ব্যবহৃত হয় তা নোট করুন।

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